@@ -523,6 +523,7 @@ typedef struct {
523523 upb_Arena* arena; /* TODO: should we have a tmp arena for tmp data? */
524524 const upb_DefPool* symtab;
525525 int depth;
526+ int result;
526527 upb_Status* status;
527528 jmp_buf err;
528529 int line;
@@ -1152,6 +1153,16 @@ static int64_t jsondec_strtoint64(jsondec* d, upb_StringView str) {
11521153 return ret;
11531154}
11541155
1156+ static void jsondec_checkempty(jsondec* d, upb_StringView str,
1157+ const upb_FieldDef* f) {
1158+ if (str.size != 0) return;
1159+ d->result = kUpb_JsonDecodeResult_OkWithEmptyStringNumerics;
1160+ upb_Status_SetErrorFormat(d->status,
1161+ "Empty string is not a valid number (field: %s). "
1162+ "This will be an error in a future version.",
1163+ upb_FieldDef_FullName(f));
1164+ }
1165+
11551166/* Primitive value types ******************************************************/
11561167
11571168/* Parse INT32 or INT64 value. */
@@ -1173,6 +1184,7 @@ static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) {
11731184 }
11741185 case JD_STRING: {
11751186 upb_StringView str = jsondec_string(d);
1187+ jsondec_checkempty(d, str, f);
11761188 val.int64_val = jsondec_strtoint64(d, str);
11771189 break;
11781190 }
@@ -1210,6 +1222,7 @@ static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) {
12101222 }
12111223 case JD_STRING: {
12121224 upb_StringView str = jsondec_string(d);
1225+ jsondec_checkempty(d, str, f);
12131226 val.uint64_val = jsondec_strtouint64(d, str);
12141227 break;
12151228 }
@@ -1238,14 +1251,26 @@ static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) {
12381251 break;
12391252 case JD_STRING:
12401253 str = jsondec_string(d);
1241- if (jsondec_streql(str, "NaN")) {
1254+ if (str.size == 0) {
1255+ jsondec_checkempty(d, str, f);
1256+ val.double_val = 0.0;
1257+ } else if (jsondec_streql(str, "NaN")) {
12421258 val.double_val = NAN;
12431259 } else if (jsondec_streql(str, "Infinity")) {
12441260 val.double_val = INFINITY;
12451261 } else if (jsondec_streql(str, "-Infinity")) {
12461262 val.double_val = -INFINITY;
12471263 } else {
1248- val.double_val = strtod(str.data, NULL);
1264+ char* end;
1265+ val.double_val = strtod(str.data, &end);
1266+ if (end != str.data + str.size) {
1267+ d->result = kUpb_JsonDecodeResult_OkWithEmptyStringNumerics;
1268+ upb_Status_SetErrorFormat(
1269+ d->status,
1270+ "Non-number characters in quoted number (field: %s). "
1271+ "This will be an error in a future version.",
1272+ upb_FieldDef_FullName(f));
1273+ }
12491274 }
12501275 break;
12511276 default:
@@ -1987,10 +2012,10 @@ static void jsondec_wellknown(jsondec* d, upb_Message* msg,
19872012 }
19882013}
19892014
1990- static bool upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg,
1991- const upb_MessageDef* const m) {
2015+ static int upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg,
2016+ const upb_MessageDef* const m) {
19922017 UPB_ASSERT(!upb_Message_IsFrozen(msg));
1993- if (UPB_SETJMP(d->err)) return false ;
2018+ if (UPB_SETJMP(d->err)) return kUpb_JsonDecodeResult_Error ;
19942019
19952020 jsondec_tomsg(d, msg, m);
19962021
@@ -1999,16 +2024,19 @@ static bool upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg,
19992024 jsondec_consumews(d);
20002025
20012026 if (d->ptr == d->end) {
2002- return true ;
2027+ return d->result ;
20032028 } else {
20042029 jsondec_seterrmsg(d, "unexpected trailing characters");
2005- return false ;
2030+ return kUpb_JsonDecodeResult_Error ;
20062031 }
20072032}
20082033
2009- bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg,
2010- const upb_MessageDef* m, const upb_DefPool* symtab,
2011- int options, upb_Arena* arena, upb_Status* status) {
2034+ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size,
2035+ upb_Message* msg,
2036+ const upb_MessageDef* m,
2037+ const upb_DefPool* symtab,
2038+ int options, upb_Arena* arena,
2039+ upb_Status* status) {
20122040 UPB_ASSERT(!upb_Message_IsFrozen(msg));
20132041 jsondec d;
20142042
@@ -2021,6 +2049,7 @@ bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg,
20212049 d.status = status;
20222050 d.options = options;
20232051 d.depth = 64;
2052+ d.result = kUpb_JsonDecodeResult_Ok;
20242053 d.line = 1;
20252054 d.line_begin = d.ptr;
20262055 d.debug_field = NULL;
0 commit comments