From 3f436a63b9ca90890d7cadc5c4e10247fb138c9c Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Tue, 28 May 2024 14:12:25 -0500 Subject: [PATCH 1/2] Refactor to remove more magic numbers --- encode.go | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/encode.go b/encode.go index 90a1a59d..b45147f5 100644 --- a/encode.go +++ b/encode.go @@ -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[:]) @@ -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 } @@ -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 } From 20cde110352b63665f49d841469bd930c552ae01 Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Tue, 28 May 2024 20:44:41 -0500 Subject: [PATCH 2/2] Use "cbor:" prefixed error msg for TimeTagToAnyMode --- decode.go | 14 ++++++++------ decode_test.go | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/decode.go b/decode.go index 5449d533..06ee2946 100644 --- a/decode.go +++ b/decode.go @@ -1874,11 +1874,12 @@ 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 @@ -1886,11 +1887,12 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli 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 diff --git a/decode_test.go b/decode_test.go index 6eebb946..b5060fc0 100644 --- a/decode_test.go +++ b/decode_test.go @@ -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) {