encoding/jsonpb: fix encoding of max/min Duration and max Timestamp

Bad off-by-one error:(

Change-Id: I47dfaa8529fcdb2d53a4fc67c1f046d2152fe8fe
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/173837
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Herbie Ong 2019-04-24 20:51:28 -07:00
parent 060cdacd3b
commit ad9c125737
3 changed files with 36 additions and 10 deletions

View File

@ -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,

View File

@ -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},

View File

@ -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.