summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/asn1-ber.v1/header_test.go
blob: cac1e2e2b7e2c67e1a40fbb4661d0f0f331c4f98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package ber

import (
	"bytes"
	"io"
	"testing"
)

func TestReadHeader(t *testing.T) {
	testcases := map[string]struct {
		Data               []byte
		ExpectedIdentifier Identifier
		ExpectedLength     int
		ExpectedBytesRead  int
		ExpectedError      string
	}{
		"empty": {
			Data:               []byte{},
			ExpectedIdentifier: Identifier{},
			ExpectedLength:     0,
			ExpectedBytesRead:  0,
			ExpectedError:      io.ErrUnexpectedEOF.Error(),
		},

		"valid short form": {
			Data: []byte{
				byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
				127,
			},
			ExpectedIdentifier: Identifier{
				ClassType: ClassUniversal,
				TagType:   TypePrimitive,
				Tag:       TagCharacterString,
			},
			ExpectedLength:    127,
			ExpectedBytesRead: 2,
			ExpectedError:     "",
		},

		"valid long form": {
			Data: []byte{
				// 2-byte encoding of tag
				byte(ClassUniversal) | byte(TypePrimitive) | byte(HighTag),
				byte(TagCharacterString),

				// 2-byte encoding of length
				LengthLongFormBitmask | 1,
				127,
			},
			ExpectedIdentifier: Identifier{
				ClassType: ClassUniversal,
				TagType:   TypePrimitive,
				Tag:       TagCharacterString,
			},
			ExpectedLength:    127,
			ExpectedBytesRead: 4,
			ExpectedError:     "",
		},

		"valid indefinite length": {
			Data: []byte{
				byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString),
				LengthLongFormBitmask,
			},
			ExpectedIdentifier: Identifier{
				ClassType: ClassUniversal,
				TagType:   TypeConstructed,
				Tag:       TagCharacterString,
			},
			ExpectedLength:    LengthIndefinite,
			ExpectedBytesRead: 2,
			ExpectedError:     "",
		},

		"invalid indefinite length": {
			Data: []byte{
				byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
				LengthLongFormBitmask,
			},
			ExpectedIdentifier: Identifier{},
			ExpectedLength:     0,
			ExpectedBytesRead:  2,
			ExpectedError:      "indefinite length used with primitive type",
		},
	}

	for k, tc := range testcases {
		reader := bytes.NewBuffer(tc.Data)
		identifier, length, read, err := readHeader(reader)

		if err != nil {
			if tc.ExpectedError == "" {
				t.Errorf("%s: unexpected error: %v", k, err)
			} else if err.Error() != tc.ExpectedError {
				t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
			}
		} else if tc.ExpectedError != "" {
			t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
			continue
		}

		if read != tc.ExpectedBytesRead {
			t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
		}

		if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
			t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
				tc.ExpectedIdentifier.ClassType,
				ClassMap[tc.ExpectedIdentifier.ClassType],
				identifier.ClassType,
				ClassMap[identifier.ClassType],
			)
		}
		if identifier.TagType != tc.ExpectedIdentifier.TagType {
			t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
				tc.ExpectedIdentifier.TagType,
				TypeMap[tc.ExpectedIdentifier.TagType],
				identifier.TagType,
				TypeMap[identifier.TagType],
			)
		}
		if identifier.Tag != tc.ExpectedIdentifier.Tag {
			t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
				tc.ExpectedIdentifier.Tag,
				tagMap[tc.ExpectedIdentifier.Tag],
				identifier.Tag,
				tagMap[identifier.Tag],
			)
		}

		if length != tc.ExpectedLength {
			t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
		}
	}
}