1 package ber
2
3 import (
4 "bytes"
5 "io"
6 "testing"
7 )
8
9 func TestReadHeader(t *testing.T) {
10 testCases := map[string]struct {
11 Data []byte
12 ExpectedIdentifier Identifier
13 ExpectedLength int
14 ExpectedBytesRead int
15 ExpectedError string
16 }{
17 "empty": {
18 Data: []byte{},
19 ExpectedIdentifier: Identifier{},
20 ExpectedLength: 0,
21 ExpectedBytesRead: 0,
22 ExpectedError: io.EOF.Error(),
23 },
24
25 "valid short form": {
26 Data: []byte{
27 byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
28 127,
29 },
30 ExpectedIdentifier: Identifier{
31 ClassType: ClassUniversal,
32 TagType: TypePrimitive,
33 Tag: TagCharacterString,
34 },
35 ExpectedLength: 127,
36 ExpectedBytesRead: 2,
37 ExpectedError: "",
38 },
39
40 "valid long form": {
41 Data: []byte{
42
43 byte(ClassUniversal) | byte(TypePrimitive) | byte(HighTag),
44 byte(TagCharacterString),
45
46
47 LengthLongFormBitmask | 1,
48 127,
49 },
50 ExpectedIdentifier: Identifier{
51 ClassType: ClassUniversal,
52 TagType: TypePrimitive,
53 Tag: TagCharacterString,
54 },
55 ExpectedLength: 127,
56 ExpectedBytesRead: 4,
57 ExpectedError: "",
58 },
59
60 "valid indefinite length": {
61 Data: []byte{
62 byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString),
63 LengthLongFormBitmask,
64 },
65 ExpectedIdentifier: Identifier{
66 ClassType: ClassUniversal,
67 TagType: TypeConstructed,
68 Tag: TagCharacterString,
69 },
70 ExpectedLength: LengthIndefinite,
71 ExpectedBytesRead: 2,
72 ExpectedError: "",
73 },
74
75 "invalid indefinite length": {
76 Data: []byte{
77 byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
78 LengthLongFormBitmask,
79 },
80 ExpectedIdentifier: Identifier{},
81 ExpectedLength: 0,
82 ExpectedBytesRead: 2,
83 ExpectedError: "indefinite length used with primitive type",
84 },
85 }
86
87 for k, tc := range testCases {
88 reader := bytes.NewBuffer(tc.Data)
89 identifier, length, read, err := readHeader(reader)
90
91 if err != nil {
92 if tc.ExpectedError == "" {
93 t.Errorf("%s: unexpected error: %v", k, err)
94 } else if err.Error() != tc.ExpectedError {
95 t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
96 }
97 } else if tc.ExpectedError != "" {
98 t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
99 continue
100 }
101
102 if read != tc.ExpectedBytesRead {
103 t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
104 }
105
106 if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
107 t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
108 tc.ExpectedIdentifier.ClassType,
109 ClassMap[tc.ExpectedIdentifier.ClassType],
110 identifier.ClassType,
111 ClassMap[identifier.ClassType],
112 )
113 }
114 if identifier.TagType != tc.ExpectedIdentifier.TagType {
115 t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
116 tc.ExpectedIdentifier.TagType,
117 TypeMap[tc.ExpectedIdentifier.TagType],
118 identifier.TagType,
119 TypeMap[identifier.TagType],
120 )
121 }
122 if identifier.Tag != tc.ExpectedIdentifier.Tag {
123 t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
124 tc.ExpectedIdentifier.Tag,
125 tagMap[tc.ExpectedIdentifier.Tag],
126 identifier.Tag,
127 tagMap[identifier.Tag],
128 )
129 }
130
131 if length != tc.ExpectedLength {
132 t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
133 }
134 }
135 }
136
View as plain text