Skip to content

Commit

Permalink
Merge pull request #544 from fxamacker/fxamacker/refactor-more
Browse files Browse the repository at this point in the history
Use "cbor:" prefixed error msg when decoding with non-default TimeTagToAnyMode setting
  • Loading branch information
fxamacker committed May 29, 2024
2 parents c8b278f + 20cde11 commit 22b6d0c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 19 deletions.
14 changes: 8 additions & 6 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -1874,23 +1874,25 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli
if tagNum == 1 {
tm = tm.UTC()
}
// Formats to RFC3339 and errors on time.Time values that cannot be
// represented by RFC3339.
// Call time.MarshalText() to format decoded time to RFC3339 format,
// and return error on time value that cannot be represented in
// RFC3339 format. E.g. year cannot exceed 9999, etc.
text, err := tm.Truncate(time.Second).MarshalText()
if err != nil {
return nil, err
return nil, fmt.Errorf("cbor: decoded time cannot be represented in RFC3339 format: %v", err)
}
return string(text), nil

case TimeTagToRFC3339Nano:
if tagNum == 1 {
tm = tm.UTC()
}
// Formats to RFC3339 with subsecond precision and errors on
// time.Time values that cannot be represented by RFC3339.
// Call time.MarshalText() to format decoded time to RFC3339 format,
// and return error on time value that cannot be represented in
// RFC3339 format with sub-second precision.
text, err := tm.MarshalText()
if err != nil {
return nil, err
return nil, fmt.Errorf("cbor: decoded time cannot be represented in RFC3339 format with sub-second precision: %v", err)
}
return string(text), nil

Expand Down
4 changes: 2 additions & 2 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8915,13 +8915,13 @@ func TestDecModeTimeTagToAny(t *testing.T) {
name: "error under TimeTagToRFC3339 when tag 1 represents a time that can't be represented by valid RFC3339",
opts: DecOptions{TimeTagToAny: TimeTagToRFC3339},
in: hexDecode("c11b0000003afff44181"), // 1(253402300801)
wantErrMessage: "Time.MarshalText: year outside of range [0,9999]",
wantErrMessage: "cbor: decoded time cannot be represented in RFC3339 format: Time.MarshalText: year outside of range [0,9999]",
},
{
name: "error under TimeTagToRFC3339Nano when tag 1 represents a time that can't be represented by valid RFC3339",
opts: DecOptions{TimeTagToAny: TimeTagToRFC3339Nano},
in: hexDecode("c11b0000003afff44181"), // 1(253402300801)
wantErrMessage: "Time.MarshalText: year outside of range [0,9999]",
wantErrMessage: "cbor: decoded time cannot be represented in RFC3339 format with sub-second precision: Time.MarshalText: year outside of range [0,9999]",
},
} {
t.Run(tc.name, func(t *testing.T) {
Expand Down
34 changes: 23 additions & 11 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,9 @@ func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error {
if v.Kind() == reflect.Float64 && (fopt == ShortestFloatNone || cannotFitFloat32(f64)) {
// Encode float64
// Don't use encodeFloat64() because it cannot be inlined.
var scratch [9]byte
const argumentSize = 8
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | byte(additionalInformationAsFloat64)
binary.BigEndian.PutUint64(scratch[1:], math.Float64bits(f64))
e.Write(scratch[:])
Expand All @@ -1005,20 +1007,24 @@ func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error {
if p == float16.PrecisionExact {
// Encode float16
// Don't use encodeFloat16() because it cannot be inlined.
var scratch [3]byte
const argumentSize = 2
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat16
binary.BigEndian.PutUint16(scratch[1:], uint16(f16))
e.Write(scratch[:3])
e.Write(scratch[:])
return nil
}
}

// Encode float32
// Don't use encodeFloat32() because it cannot be inlined.
var scratch [5]byte
const argumentSize = 4
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat32
binary.BigEndian.PutUint32(scratch[1:], math.Float32bits(f32))
e.Write(scratch[:5])
e.Write(scratch[:])
return nil
}

Expand Down Expand Up @@ -1104,26 +1110,32 @@ func encodeNaN(e *bytes.Buffer, em *encMode, v reflect.Value) error {
}

func encodeFloat16(e *bytes.Buffer, f16 float16.Float16) error {
var scratch [3]byte
const argumentSize = 2
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat16
binary.BigEndian.PutUint16(scratch[1:], uint16(f16))
e.Write(scratch[:3])
e.Write(scratch[:])
return nil
}

func encodeFloat32(e *bytes.Buffer, f32 float32) error {
var scratch [5]byte
const argumentSize = 4
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat32
binary.BigEndian.PutUint32(scratch[1:], math.Float32bits(f32))
e.Write(scratch[:5])
e.Write(scratch[:])
return nil
}

func encodeFloat64(e *bytes.Buffer, f64 float64) error {
var scratch [9]byte
const argumentSize = 8
const headSize = 1 + argumentSize
var scratch [headSize]byte
scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat64
binary.BigEndian.PutUint64(scratch[1:], math.Float64bits(f64))
e.Write(scratch[:9])
e.Write(scratch[:])
return nil
}

Expand Down

0 comments on commit 22b6d0c

Please sign in to comment.