Skip to content

Commit

Permalink
fixed formatting and parsing of negative durations between -1s and 0s
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 461663523
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Jul 18, 2022
1 parent 24f567b commit 470d632
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
13 changes: 9 additions & 4 deletions upb/json_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@ static const char* jsondec_buftouint64(jsondec* d, const char* ptr,
}

static const char* jsondec_buftoint64(jsondec* d, const char* ptr,
const char* end, int64_t* val) {
const char* end, int64_t* val,
bool* is_neg) {
bool neg = false;
uint64_t u64;

Expand All @@ -646,6 +647,9 @@ static const char* jsondec_buftoint64(jsondec* d, const char* ptr,
}

*val = neg ? -u64 : u64;
if (is_neg) {
*is_neg = neg;
}
return ptr;
}

Expand All @@ -661,7 +665,7 @@ static uint64_t jsondec_strtouint64(jsondec* d, upb_StringView str) {
static int64_t jsondec_strtoint64(jsondec* d, upb_StringView str) {
const char* end = str.data + str.size;
int64_t ret;
if (jsondec_buftoint64(d, str.data, end, &ret) != end) {
if (jsondec_buftoint64(d, str.data, end, &ret, NULL) != end) {
jsondec_err(d, "Non-number characters in quoted integer");
}
return ret;
Expand Down Expand Up @@ -1130,9 +1134,10 @@ static void jsondec_duration(jsondec* d, upb_Message* msg,
const char* ptr = str.data;
const char* end = ptr + str.size;
const int64_t max = (uint64_t)3652500 * 86400;
bool neg = false;

/* "3.000000001s", "3s", etc. */
ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val, &neg);
nanos.int32_val = jsondec_nanos(d, &ptr, end);

if (end - ptr != 1 || *ptr != 's') {
Expand All @@ -1143,7 +1148,7 @@ static void jsondec_duration(jsondec* d, upb_Message* msg,
jsondec_err(d, "Duration out of range");
}

if (seconds.int64_val < 0) {
if (neg) {
nanos.int32_val = -nanos.int32_val;
}

Expand Down
14 changes: 12 additions & 2 deletions upb/json_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,27 @@ static void jsonenc_duration(jsonenc* e, const upb_Message* msg,
const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2);
int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val;
int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val;
bool negative = false;

if (seconds > 315576000000 || seconds < -315576000000 ||
(seconds < 0) != (nanos < 0)) {
(seconds != 0 && nanos != 0 && (seconds < 0) != (nanos < 0))) {
jsonenc_err(e, "bad duration");
}

if (seconds < 0) {
negative = true;
seconds = -seconds;
}
if (nanos < 0) {
negative = true;
nanos = -nanos;
}

jsonenc_printf(e, "\"%" PRId64, seconds);
jsonenc_putstr(e, "\"");
if (negative) {
jsonenc_putstr(e, "-");
}
jsonenc_printf(e, "%" PRId64, seconds);
jsonenc_nanos(e, nanos);
jsonenc_putstr(e, "s\"");
}
Expand Down

0 comments on commit 470d632

Please sign in to comment.