From 08d863dd3aa97110a20f367b7e2b632788553272 Mon Sep 17 00:00:00 2001
From: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Tue, 18 Jun 2024 14:27:25 +0300
Subject: [PATCH] Pull request 2235: 7069-fix-blocked-services

Updates #7069.

Squashed commit of the following:

commit 0f87493966124af4fa4b28eb1f67281343dd8242
Merge: 87f06b864 28a6c24db
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 18 14:09:18 2024 +0300

    Merge branch 'master' into 7069-fix-blocked-services

commit 87f06b86432bba4d2e2583010784746452b7690f
Merge: c2440752c 66877c92d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 18 13:47:28 2024 +0300

    Merge branch 'master' into 7069-fix-blocked-services

commit c2440752c8a223e8ab2e4a519da9259d888ca06f
Merge: 17a9c14e2 1c82be295
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 17 18:42:48 2024 +0300

    Merge branch 'master' into 7069-fix-blocked-services

commit 17a9c14e29a38ed513a827d9b5351d66f1e6cb48
Merge: 11160bc62 bed86d57f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 11 13:41:00 2024 +0300

    Merge branch 'master' into 7069-fix-blocked-services

commit 11160bc62b08fd6e984d38d5600fa62c3564668f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 11 13:36:56 2024 +0300

    all: imp docs

commit 491287164d31606c93dcbeb4f1e351df0960309b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 10 14:03:22 2024 +0300

    home: imp code

commit 0caf8b15797c28447039736cc9641ccddee5cac0
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 10 13:35:54 2024 +0300

    all: upd chlog

commit 46f793b2591dce54a9566ccb9cb723ab5c60cd6a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 10 13:27:22 2024 +0300

    home: fix blocked services
---
 CHANGELOG.md                               | 4 ++++
 internal/client/persistent.go              | 3 ++-
 internal/home/clients.go                   | 7 +++++++
 internal/home/clientshttp.go               | 2 +-
 internal/home/clientshttp_internal_test.go | 2 +-
 5 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 794f1220..284fe8bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -51,10 +51,14 @@ NOTE: Add new changes BELOW THIS COMMENT.
 
 ### Fixed
 
+- Panic caused by missing user-specific blocked services object in configuration
+  file ([#7069]).
 - Tracking `/etc/hosts` file changes causing panics within particular
   filesystems on start ([#7076]).
 
 [#7053]: https://github.com/AdguardTeam/AdGuardHome/issues/7053
+[#7069]: https://github.com/AdguardTeam/AdGuardHome/issues/7069
+[#7076]: https://github.com/AdguardTeam/AdGuardHome/issues/7076
 
 [install-script]: https://github.com/AdguardTeam/AdGuardHome/?tab=readme-ov-file#automated-install-linux-and-mac
 
diff --git a/internal/client/persistent.go b/internal/client/persistent.go
index 317dc72b..52f3aacc 100644
--- a/internal/client/persistent.go
+++ b/internal/client/persistent.go
@@ -66,7 +66,8 @@ type Persistent struct {
 
 	SafeSearch filtering.SafeSearch
 
-	// BlockedServices is the configuration of blocked services of a client.
+	// BlockedServices is the configuration of blocked services of a client.  It
+	// must not be nil after initialization.
 	BlockedServices *filtering.BlockedServices
 
 	Name string
diff --git a/internal/home/clients.go b/internal/home/clients.go
index 4f3870ec..3616cb0b 100644
--- a/internal/home/clients.go
+++ b/internal/home/clients.go
@@ -16,6 +16,7 @@ import (
 	"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
 	"github.com/AdguardTeam/AdGuardHome/internal/filtering"
 	"github.com/AdguardTeam/AdGuardHome/internal/querylog"
+	"github.com/AdguardTeam/AdGuardHome/internal/schedule"
 	"github.com/AdguardTeam/AdGuardHome/internal/whois"
 	"github.com/AdguardTeam/dnsproxy/proxy"
 	"github.com/AdguardTeam/dnsproxy/upstream"
@@ -261,6 +262,12 @@ func (o *clientObject) toPersistent(
 		}
 	}
 
+	if o.BlockedServices == nil {
+		o.BlockedServices = &filtering.BlockedServices{
+			Schedule: schedule.EmptyWeekly(),
+		}
+	}
+
 	err = o.BlockedServices.Validate()
 	if err != nil {
 		return nil, fmt.Errorf("init blocked services %q: %w", cli.Name, err)
diff --git a/internal/home/clientshttp.go b/internal/home/clientshttp.go
index 40a91f86..fbec5c23 100644
--- a/internal/home/clientshttp.go
+++ b/internal/home/clientshttp.go
@@ -267,7 +267,7 @@ func copyBlockedServices(
 	var weekly *schedule.Weekly
 	if sch != nil {
 		weekly = sch.Clone()
-	} else if prev != nil && prev.BlockedServices != nil {
+	} else if prev != nil {
 		weekly = prev.BlockedServices.Schedule.Clone()
 	} else {
 		weekly = schedule.EmptyWeekly()
diff --git a/internal/home/clientshttp_internal_test.go b/internal/home/clientshttp_internal_test.go
index dc1aa87d..aa2f40fb 100644
--- a/internal/home/clientshttp_internal_test.go
+++ b/internal/home/clientshttp_internal_test.go
@@ -49,7 +49,7 @@ func newPersistentClient(name string) (c *client.Persistent) {
 		Name: name,
 		UID:  client.MustNewUID(),
 		BlockedServices: &filtering.BlockedServices{
-			Schedule: &schedule.Weekly{},
+			Schedule: schedule.EmptyWeekly(),
 		},
 	}
 }