Skip to content

Commit

Permalink
Add and use InadmissibleTagContentTypeError
Browse files Browse the repository at this point in the history
Currently *errors.errorString is returned when unmarshalling
built-in tags (tag 0-3 and 21-23) with inadmissible content type.

This commit adds InadmissibleTagContentTypeError and returns this
error with the same error message as before when unmarshalling
build-in tags with inadmissible content type.
  • Loading branch information
fxamacker committed Jun 9, 2024
1 parent a0ec462 commit 752db06
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 20 deletions.
27 changes: 13 additions & 14 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,34 +139,33 @@ func validBuiltinTag(tagNum uint64, contentHead byte) error {
case tagNumRFC3339Time:
// Tag content (date/time text string in RFC 3339 format) must be string type.
if t != cborTypeTextString {
return fmt.Errorf(
"cbor: tag number %d must be followed by text string, got %s",
return newInadmissibleTagContentTypeError(
tagNumRFC3339Time,
t.String(),
)
"text string",
t.String())
}
return nil

case tagNumEpochTime:
// Tag content (epoch date/time) must be uint, int, or float type.
if t != cborTypePositiveInt && t != cborTypeNegativeInt && (contentHead < 0xf9 || contentHead > 0xfb) {
return fmt.Errorf(
"cbor: tag number %d must be followed by integer or floating-point number, got %s",
return newInadmissibleTagContentTypeError(
tagNumEpochTime,
t.String(),
)
"integer or floating-point number",
t.String())
}
return nil

case tagNumUnsignedBignum, tagNumNegativeBignum:
// Tag content (bignum) must be byte type.
if t != cborTypeByteString {
return fmt.Errorf(
"cbor: tag number %d or %d must be followed by byte string, got %s",
tagNumUnsignedBignum,
tagNumNegativeBignum,
t.String(),
)
return newInadmissibleTagContentTypeErrorf(
fmt.Sprintf(
"tag number %d or %d must be followed by byte string, got %s",
tagNumUnsignedBignum,
tagNumNegativeBignum,
t.String(),
))
}
return nil

Expand Down
39 changes: 39 additions & 0 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,45 @@ func (e *ByteStringExpectedFormatError) Unwrap() error {
return e.err
}

// InadmissibleTagContentTypeError is returned when unmarshaling built-in CBOR tags
// fails because of inadmissible type for tag content. Currently, the built-in
// CBOR tags in this codec are tags 0-3 and 21-23.
// See "Tag validity" in RFC 8949 Section 5.3.2.
type InadmissibleTagContentTypeError struct {
s string
tagNum int
expectedTagContentType string
gotTagContentType string
}

func newInadmissibleTagContentTypeError(
tagNum int,
expectedTagContentType string,
gotTagContentType string,
) *InadmissibleTagContentTypeError {
return &InadmissibleTagContentTypeError{
tagNum: tagNum,
expectedTagContentType: expectedTagContentType,
gotTagContentType: gotTagContentType,
}
}

func newInadmissibleTagContentTypeErrorf(s string) *InadmissibleTagContentTypeError {
return &InadmissibleTagContentTypeError{s: "cbor: " + s}

Check failure on line 281 in decode.go

View workflow job for this annotation

GitHub Actions / Lint

string `cbor: ` has 4 occurrences, make it a constant (goconst)
}

func (e *InadmissibleTagContentTypeError) Error() string {
if e.s == "" {
return fmt.Sprintf(
"cbor: tag number %d must be followed by %s, got %s",
e.tagNum,
e.expectedTagContentType,
e.gotTagContentType,
)
}
return e.s
}

// DupMapKeyMode specifies how to enforce duplicate map key. Two map keys are considered duplicates if:
// 1. When decoding into a struct, both keys match the same struct field. The keys are also
// considered duplicates if neither matches any field and decoding to interface{} would produce
Expand Down
11 changes: 5 additions & 6 deletions diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,10 @@ func (di *diagnose) item() error { //nolint:gocyclo
switch tagNum {
case tagNumUnsignedBignum:
if nt := di.d.nextCBORType(); nt != cborTypeByteString {
return fmt.Errorf(
"cbor: tag number %d must be followed by byte string, got %s",
return newInadmissibleTagContentTypeError(
tagNumUnsignedBignum,
nt.String(),
)
"byte string",
nt.String())
}

b, _ := di.d.parseByteString()
Expand All @@ -415,9 +414,9 @@ func (di *diagnose) item() error { //nolint:gocyclo

case tagNumNegativeBignum:
if nt := di.d.nextCBORType(); nt != cborTypeByteString {
return fmt.Errorf(
"cbor: tag number %d must be followed by byte string, got %s",
return newInadmissibleTagContentTypeError(
tagNumNegativeBignum,
"byte string",
nt.String(),
)
}
Expand Down

0 comments on commit 752db06

Please sign in to comment.