Skip to content

Commit 9246f79

Browse files
committed
Fix varbin serialization
1 parent ff58edb commit 9246f79

File tree

5 files changed

+1039
-33
lines changed

5 files changed

+1039
-33
lines changed

common/geosite/compat_test.go

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bufio"
55
"bytes"
66
"encoding/binary"
7+
"io"
8+
"strconv"
79
"strings"
810
"testing"
911

@@ -12,26 +14,52 @@ import (
1214
"github.com/stretchr/testify/require"
1315
)
1416

15-
// Old implementation using varbin reflection-based serialization
16-
1717
func oldWriteString(writer varbin.Writer, value string) error {
18-
//nolint:staticcheck
19-
return varbin.Write(writer, binary.BigEndian, value)
18+
_, err := varbin.WriteUvarint(writer, uint64(len(value)))
19+
if err != nil {
20+
return err
21+
}
22+
if value == "" {
23+
return nil
24+
}
25+
_, err = writer.Write([]byte(value))
26+
return err
2027
}
2128

2229
func oldWriteItem(writer varbin.Writer, item Item) error {
23-
//nolint:staticcheck
24-
return varbin.Write(writer, binary.BigEndian, item)
30+
err := writer.WriteByte(byte(item.Type))
31+
if err != nil {
32+
return err
33+
}
34+
return oldWriteString(writer, item.Value)
2535
}
2636

2737
func oldReadString(reader varbin.Reader) (string, error) {
28-
//nolint:staticcheck
29-
return varbin.ReadValue[string](reader, binary.BigEndian)
38+
length, err := binary.ReadUvarint(reader)
39+
if err != nil {
40+
return "", err
41+
}
42+
if length == 0 {
43+
return "", nil
44+
}
45+
buf := make([]byte, length)
46+
_, err = io.ReadFull(reader, buf)
47+
if err != nil {
48+
return "", err
49+
}
50+
return string(buf), nil
3051
}
3152

3253
func oldReadItem(reader varbin.Reader) (Item, error) {
33-
//nolint:staticcheck
34-
return varbin.ReadValue[Item](reader, binary.BigEndian)
54+
typeByte, err := reader.ReadByte()
55+
if err != nil {
56+
return Item{}, err
57+
}
58+
value, err := oldReadString(reader)
59+
if err != nil {
60+
return Item{}, err
61+
}
62+
return Item{Type: ItemType(typeByte), Value: value}, nil
3563
}
3664

3765
func TestStringCompat(t *testing.T) {
@@ -44,10 +72,12 @@ func TestStringCompat(t *testing.T) {
4472
{"empty", ""},
4573
{"single_char", "a"},
4674
{"ascii", "example.com"},
75+
{"mixed_case", "Example.COM"},
4776
{"utf8", "测试域名.中国"},
4877
{"special_chars", "\x00\xff\n\t"},
4978
{"127_bytes", strings.Repeat("x", 127)},
5079
{"128_bytes", strings.Repeat("x", 128)},
80+
{"255_bytes", strings.Repeat("x", 255)},
5181
{"16383_bytes", strings.Repeat("x", 16383)},
5282
{"16384_bytes", strings.Repeat("x", 16384)},
5383
}
@@ -98,12 +128,15 @@ func TestItemCompat(t *testing.T) {
98128
}{
99129
{"domain_empty", Item{Type: RuleTypeDomain, Value: ""}},
100130
{"domain_normal", Item{Type: RuleTypeDomain, Value: "example.com"}},
131+
{"domain_mixed_case", Item{Type: RuleTypeDomain, Value: "Example.COM"}},
101132
{"domain_suffix", Item{Type: RuleTypeDomainSuffix, Value: ".example.com"}},
102133
{"domain_keyword", Item{Type: RuleTypeDomainKeyword, Value: "google"}},
103134
{"domain_regex", Item{Type: RuleTypeDomainRegex, Value: `^.*\.example\.com$`}},
104135
{"utf8_domain", Item{Type: RuleTypeDomain, Value: "测试.com"}},
136+
{"special_chars_value", Item{Type: RuleTypeDomain, Value: "\x00\x7f\n\t"}},
105137
{"long_domain", Item{Type: RuleTypeDomainSuffix, Value: strings.Repeat("a", 200) + ".com"}},
106138
{"128_bytes_value", Item{Type: RuleTypeDomain, Value: strings.Repeat("x", 128)}},
139+
{"256_bytes_value", Item{Type: RuleTypeDomain, Value: strings.Repeat("y", 256)}},
107140
}
108141

109142
for _, tc := range cases {
@@ -188,6 +221,10 @@ func TestGeositeWriteReadCompat(t *testing.T) {
188221
"large_items",
189222
generateLargeItems(1000),
190223
},
224+
{
225+
"many_codes",
226+
generateManyCodes(64, 8),
227+
},
191228
}
192229

193230
for _, tc := range cases {
@@ -232,3 +269,19 @@ func generateLargeItems(count int) map[string][]Item {
232269
}
233270
return map[string][]Item{"large": items}
234271
}
272+
273+
func generateManyCodes(codeCount, itemsPerCode int) map[string][]Item {
274+
result := make(map[string][]Item, codeCount)
275+
for i := 0; i < codeCount; i++ {
276+
code := "code" + strconv.Itoa(i)
277+
items := make([]Item, itemsPerCode)
278+
for j := 0; j < itemsPerCode; j++ {
279+
items[j] = Item{
280+
Type: ItemType((i + j) % 4),
281+
Value: strings.Repeat("y", (i+j)%64) + ".example",
282+
}
283+
}
284+
result[code] = items
285+
}
286+
return result
287+
}

0 commit comments

Comments
 (0)