1package dns
2
3import "testing"
4
5// TestPacketDataNsec tests generated using fuzz.go and with a message pack
6// containing the following bytes: 0000\x00\x00000000\x00\x002000000\x0060000\x00\x130000000000000000000"
7// That bytes sequence created the overflow error and further permutations of that sequence were able to trigger
8// the other code paths.
9func TestPackDataNsec(t *testing.T) {
10	type args struct {
11		bitmap []uint16
12		msg    []byte
13		off    int
14	}
15	tests := []struct {
16		name       string
17		args       args
18		want       int
19		wantErr    bool
20		wantErrMsg string
21	}{
22		{
23			name: "overflow",
24			args: args{
25				bitmap: []uint16{
26					8962, 8963, 8970, 8971, 8978, 8979,
27					8986, 8987, 8994, 8995, 9002, 9003,
28					9010, 9011, 9018, 9019, 9026, 9027,
29					9034, 9035, 9042, 9043, 9050, 9051,
30					9058, 9059, 9066,
31				},
32				msg: []byte{
33					48, 48, 48, 48, 0, 0, 0,
34					1, 0, 0, 0, 0, 0, 0, 50,
35					48, 48, 48, 48, 48, 48,
36					0, 54, 48, 48, 48, 48,
37					0, 19, 48, 48,
38				},
39				off: 48,
40			},
41			wantErr:    true,
42			wantErrMsg: "dns: overflow packing nsec",
43			want:       31,
44		},
45		{
46			name: "disordered nsec bits",
47			args: args{
48				bitmap: []uint16{
49					8962,
50					0,
51				},
52				msg: []byte{
53					48, 48, 48, 48, 0, 0, 0, 1, 0, 0, 0, 0,
54					0, 0, 50, 48, 48, 48, 48, 48, 48, 0, 54, 48,
55					48, 48, 48, 0, 19, 48, 48, 48, 48, 48, 48, 0,
56					0, 0, 1, 0, 0, 0, 0, 0, 0, 50, 48, 48,
57					48, 48, 48, 48, 0, 54, 48, 48, 48, 48, 0, 19,
58					48, 48, 48, 48, 48, 48, 0, 0, 0, 1, 0, 0,
59					0, 0, 0, 0, 50, 48, 48, 48, 48, 48, 48, 0,
60					54, 48, 48, 48, 48, 0, 19, 48, 48, 48, 48, 48,
61					48, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 50,
62					48, 48, 48, 48, 48, 48, 0, 54, 48, 48, 48, 48,
63					0, 19, 48, 48, 48, 48, 48, 48, 0, 0, 0, 1,
64					0, 0, 0, 0, 0, 0, 50, 48, 48, 48, 48, 48,
65					48, 0, 54, 48, 48, 48, 48, 0, 19, 48, 48,
66				},
67				off: 0,
68			},
69			wantErr:    true,
70			wantErrMsg: "dns: nsec bits out of order",
71			want:       155,
72		},
73		{
74			name: "simple message with only one window",
75			args: args{
76				bitmap: []uint16{
77					0,
78				},
79				msg: []byte{
80					48, 48, 48, 48, 0, 0,
81					0, 1, 0, 0, 0, 0,
82					0, 0, 50, 48, 48, 48,
83					48, 48, 48, 0, 54, 48,
84					48, 48, 48, 0, 19, 48, 48,
85				},
86				off: 0,
87			},
88			wantErr: false,
89			want:    3,
90		},
91	}
92	for _, tt := range tests {
93		t.Run(tt.name, func(t *testing.T) {
94			got, err := packDataNsec(tt.args.bitmap, tt.args.msg, tt.args.off)
95			if (err != nil) != tt.wantErr {
96				t.Errorf("packDataNsec() error = %v, wantErr %v", err, tt.wantErr)
97				return
98			}
99			if err != nil && tt.wantErrMsg != err.Error() {
100				t.Errorf("packDataNsec() error msg = %v, wantErrMsg %v", err.Error(), tt.wantErrMsg)
101				return
102			}
103			if got != tt.want {
104				t.Errorf("packDataNsec() = %v, want %v", got, tt.want)
105			}
106		})
107	}
108}
109
110func TestUnpackString(t *testing.T) {
111	msg := []byte("\x00abcdef\x0f\\\"ghi\x04mmm\x7f")
112	msg[0] = byte(len(msg) - 1)
113
114	got, _, err := unpackString(msg, 0)
115	if err != nil {
116		t.Fatal(err)
117	}
118
119	if want := `abcdef\015\\\"ghi\004mmm\127`; want != got {
120		t.Errorf("expected %q, got %q", want, got)
121	}
122}
123
124func BenchmarkUnpackString(b *testing.B) {
125	msg := []byte("\x00abcdef\x0f\\\"ghi\x04mmm")
126	msg[0] = byte(len(msg) - 1)
127
128	for n := 0; n < b.N; n++ {
129		got, _, err := unpackString(msg, 0)
130		if err != nil {
131			b.Fatal(err)
132		}
133
134		if want := `abcdef\015\\\"ghi\004mmm`; want != got {
135			b.Errorf("expected %q, got %q", want, got)
136		}
137	}
138}
139