diff --git a/CHANGELOG.md b/CHANGELOG.md index f27a5d13..517776da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,13 @@ See also the [v0.107.34 GitHub milestone][ms-v0.107.34]. NOTE: Add new changes BELOW THIS COMMENT. --> +### Fixed + +- Excessive RAM and CPU consumption by Safe Browsing and Parental Control + filters ([#5896]). + +[#5896]: https://github.com/AdguardTeam/AdGuardHome/issues/5896 + diff --git a/internal/filtering/hashprefix/cache.go b/internal/filtering/hashprefix/cache.go index a4eedec9..d4211b72 100644 --- a/internal/filtering/hashprefix/cache.go +++ b/internal/filtering/hashprefix/cache.go @@ -25,7 +25,7 @@ func toCacheItem(data []byte) *cacheItem { t := time.Unix(int64(binary.BigEndian.Uint64(data)), 0) data = data[expirySize:] - hashes := make([]hostnameHash, len(data)/hashSize) + hashes := make([]hostnameHash, 0, len(data)/hashSize) for i := 0; i < len(data); i += hashSize { var hash hostnameHash @@ -41,9 +41,10 @@ func toCacheItem(data []byte) *cacheItem { // fromCacheItem encodes cacheItem into data. func fromCacheItem(item *cacheItem) (data []byte) { - data = make([]byte, len(item.hashes)*hashSize+expirySize) + data = make([]byte, 0, len(item.hashes)*hashSize+expirySize) + expiry := item.expiry.Unix() - binary.BigEndian.PutUint64(data[:expirySize], uint64(expiry)) + data = binary.BigEndian.AppendUint64(data, uint64(expiry)) for _, v := range item.hashes { // nolint:looppointer // The subsilce is used for a copy. diff --git a/internal/filtering/hashprefix/cache_internal_test.go b/internal/filtering/hashprefix/cache_internal_test.go new file mode 100644 index 00000000..e023826d --- /dev/null +++ b/internal/filtering/hashprefix/cache_internal_test.go @@ -0,0 +1,44 @@ +package hashprefix + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestCacheItem(t *testing.T) { + item := &cacheItem{ + expiry: time.Unix(0x01_23_45_67_89_AB_CD_EF, 0), + hashes: []hostnameHash{{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + }, { + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + }}, + } + + wantData := []byte{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + 0x01, 0x03, 0x05, 0x07, 0x02, 0x04, 0x06, 0x08, + } + + gotData := fromCacheItem(item) + assert.Equal(t, wantData, gotData) + + newItem := toCacheItem(gotData) + gotData = fromCacheItem(newItem) + assert.Equal(t, wantData, gotData) +}