1package magna
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/assert"
7)
8
9func TestDecodeDomain(t *testing.T) {
10 tests := []struct {
11 name string
12 offset int
13 input []byte
14 expectedDomain string
15 expectedOffset int
16 expectedError error
17 }{
18 {
19 name: "Simple domain",
20 input: []byte{3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0},
21 expectedDomain: "www.example.com",
22 expectedOffset: 17,
23 expectedError: nil,
24 },
25 {
26 name: "Domain with compression",
27 offset: 17,
28 input: []byte{3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0, 3, 'f', 'o', 'o', 0xC0, 0},
29 expectedDomain: "foo.www.example.com",
30 expectedOffset: 23,
31 expectedError: nil,
32 },
33 {
34 name: "Invalid label length",
35 input: []byte{64, 'x'},
36 expectedDomain: "",
37 expectedOffset: 2,
38 expectedError: &InvalidLabelError{Length: 64},
39 },
40 {
41 name: "Compression loop",
42 input: []byte{0xC0, 0, 0xC0, 0},
43 expectedDomain: "",
44 expectedOffset: 4,
45 expectedError: &DomainCompressionError{},
46 },
47 {
48 name: "Truncated input",
49 input: []byte{3, 'w', 'w'},
50 expectedDomain: "",
51 expectedOffset: 3,
52 expectedError: &BufferOverflowError{Length: 3, Offset: 4},
53 },
54 }
55
56 for _, tt := range tests {
57 t.Run(tt.name, func(t *testing.T) {
58 domain, offset, err := decode_domain(tt.input, tt.offset)
59
60 t.Log(tt.name)
61 assert.Equal(t, tt.expectedError, err)
62 assert.Equal(t, tt.expectedDomain, domain)
63 assert.Equal(t, tt.expectedOffset, offset)
64 })
65 }
66}
67
68func TestEncodeDomain(t *testing.T) {
69 tests := []struct {
70 name string
71 input string
72 offsets map[string]uint16
73 expected []byte
74 newOffsets map[string]uint16
75 }{
76 {
77 name: "Simple domain",
78 input: "example.com",
79 offsets: make(map[string]uint16),
80 expected: []byte{7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0},
81 newOffsets: map[string]uint16{"example.com": 0, "com": 8},
82 },
83 {
84 name: "Domain with existing offset",
85 input: "test.example.com",
86 offsets: map[string]uint16{"example.com": 10},
87 expected: []byte{4, 't', 'e', 's', 't', 0xC0, 0x0A},
88 newOffsets: map[string]uint16{"test.example.com": 0, "example.com": 10},
89 },
90 {
91 name: "Multiple subdomains",
92 input: "a.b.c.d",
93 offsets: make(map[string]uint16),
94 expected: []byte{1, 'a', 1, 'b', 1, 'c', 1, 'd', 0},
95 newOffsets: map[string]uint16{"a.b.c.d": 0, "b.c.d": 2, "c.d": 4, "d": 6},
96 },
97 }
98
99 for _, tt := range tests {
100 t.Run(tt.name, func(t *testing.T) {
101 result := encode_domain([]byte{}, tt.input, &tt.offsets)
102 assert.Equal(t, tt.expected, result, "Encoded domain does not match expected output")
103 assert.Equal(t, tt.newOffsets, tt.offsets, "Offsets map does not match expected state")
104 })
105 }
106}
107
108func FuzzDecodeDomain(f *testing.F) {
109 testcases := [][]byte{
110 {
111 0x03, 0x63, 0x6f, 0x6d, 0x00,
112 },
113 {
114 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x01, 0x63, 0xC0, 0x00,
115 },
116 {
117 0x03, 0x63, 0x6f, 0x6d, 0xC0, 0x00,
118 },
119 }
120 for _, tc := range testcases {
121 f.Add(tc)
122 }
123 f.Fuzz(func(t *testing.T, msg []byte) {
124 decode_domain(msg, 0)
125 })
126}