+30
-31
domain_name.go
+30
-31
domain_name.go
·····················
······+return "", len(buf), fmt.Errorf("failed to read domain compression pointer offset byte: %w", err)·········+func encodeDomain(bytes []byte, domainName string, offsets *map[string]uint16) ([]byte, error) {······
+143
-22
domain_test.go
+143
-22
domain_test.go
·································
···························+t.Logf("Test: %s, Input: %x, OffsetIn: %d => Domain: '%s', OffsetOut: %d, Err: %v", tt.name, tt.input, tt.offset, domain, offset, err)······
+24
-10
errors.go
+24
-10
errors.go
······
···+return fmt.Sprintf("buffer overflow: attempted to read past buffer length %d at offset %d", e.Length, e.Offset)···
+8
-28
errors_test.go
+8
-28
errors_test.go
············
······+{"PositiveOffset", 10, 15, "buffer overflow: attempted to read past buffer length 10 at offset 15"},+{"ZeroLengthBuffer", 0, 5, "buffer overflow: attempted to read past buffer length 0 at offset 5"},+{"NegativeOffset", 10, -1, "buffer overflow: attempted to read past buffer length 10 at offset -1"},+{"EqualOffset", 10, 10, "buffer overflow: attempted to read past buffer length 10 at offset 10"},······
+10
-7
header.go
+10
-7
header.go
···
···
+81
-60
header_test.go
+81
-60
header_test.go
····································
············+assert.True(t, errors.Is(err, tt.expectedErr), "Error type mismatch. Got %T, expected %T", err, tt.expectedErr)························+t.Errorf("FuzzDecodeHeader: expected BufferOverflowError or wrapped BOF, got %T: %v", err, err)+t.Errorf("FuzzDecodeHeader: encode/decode mismatch\nInput: %x\nEncoded: %x", data[:12], encoded)
+41
-20
message.go
+41
-20
message.go
·········
·········+return nil, fmt.Errorf("failed to encode authority record #%d (%s): %w", i+1, authority.Name, err)+return nil, fmt.Errorf("failed to encode additional record #%d (%s): %w", i+1, additional.Name, err)
+232
-52
message_test.go
+232
-52
message_test.go
············
···+buildAnswer := func(id uint16, name string, rtype DNSType, rclass DNSClass, ttl uint32, rdata ResourceRecordData) []byte {······+assert.True(t, errors.Is(err, tt.wantErrType), "Error type mismatch. Got %T, expected %T", err, tt.wantErrType)+{Name: "test.local", RType: AType, RClass: IN, TTL: 60, RDLength: 4, RData: &A{net.ParseIP("192.0.2.1").To4()}},+{Name: "www.example.com", RType: AType, RClass: IN, TTL: 300, RDLength: 4, RData: &A{net.ParseIP("192.0.2.2").To4()}},+{Name: "mail.example.com", RType: AType, RClass: IN, TTL: 300, RDLength: 4, RData: &A{net.ParseIP("192.0.2.3").To4()}},+{Name: "example.com", RType: MXType, RClass: IN, TTL: 3600, RDLength: 9, RData: &MX{Preference: 10, Exchange: "mail.example.com"}},+{Name: "mail.example.com", RType: AType, RClass: IN, TTL: 300, RDLength: 4, RData: &A{net.ParseIP("192.0.2.4").To4()}},+{Name: "example.com", RType: TXTType, RClass: IN, TTL: 600, RDLength: 36, RData: &TXT{TxtData: []string{"v=spf1 include:_spf.google.com ~all"}}},···+if !(errors.As(err, &bufErr) || errors.As(err, &labelErr) || errors.As(err, &compErr) || strings.Contains(err.Error(), "record:")) {
+16
-8
question.go
+16
-8
question.go
······// Encode serializes a Question into bytes, using a map to handle domain name compression offsets.
······// Encode serializes a Question into bytes, using a map to handle domain name compression offsets.
+103
-82
question_test.go
+103
-82
question_test.go
···························-expected: []byte{9, 's', 'u', 'b', 'd', 'o', 'm', 'a', 'i', 'n', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0, 0, 28, 0, 1},·········-longDomainName := string(longLabel) + "." + string(longLabel) + "." + string(longLabel) + "." + string(longLabel[:61])
·········+wantErrMsg: "question decode: failed to decode QName: invalid domain label: length 64 exceeds maximum 63",+wantErrMsg: "question decode: failed to decode QName: invalid domain compression: pointer loop detected",·········+assert.True(t, errors.Is(err, tt.expectedErr), "Error type mismatch. Got %T, expected %T", err, tt.expectedErr)·········+expected: []byte{9, 's', 'u', 'b', 'd', 'o', 'm', 'a', 'i', 'n', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0, 0, 28, 0, 1},······+assert.True(t, errors.Is(err, tt.expectedErr), "Error type mismatch. Got %T, expected %T", err, tt.expectedErr)···
+208
-126
resource_record.go
+208
-126
resource_record.go
·································-return len(buf), &MagnaError{Message: fmt.Sprintf("magna: WKS RDLENGTH too short: %d", rdlength)}··················-return len(buf), &MagnaError{Message: fmt.Sprintf("magna: HINFO RDATA length mismatch, expected end at %d, ended at %d", endOffset, currentOffset)}·········-Message: fmt.Sprintf("magna: TXT string segment length %d at offset %d exceeds RDLENGTH boundary %d", strLen, nextOffsetAfterLen, endOffset),···-Message: fmt.Sprintf("magna: TXT RDATA parsing finished at offset %d, but expected end at %d based on RDLENGTH", currentOffset, endOffset),·········
·································+return len(buf), fmt.Errorf("WKS record: RDLENGTH %d is too short, minimum 5 required", rdlength)···············+return len(buf), fmt.Errorf("HINFO record: missing OS length byte at offset %d (expected end: %d)", currentOffset, endOffset)···+return len(buf), fmt.Errorf("HINFO record: RDATA length mismatch, consumed %d bytes, expected %d", currentOffset-startOffset, rdlength)+return nil, fmt.Errorf("HINFO record: CPU string length %d exceeds maximum 255", len(hinfo.CPU))+return nil, fmt.Errorf("HINFO record: OS string length %d exceeds maximum 255", len(hinfo.OS))·········+return len(buf), fmt.Errorf("TXT record: string segment length %d exceeds RDLENGTH boundary %d", strLen, endOffset)+return len(buf), fmt.Errorf("TXT record: failed to read string data (length %d): %w", strLen, err)···+return len(buf), fmt.Errorf("TXT record: RDATA parsing finished at offset %d, but expected end at %d", currentOffset, endOffset)······+return offset, fmt.Errorf("rr decode: failed to decode RData for %s (%s): %w", r.Name, r.RType.String(), err)···+return nil, fmt.Errorf("rr encode: failed to encode RData for %s (%s): %w", r.Name, r.RType.String(), err)
+472
-83
resource_record_test.go
+472
-83
resource_record_test.go
······-assert.Equal(t, expectedDecodedData, txtData.TxtData, "Decoded TXT data does not match expected concatenation")-input := []byte{0x69, 0x7b, 0x81, 0x83, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xf, 0x6e, 0x6f, 0x77, 0x61, 0x79, 0x74, 0x68, 0x69, 0x73, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x3, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0x1, 0x0, 0x1, 0xc0, 0x1c, 0x0, 0x6, 0x0, 0x1, 0x0, 0x0, 0x3, 0x84, 0x0, 0x3d, 0x1, 0x61, 0xc, 0x67, 0x74, 0x6c, 0x64, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x3, 0x6e, 0x65, 0x74, 0x0, 0x5, 0x6e, 0x73, 0x74, 0x6c, 0x64, 0xc, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2d, 0x67, 0x72, 0x73, 0xc0, 0x1c, 0x67, 0xaa, 0xc5, 0x6b, 0x0, 0x0, 0x7, 0x8, 0x0, 0x0, 0x3, 0x84, 0x0, 0x9, 0x3a, 0x80, 0x0, 0x0, 0x3, 0x84}
······+func buildRRBytes(t *testing.T, name string, rtype DNSType, rclass DNSClass, ttl uint32, rdataBytes []byte) []byte {+soaEncode := &SOA{MName: mname, RName: rname, Serial: serial, Refresh: refresh, Retry: retry, Expire: expire, Minimum: minimum}+assert.ErrorContains(t, err, "TXT record: string segment length 5 exceeds RDLENGTH boundary 4")+input: buildRRBytes(t, "b.org", TXTType, IN, 300, encodeRData(t, &TXT{[]string{"hello", "world"}})),+Name: "b.org", RType: TXTType, RClass: IN, TTL: 300, RDLength: 12, RData: &TXT{[]string{"hello", "world"}},+Name: "c.net", RType: DNSType(9999), RClass: IN, TTL: 10, RDLength: 2, RData: &Reserved{[]byte{0xca, 0xfe}},+rr: &ResourceRecord{Name: "a.com", RType: AType, RClass: IN, TTL: 60, RData: &A{net.IP{1, 1, 1, 1}}},+rr: &ResourceRecord{Name: "b.org", RType: TXTType, RClass: IN, TTL: 300, RData: &TXT{[]string{"hello", "world"}}},+rr: &ResourceRecord{Name: "a..b", RType: AType, RClass: IN, TTL: 60, RData: &A{net.IP{1, 1, 1, 1}}},+rr: &ResourceRecord{Name: "a.com", RType: AType, RClass: IN, TTL: 60, RData: &A{net.ParseIP("::1")}},+wantErrMsg: "rr encode: failed to encode RData for a.com (A): A record: cannot encode non-IPv4 address",+rr: &ResourceRecord{Name: "b.org", RType: TXTType, RClass: IN, TTL: 300, RData: &TXT{[]string{string(make([]byte, 256))}}},+wantErrMsg: "rr encode: failed to encode RData for b.org (TXT): TXT record: string segment length 256 exceeds maximum 255",+assert.Empty(t, decodedRR.RData.(*Reserved).Bytes, "Nil RData should decode as empty Reserved")+assert.NotEqual(t, uint16(0), decodedRR.RDLength, "Non-nil RData should have non-zero RDLength")
+1
-1
types.go
+1
-1
types.go
+16
-16
utils.go
+16
-16
utils.go
···
···