1
2
3
4
5 package cryptobyte
6
7 import (
8 "bytes"
9 "errors"
10 "fmt"
11 "testing"
12 )
13
14 func builderBytesEq(b *Builder, want ...byte) error {
15 got := b.BytesOrPanic()
16 if !bytes.Equal(got, want) {
17 return fmt.Errorf("Bytes() = %v, want %v", got, want)
18 }
19 return nil
20 }
21
22 func TestContinuationError(t *testing.T) {
23 const errorStr = "TestContinuationError"
24 var b Builder
25 b.AddUint8LengthPrefixed(func(b *Builder) {
26 b.AddUint8(1)
27 panic(BuildError{Err: errors.New(errorStr)})
28 })
29
30 ret, err := b.Bytes()
31 if ret != nil {
32 t.Error("expected nil result")
33 }
34 if err == nil {
35 t.Fatal("unexpected nil error")
36 }
37 if s := err.Error(); s != errorStr {
38 t.Errorf("expected error %q, got %v", errorStr, s)
39 }
40 }
41
42 func TestContinuationNonError(t *testing.T) {
43 defer func() {
44 recover()
45 }()
46
47 var b Builder
48 b.AddUint8LengthPrefixed(func(b *Builder) {
49 b.AddUint8(1)
50 panic(1)
51 })
52
53 t.Error("Builder did not panic")
54 }
55
56 func TestGeneratedPanic(t *testing.T) {
57 defer func() {
58 recover()
59 }()
60
61 var b Builder
62 b.AddUint8LengthPrefixed(func(b *Builder) {
63 var p *byte
64 *p = 0
65 })
66
67 t.Error("Builder did not panic")
68 }
69
70 func TestBytes(t *testing.T) {
71 var b Builder
72 v := []byte("foobarbaz")
73 b.AddBytes(v[0:3])
74 b.AddBytes(v[3:4])
75 b.AddBytes(v[4:9])
76 if err := builderBytesEq(&b, v...); err != nil {
77 t.Error(err)
78 }
79 s := String(b.BytesOrPanic())
80 for _, w := range []string{"foo", "bar", "baz"} {
81 var got []byte
82 if !s.ReadBytes(&got, 3) {
83 t.Errorf("ReadBytes() = false, want true (w = %v)", w)
84 }
85 want := []byte(w)
86 if !bytes.Equal(got, want) {
87 t.Errorf("ReadBytes(): got = %v, want %v", got, want)
88 }
89 }
90 if len(s) != 0 {
91 t.Errorf("len(s) = %d, want 0", len(s))
92 }
93 }
94
95 func TestUint8(t *testing.T) {
96 var b Builder
97 b.AddUint8(42)
98 if err := builderBytesEq(&b, 42); err != nil {
99 t.Error(err)
100 }
101
102 var s String = b.BytesOrPanic()
103 var v uint8
104 if !s.ReadUint8(&v) {
105 t.Error("ReadUint8() = false, want true")
106 }
107 if v != 42 {
108 t.Errorf("v = %d, want 42", v)
109 }
110 if len(s) != 0 {
111 t.Errorf("len(s) = %d, want 0", len(s))
112 }
113 }
114
115 func TestUint16(t *testing.T) {
116 var b Builder
117 b.AddUint16(65534)
118 if err := builderBytesEq(&b, 255, 254); err != nil {
119 t.Error(err)
120 }
121 var s String = b.BytesOrPanic()
122 var v uint16
123 if !s.ReadUint16(&v) {
124 t.Error("ReadUint16() == false, want true")
125 }
126 if v != 65534 {
127 t.Errorf("v = %d, want 65534", v)
128 }
129 if len(s) != 0 {
130 t.Errorf("len(s) = %d, want 0", len(s))
131 }
132 }
133
134 func TestUint24(t *testing.T) {
135 var b Builder
136 b.AddUint24(0xfffefd)
137 if err := builderBytesEq(&b, 255, 254, 253); err != nil {
138 t.Error(err)
139 }
140
141 var s String = b.BytesOrPanic()
142 var v uint32
143 if !s.ReadUint24(&v) {
144 t.Error("ReadUint24() = false, want true")
145 }
146 if v != 0xfffefd {
147 t.Errorf("v = %d, want fffefd", v)
148 }
149 if len(s) != 0 {
150 t.Errorf("len(s) = %d, want 0", len(s))
151 }
152 }
153
154 func TestUint24Truncation(t *testing.T) {
155 var b Builder
156 b.AddUint24(0x10111213)
157 if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil {
158 t.Error(err)
159 }
160 }
161
162 func TestUint32(t *testing.T) {
163 var b Builder
164 b.AddUint32(0xfffefdfc)
165 if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil {
166 t.Error(err)
167 }
168
169 var s String = b.BytesOrPanic()
170 var v uint32
171 if !s.ReadUint32(&v) {
172 t.Error("ReadUint32() = false, want true")
173 }
174 if v != 0xfffefdfc {
175 t.Errorf("v = %x, want fffefdfc", v)
176 }
177 if len(s) != 0 {
178 t.Errorf("len(s) = %d, want 0", len(s))
179 }
180 }
181
182 func TestUint48(t *testing.T) {
183 var b Builder
184 var u uint64 = 0xfefcff3cfdfc
185 b.AddUint48(u)
186 if err := builderBytesEq(&b, 254, 252, 255, 60, 253, 252); err != nil {
187 t.Error(err)
188 }
189
190 var s String = b.BytesOrPanic()
191 var v uint64
192 if !s.ReadUint48(&v) {
193 t.Error("ReadUint48() = false, want true")
194 }
195 if v != u {
196 t.Errorf("v = %x, want %x", v, u)
197 }
198 if len(s) != 0 {
199 t.Errorf("len(s) = %d, want 0", len(s))
200 }
201 }
202
203 func TestUint64(t *testing.T) {
204 var b Builder
205 b.AddUint64(0xf2fefefcff3cfdfc)
206 if err := builderBytesEq(&b, 242, 254, 254, 252, 255, 60, 253, 252); err != nil {
207 t.Error(err)
208 }
209
210 var s String = b.BytesOrPanic()
211 var v uint64
212 if !s.ReadUint64(&v) {
213 t.Error("ReadUint64() = false, want true")
214 }
215 if v != 0xf2fefefcff3cfdfc {
216 t.Errorf("v = %x, want f2fefefcff3cfdfc", v)
217 }
218 if len(s) != 0 {
219 t.Errorf("len(s) = %d, want 0", len(s))
220 }
221 }
222
223 func TestUMultiple(t *testing.T) {
224 var b Builder
225 b.AddUint8(23)
226 b.AddUint32(0xfffefdfc)
227 b.AddUint16(42)
228 if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil {
229 t.Error(err)
230 }
231
232 var s String = b.BytesOrPanic()
233 var (
234 x uint8
235 y uint32
236 z uint16
237 )
238 if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) {
239 t.Error("ReadUint8() = false, want true")
240 }
241 if x != 23 || y != 0xfffefdfc || z != 42 {
242 t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z)
243 }
244 if len(s) != 0 {
245 t.Errorf("len(s) = %d, want 0", len(s))
246 }
247 }
248
249 func TestUint8LengthPrefixedSimple(t *testing.T) {
250 var b Builder
251 b.AddUint8LengthPrefixed(func(c *Builder) {
252 c.AddUint8(23)
253 c.AddUint8(42)
254 })
255 if err := builderBytesEq(&b, 2, 23, 42); err != nil {
256 t.Error(err)
257 }
258
259 var base, child String = b.BytesOrPanic(), nil
260 var x, y uint8
261 if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) ||
262 !child.ReadUint8(&y) {
263 t.Error("parsing failed")
264 }
265 if x != 23 || y != 42 {
266 t.Errorf("want x, y == 23, 42; got %d, %d", x, y)
267 }
268 if len(base) != 0 {
269 t.Errorf("len(base) = %d, want 0", len(base))
270 }
271 if len(child) != 0 {
272 t.Errorf("len(child) = %d, want 0", len(child))
273 }
274 }
275
276 func TestUint8LengthPrefixedMulti(t *testing.T) {
277 var b Builder
278 b.AddUint8LengthPrefixed(func(c *Builder) {
279 c.AddUint8(23)
280 c.AddUint8(42)
281 })
282 b.AddUint8(5)
283 b.AddUint8LengthPrefixed(func(c *Builder) {
284 c.AddUint8(123)
285 c.AddUint8(234)
286 })
287 if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil {
288 t.Error(err)
289 }
290
291 var s, child String = b.BytesOrPanic(), nil
292 var u, v, w, x, y uint8
293 if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) ||
294 !s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) {
295 t.Error("parsing failed")
296 }
297 if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 {
298 t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234",
299 u, v, w, x, y)
300 }
301 if len(s) != 0 {
302 t.Errorf("len(s) = %d, want 0", len(s))
303 }
304 if len(child) != 0 {
305 t.Errorf("len(child) = %d, want 0", len(child))
306 }
307 }
308
309 func TestUint8LengthPrefixedNested(t *testing.T) {
310 var b Builder
311 b.AddUint8LengthPrefixed(func(c *Builder) {
312 c.AddUint8(5)
313 c.AddUint8LengthPrefixed(func(d *Builder) {
314 d.AddUint8(23)
315 d.AddUint8(42)
316 })
317 c.AddUint8(123)
318 })
319 if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil {
320 t.Error(err)
321 }
322
323 var base, child1, child2 String = b.BytesOrPanic(), nil, nil
324 var u, v, w, x uint8
325 if !base.ReadUint8LengthPrefixed(&child1) {
326 t.Error("parsing base failed")
327 }
328 if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) {
329 t.Error("parsing child1 failed")
330 }
331 if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) {
332 t.Error("parsing child2 failed")
333 }
334 if u != 5 || v != 23 || w != 42 || x != 123 {
335 t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123",
336 u, v, w, x)
337 }
338 if len(base) != 0 {
339 t.Errorf("len(base) = %d, want 0", len(base))
340 }
341 if len(child1) != 0 {
342 t.Errorf("len(child1) = %d, want 0", len(child1))
343 }
344 if len(base) != 0 {
345 t.Errorf("len(child2) = %d, want 0", len(child2))
346 }
347 }
348
349 func TestPreallocatedBuffer(t *testing.T) {
350 var buf [5]byte
351 b := NewBuilder(buf[0:0])
352 b.AddUint8(1)
353 b.AddUint8LengthPrefixed(func(c *Builder) {
354 c.AddUint8(3)
355 c.AddUint8(4)
356 })
357 b.AddUint16(1286)
358 want := []byte{1, 2, 3, 4, 0}
359 if !bytes.Equal(buf[:], want) {
360 t.Errorf("buf = %v want %v", buf, want)
361 }
362 if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil {
363 t.Error(err)
364 }
365 }
366
367 func TestWriteWithPendingChild(t *testing.T) {
368 var b Builder
369 b.AddUint8LengthPrefixed(func(c *Builder) {
370 c.AddUint8LengthPrefixed(func(d *Builder) {
371 func() {
372 defer func() {
373 if recover() == nil {
374 t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
375 }
376 }()
377 c.AddUint8(2)
378 }()
379
380 defer func() {
381 if recover() == nil {
382 t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
383 }
384 }()
385 b.AddUint8(2)
386 })
387
388 defer func() {
389 if recover() == nil {
390 t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
391 }
392 }()
393 b.AddUint8(2)
394 })
395 }
396
397 func TestSetError(t *testing.T) {
398 const errorStr = "TestSetError"
399 var b Builder
400 b.SetError(errors.New(errorStr))
401
402 ret, err := b.Bytes()
403 if ret != nil {
404 t.Error("expected nil result")
405 }
406 if err == nil {
407 t.Fatal("unexpected nil error")
408 }
409 if s := err.Error(); s != errorStr {
410 t.Errorf("expected error %q, got %v", errorStr, s)
411 }
412 }
413
414 func TestUnwrite(t *testing.T) {
415 var b Builder
416 b.AddBytes([]byte{1, 2, 3, 4, 5})
417 b.Unwrite(2)
418 if err := builderBytesEq(&b, 1, 2, 3); err != nil {
419 t.Error(err)
420 }
421
422 func() {
423 defer func() {
424 if recover() == nil {
425 t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
426 }
427 }()
428 b.Unwrite(4)
429 }()
430
431 b = Builder{}
432 b.AddBytes([]byte{1, 2, 3, 4, 5})
433 b.AddUint8LengthPrefixed(func(b *Builder) {
434 b.AddBytes([]byte{1, 2, 3, 4, 5})
435
436 defer func() {
437 if recover() == nil {
438 t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
439 }
440 }()
441 b.Unwrite(6)
442 })
443
444 b = Builder{}
445 b.AddBytes([]byte{1, 2, 3, 4, 5})
446 b.AddUint8LengthPrefixed(func(c *Builder) {
447 defer func() {
448 if recover() == nil {
449 t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
450 }
451 }()
452 b.Unwrite(2)
453 })
454 }
455
456 func TestFixedBuilderLengthPrefixed(t *testing.T) {
457 bufCap := 10
458 inner := bytes.Repeat([]byte{0xff}, bufCap-2)
459 buf := make([]byte, 0, bufCap)
460 b := NewFixedBuilder(buf)
461 b.AddUint16LengthPrefixed(func(b *Builder) {
462 b.AddBytes(inner)
463 })
464 if got := b.BytesOrPanic(); len(got) != bufCap {
465 t.Errorf("Expected output length to be %d, got %d", bufCap, len(got))
466 }
467 }
468
469 func TestFixedBuilderPanicReallocate(t *testing.T) {
470 defer func() {
471 recover()
472 }()
473
474 b := NewFixedBuilder(make([]byte, 0, 10))
475 b1 := NewFixedBuilder(make([]byte, 0, 10))
476 b.AddUint16LengthPrefixed(func(b *Builder) {
477 *b = *b1
478 })
479
480 t.Error("Builder did not panic")
481 }
482
483
484
485 func TestASN1Int64(t *testing.T) {
486 tests := []struct {
487 in int64
488 want []byte
489 }{
490 {-0x800000, []byte{2, 3, 128, 0, 0}},
491 {-256, []byte{2, 2, 255, 0}},
492 {-129, []byte{2, 2, 255, 127}},
493 {-128, []byte{2, 1, 128}},
494 {-1, []byte{2, 1, 255}},
495 {0, []byte{2, 1, 0}},
496 {1, []byte{2, 1, 1}},
497 {2, []byte{2, 1, 2}},
498 {127, []byte{2, 1, 127}},
499 {128, []byte{2, 2, 0, 128}},
500 {256, []byte{2, 2, 1, 0}},
501 {0x800000, []byte{2, 4, 0, 128, 0, 0}},
502 }
503 for i, tt := range tests {
504 var b Builder
505 b.AddASN1Int64(tt.in)
506 if err := builderBytesEq(&b, tt.want...); err != nil {
507 t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
508 }
509
510 var n int64
511 s := String(b.BytesOrPanic())
512 ok := s.ReadASN1Integer(&n)
513 if !ok || n != tt.in {
514 t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
515 ok, n, tt.in, i)
516 }
517 if len(s) != 0 {
518 t.Errorf("len(s) = %d, want 0", len(s))
519 }
520 }
521 }
522
523 func TestASN1Uint64(t *testing.T) {
524 tests := []struct {
525 in uint64
526 want []byte
527 }{
528 {0, []byte{2, 1, 0}},
529 {1, []byte{2, 1, 1}},
530 {2, []byte{2, 1, 2}},
531 {127, []byte{2, 1, 127}},
532 {128, []byte{2, 2, 0, 128}},
533 {256, []byte{2, 2, 1, 0}},
534 {0x800000, []byte{2, 4, 0, 128, 0, 0}},
535 {0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}},
536 {0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}},
537 {0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
538 }
539 for i, tt := range tests {
540 var b Builder
541 b.AddASN1Uint64(tt.in)
542 if err := builderBytesEq(&b, tt.want...); err != nil {
543 t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
544 }
545
546 var n uint64
547 s := String(b.BytesOrPanic())
548 ok := s.ReadASN1Integer(&n)
549 if !ok || n != tt.in {
550 t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
551 ok, n, tt.in, i)
552 }
553 if len(s) != 0 {
554 t.Errorf("len(s) = %d, want 0", len(s))
555 }
556 }
557 }
558
View as plain text