Skip to content

Commit a97a6e4

Browse files
committed
Tweak parseBase128 a bit
Mostly so this can be an example of how to parse RELATIVE-OIDs.
1 parent b6f1b1e commit a97a6e4

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

cmd/der2ascii/decoder.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,43 @@ package main
1616

1717
import "github.com/google/der-ascii/internal"
1818

19-
func parseBase128(bytes []byte) (ret uint32, lengthOverride int, rest []byte, ok bool) {
19+
func parseBase128(bytes []byte) (ret uint32, rest []byte, ok bool) {
2020
rest = bytes
21-
if len(rest) == 0 {
21+
// There must be at least one byte, and the value must be minimally-encoded.
22+
if len(rest) == 0 || rest[0] == 0x80 {
2223
return
2324
}
24-
25-
isMinimal := rest[0] != 0x80
2625
for {
2726
if len(rest) == 0 || (ret<<7)>>7 != ret {
28-
// Input too small or overflow.
27+
// Input too small or would overflow.
2928
return
3029
}
3130
b := rest[0]
32-
ret <<= 7
33-
ret |= uint32(b & 0x7f)
31+
ret = (ret << 7) | uint32(b&0x7f)
3432
rest = rest[1:]
3533
if b&0x80 == 0 {
3634
ok = true
37-
if !isMinimal {
38-
lengthOverride = len(bytes) - len(rest)
39-
}
4035
return
4136
}
4237
}
4338
}
4439

40+
func parseBase128Lax(bytes []byte) (ret uint32, lengthOverride int, rest []byte, ok bool) {
41+
rest = bytes
42+
// Tolerate non-minimal inputs.
43+
isMinimal := true
44+
for len(rest) != 0 && rest[0] == 0x80 {
45+
isMinimal = false
46+
rest = rest[1:]
47+
}
48+
ret, rest, ok = parseBase128(rest)
49+
if ok && !isMinimal {
50+
// Tell the caller how to reconstruct the non-minimal input.
51+
lengthOverride = len(bytes) - len(rest)
52+
}
53+
return
54+
}
55+
4556
// parseTag parses a tag from b, returning the resulting tag and the remainder
4657
// of the slice. On parse failure, ok is returned as false and rest is
4758
// unchanged.
@@ -65,7 +76,7 @@ func parseTag(bytes []byte) (tag internal.Tag, rest []byte, ok bool) {
6576
return
6677
}
6778

68-
n, lengthOverride, rest, base128Ok := parseBase128(rest)
79+
n, lengthOverride, rest, base128Ok := parseBase128Lax(rest)
6980
if !base128Ok {
7081
// Parse error.
7182
rest = bytes
@@ -198,9 +209,8 @@ func decodeObjectIdentifier(bytes []byte) (oid []uint32, ok bool) {
198209
// Decode each component.
199210
for len(bytes) != 0 {
200211
var c uint32
201-
var lengthOverride int
202-
c, lengthOverride, bytes, ok = parseBase128(bytes)
203-
if !ok || lengthOverride != 0 {
212+
c, bytes, ok = parseBase128(bytes)
213+
if !ok {
204214
return nil, false
205215
}
206216
oid = append(oid, c)
@@ -229,9 +239,8 @@ func decodeRelativeOID(bytes []byte) (oid []uint32, ok bool) {
229239
// Decode each component.
230240
for len(bytes) != 0 {
231241
var c uint32
232-
var lengthOverride int
233-
c, lengthOverride, bytes, ok = parseBase128(bytes)
234-
if !ok || lengthOverride != 0 {
242+
c, bytes, ok = parseBase128(bytes)
243+
if !ok {
235244
return nil, false
236245
}
237246
oid = append(oid, c)

0 commit comments

Comments
 (0)