diff --git a/encoding/jsonpb/decode_test.go b/encoding/jsonpb/decode_test.go index cb99bcdc..9fb95d6d 100644 --- a/encoding/jsonpb/decode_test.go +++ b/encoding/jsonpb/decode_test.go @@ -1822,6 +1822,16 @@ func TestUnmarshal(t *testing.T) { inputMessage: &knownpb.Duration{}, inputText: `"0.5s"`, wantMessage: &knownpb.Duration{Nanos: 5e8}, + }, { + desc: "Duration max value", + inputMessage: &knownpb.Duration{}, + inputText: `"315576000000.999999999s"`, + wantMessage: &knownpb.Duration{Seconds: 315576000000, Nanos: 999999999}, + }, { + desc: "Duration min value", + inputMessage: &knownpb.Duration{}, + inputText: `"-315576000000.999999999s"`, + wantMessage: &knownpb.Duration{Seconds: -315576000000, Nanos: -999999999}, }, { desc: "Duration with +secs out of range", inputMessage: &knownpb.Duration{}, @@ -1883,22 +1893,22 @@ func TestUnmarshal(t *testing.T) { inputText: `"2019-03-19T23:03:21.000000001Z"`, wantMessage: &knownpb.Timestamp{Seconds: 1553036601, Nanos: 1}, }, { - desc: "Timestamp upper limit", + desc: "Timestamp max value", inputMessage: &knownpb.Timestamp{}, inputText: `"9999-12-31T23:59:59.999999999Z"`, wantMessage: &knownpb.Timestamp{Seconds: 253402300799, Nanos: 999999999}, }, { - desc: "Timestamp above upper limit", + desc: "Timestamp above max value", inputMessage: &knownpb.Timestamp{}, inputText: `"9999-12-31T23:59:59-01:00"`, wantErr: true, }, { - desc: "Timestamp lower limit", + desc: "Timestamp min value", inputMessage: &knownpb.Timestamp{}, inputText: `"0001-01-01T00:00:00Z"`, wantMessage: &knownpb.Timestamp{Seconds: -62135596800}, }, { - desc: "Timestamp below lower limit", + desc: "Timestamp below min value", inputMessage: &knownpb.Timestamp{}, inputText: `"0001-01-01T00:00:00+01:00"`, wantErr: true, diff --git a/encoding/jsonpb/encode_test.go b/encoding/jsonpb/encode_test.go index 0c128617..b0e39733 100644 --- a/encoding/jsonpb/encode_test.go +++ b/encoding/jsonpb/encode_test.go @@ -1421,6 +1421,14 @@ func TestMarshal(t *testing.T) { desc: "Duration with -secs -nanos", input: &knownpb.Duration{Seconds: -123, Nanos: -450}, want: `"-123.000000450s"`, + }, { + desc: "Duration max value", + input: &knownpb.Duration{Seconds: 315576000000, Nanos: 999999999}, + want: `"315576000000.999999999s"`, + }, { + desc: "Duration min value", + input: &knownpb.Duration{Seconds: -315576000000, Nanos: -999999999}, + want: `"-315576000000.999999999s"`, }, { desc: "Duration with +secs -nanos", input: &knownpb.Duration{Seconds: 1, Nanos: -1}, @@ -1465,6 +1473,14 @@ func TestMarshal(t *testing.T) { desc: "Timestamp with 3-digit nanos", input: &knownpb.Timestamp{Nanos: 1e7}, want: `"1970-01-01T00:00:00.010Z"`, + }, { + desc: "Timestamp max value", + input: &knownpb.Timestamp{Seconds: 253402300799, Nanos: 999999999}, + want: `"9999-12-31T23:59:59.999999999Z"`, + }, { + desc: "Timestamp min value", + input: &knownpb.Timestamp{Seconds: -62135596800}, + want: `"0001-01-01T00:00:00Z"`, }, { desc: "Timestamp with +secs out of range", input: &knownpb.Timestamp{Seconds: 253402300800}, diff --git a/encoding/jsonpb/well_known_types.go b/encoding/jsonpb/well_known_types.go index 512adc2e..19c82302 100644 --- a/encoding/jsonpb/well_known_types.go +++ b/encoding/jsonpb/well_known_types.go @@ -644,10 +644,10 @@ func (o MarshalOptions) marshalDuration(m pref.Message) error { secs := secsVal.Int() nanos := nanosVal.Int() if secs < -maxSecondsInDuration || secs > maxSecondsInDuration { - return errors.New("%s: seconds out of range", msgType.FullName()) + return errors.New("%s: seconds out of range %v", msgType.FullName(), secs) } - if nanos <= -secondsInNanos || nanos >= secondsInNanos { - return errors.New("%s: nanos out of range", msgType.FullName()) + if nanos < -secondsInNanos || nanos > secondsInNanos { + return errors.New("%s: nanos out of range %v", msgType.FullName(), nanos) } if (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0) { return errors.New("%s: signs of seconds and nanos do not match", msgType.FullName()) @@ -834,10 +834,10 @@ func (o MarshalOptions) marshalTimestamp(m pref.Message) error { secs := secsVal.Int() nanos := nanosVal.Int() if secs < minTimestampSeconds || secs > maxTimestampSeconds { - return errors.New("%s: seconds out of range %q", msgType.FullName(), secs) + return errors.New("%s: seconds out of range %v", msgType.FullName(), secs) } - if nanos < 0 || nanos >= secondsInNanos { - return errors.New("%s: nanos out of range %q", msgType.FullName(), nanos) + if nanos < 0 || nanos > secondsInNanos { + return errors.New("%s: nanos out of range %v", msgType.FullName(), nanos) } // Uses RFC 3339, where generated output will be Z-normalized and uses 0, 3, // 6 or 9 fractional digits.