diff --git a/tests/json/test_json.cc b/tests/json/test_json.cc index 1f7d364267..3dc4a6c5e7 100644 --- a/tests/json/test_json.cc +++ b/tests/json/test_json.cc @@ -176,7 +176,7 @@ void test_json_roundtrip_message(const char* json_src, upb::json::PrinterPtr printer = upb::json::PrinterPtr::Create( env.arena(), serialize_handlers, data_sink.Sink()); upb::json::ParserPtr parser = upb::json::ParserPtr::Create( - env.arena(), parser_method, NULL, printer.input(), false); + env.arena(), parser_method, NULL, printer.input(), env.status(), false); env.ResetBytesSink(parser.input()); env.Reset(json_src, strlen(json_src), false, false); diff --git a/tests/pb/test_decoder.cc b/tests/pb/test_decoder.cc index b2dd812ec1..3c41801363 100644 --- a/tests/pb/test_decoder.cc +++ b/tests/pb/test_decoder.cc @@ -454,8 +454,9 @@ upb::pb::DecoderMethodPtr global_method; upb::pb::DecoderPtr CreateDecoder(upb::Arena* arena, upb::pb::DecoderMethodPtr method, - upb::Sink sink) { - upb::pb::DecoderPtr ret = upb::pb::DecoderPtr::Create(arena, method, sink); + upb::Sink sink, upb::Status* status) { + upb::pb::DecoderPtr ret = + upb::pb::DecoderPtr::Create(arena, method, sink, status); ret.set_max_nesting(MAX_NESTING); return ret; } @@ -556,7 +557,7 @@ void do_run_decoder(VerboseParserEnvironment* env, upb::pb::DecoderPtr decoder, void run_decoder(const string& proto, const string* expected_output) { VerboseParserEnvironment env(filter_hash != 0); upb::Sink sink(global_handlers, &closures[0]); - upb::pb::DecoderPtr decoder = CreateDecoder(env.arena(), global_method, sink); + upb::pb::DecoderPtr decoder = CreateDecoder(env.arena(), global_method, sink, env.status()); env.ResetBytesSink(decoder.input()); for (size_t i = 0; i < proto.size(); i++) { for (size_t j = i; j < UPB_MIN(proto.size(), i + 5); j++) { @@ -874,7 +875,8 @@ void test_valid() { upb::Status status; upb::Arena arena; upb::Sink sink(global_handlers, &closures[0]); - upb::pb::DecoderPtr decoder = CreateDecoder(&arena, global_method, sink); + upb::pb::DecoderPtr decoder = + CreateDecoder(&arena, global_method, sink, &status); output.clear(); bool ok = upb::PutBuffer(std::string(), decoder.input()); ASSERT(ok); @@ -1161,7 +1163,7 @@ void test_emptyhandlers(upb::SymbolTable* symtab, bool allowjit) { VerboseParserEnvironment env(filter_hash != 0); upb::Sink sink(global_method.dest_handlers(), &closures[0]); upb::pb::DecoderPtr decoder = - CreateDecoder(env.arena(), global_method, sink); + CreateDecoder(env.arena(), global_method, sink, env.status()); env.ResetBytesSink(decoder.input()); env.Reset(testdata[i].data, testdata[i].length, true, false); ASSERT(env.Start()); diff --git a/tests/pb/test_encoder.cc b/tests/pb/test_encoder.cc index 7145097b9a..a042d3d009 100644 --- a/tests/pb/test_encoder.cc +++ b/tests/pb/test_encoder.cc @@ -48,7 +48,7 @@ void test_pb_roundtrip() { upb::pb::EncoderPtr encoder = upb::pb::EncoderPtr::Create(&arena, encoder_handlers, string_sink.input()); upb::pb::DecoderPtr decoder = - upb::pb::DecoderPtr::Create(&arena, method, encoder.input()); + upb::pb::DecoderPtr::Create(&arena, method, encoder.input(), &status); ok = upb::PutBuffer(input, decoder.input()); ASSERT(ok); ASSERT(input == output); diff --git a/tests/test_util.h b/tests/test_util.h index 04ca3fb919..680673d27a 100644 --- a/tests/test_util.h +++ b/tests/test_util.h @@ -32,21 +32,6 @@ class VerboseParserEnvironment { /* Pass verbose=true to print detailed diagnostics to stderr. */ VerboseParserEnvironment(bool verbose) : verbose_(verbose) {} - static bool OnError(void *ud, const upb::Status* status) { - VerboseParserEnvironment* env = static_cast(ud); - - if (env->expect_error_ && env->verbose_) { - fprintf(stderr, "Encountered error, as expected: "); - } else if (!env->expect_error_) { - fprintf(stderr, "Encountered unexpected error: "); - } else { - return false; - } - - fprintf(stderr, "%s\n", status->error_message()); - return false; - } - void Reset(const char *buf, size_t len, bool may_skip, bool expect_error) { buf_ = buf; len_ = len; @@ -99,6 +84,17 @@ class VerboseParserEnvironment { return false; } + if (!status_.ok()) { + if (expect_error_ && verbose_) { + fprintf(stderr, "Encountered error, as expected: %s", + status_.error_message()); + } else if (!expect_error_) { + fprintf(stderr, "Encountered unexpected error: %s", + status_.error_message()); + return false; + } + } + return true; } @@ -175,6 +171,7 @@ class VerboseParserEnvironment { bool SkippedWithNull() { return skipped_with_null_; } upb::Arena* arena() { return &arena_; } + upb::Status* status() { return &status_; } private: upb::Arena arena_; diff --git a/upb/json/parser.c b/upb/json/parser.c index a594bfdb32..5fe20efc13 100644 --- a/upb/json/parser.c +++ b/upb/json/parser.c @@ -306,8 +306,9 @@ static void json_parser_any_frame_set_payload_type( /* Initialize parser. */ parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type); upb_sink_reset(&frame->sink, h, encoder); - frame->parser = upb_json_parser_create(p->arena, parser_method, p->symtab, - frame->sink, p->ignore_json_unknown); + frame->parser = + upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink, + p->status, p->ignore_json_unknown); } static void json_parser_any_frame_free(upb_jsonparser_any_frame *frame) { @@ -2379,11 +2380,11 @@ static bool is_string_wrapper_object(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 2541 "upb/json/parser.rl" +#line 2542 "upb/json/parser.rl" -#line 2387 "upb/json/parser.c" +#line 2388 "upb/json/parser.c" static const char _json_actions[] = { 0, 1, 0, 1, 1, 1, 3, 1, 4, 1, 6, 1, 7, 1, 8, 1, @@ -2630,7 +2631,7 @@ static const int json_en_value_machine = 75; static const int json_en_main = 1; -#line 2544 "upb/json/parser.rl" +#line 2545 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -2653,7 +2654,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 2657 "upb/json/parser.c" +#line 2658 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -2728,83 +2729,83 @@ _match: switch ( *_acts++ ) { case 1: -#line 2392 "upb/json/parser.rl" +#line 2393 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 2: -#line 2394 "upb/json/parser.rl" +#line 2395 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 23;goto _again;} } break; case 3: -#line 2398 "upb/json/parser.rl" +#line 2399 "upb/json/parser.rl" { start_text(parser, p); } break; case 4: -#line 2399 "upb/json/parser.rl" +#line 2400 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 5: -#line 2405 "upb/json/parser.rl" +#line 2406 "upb/json/parser.rl" { start_hex(parser); } break; case 6: -#line 2406 "upb/json/parser.rl" +#line 2407 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 7: -#line 2407 "upb/json/parser.rl" +#line 2408 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 8: -#line 2413 "upb/json/parser.rl" +#line 2414 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 9: -#line 2419 "upb/json/parser.rl" +#line 2420 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 10: -#line 2431 "upb/json/parser.rl" +#line 2432 "upb/json/parser.rl" { start_duration_base(parser, p); } break; case 11: -#line 2432 "upb/json/parser.rl" +#line 2433 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_duration_base(parser, p)); } break; case 12: -#line 2434 "upb/json/parser.rl" +#line 2435 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 13: -#line 2439 "upb/json/parser.rl" +#line 2440 "upb/json/parser.rl" { start_timestamp_base(parser, p); } break; case 14: -#line 2440 "upb/json/parser.rl" +#line 2441 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_base(parser, p)); } break; case 15: -#line 2442 "upb/json/parser.rl" +#line 2443 "upb/json/parser.rl" { start_timestamp_fraction(parser, p); } break; case 16: -#line 2443 "upb/json/parser.rl" +#line 2444 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } break; case 17: -#line 2445 "upb/json/parser.rl" +#line 2446 "upb/json/parser.rl" { start_timestamp_zone(parser, p); } break; case 18: -#line 2446 "upb/json/parser.rl" +#line 2447 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } break; case 19: -#line 2448 "upb/json/parser.rl" +#line 2449 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 20: -#line 2453 "upb/json/parser.rl" +#line 2454 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { {stack[top++] = cs; cs = 47;goto _again;} @@ -2816,11 +2817,11 @@ _match: } break; case 21: -#line 2464 "upb/json/parser.rl" +#line 2465 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 75;goto _again;} } break; case 22: -#line 2469 "upb/json/parser.rl" +#line 2470 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_member(parser, p); @@ -2830,11 +2831,11 @@ _match: } break; case 23: -#line 2476 "upb/json/parser.rl" +#line 2477 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 24: -#line 2479 "upb/json/parser.rl" +#line 2480 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { end_any_member(parser, p); @@ -2844,7 +2845,7 @@ _match: } break; case 25: -#line 2490 "upb/json/parser.rl" +#line 2491 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_object(parser, p); @@ -2854,7 +2855,7 @@ _match: } break; case 26: -#line 2499 "upb/json/parser.rl" +#line 2500 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { CHECK_RETURN_TOP(end_any_object(parser, p)); @@ -2864,54 +2865,54 @@ _match: } break; case 27: -#line 2511 "upb/json/parser.rl" +#line 2512 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 28: -#line 2515 "upb/json/parser.rl" +#line 2516 "upb/json/parser.rl" { end_array(parser); } break; case 29: -#line 2520 "upb/json/parser.rl" +#line 2521 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_number(parser, p)); } break; case 30: -#line 2521 "upb/json/parser.rl" +#line 2522 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 31: -#line 2523 "upb/json/parser.rl" +#line 2524 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 32: -#line 2524 "upb/json/parser.rl" +#line 2525 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 33: -#line 2526 "upb/json/parser.rl" +#line 2527 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2528 "upb/json/parser.rl" +#line 2529 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2530 "upb/json/parser.rl" +#line 2531 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 36: -#line 2532 "upb/json/parser.rl" +#line 2533 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject_full(parser)); } break; case 37: -#line 2533 "upb/json/parser.rl" +#line 2534 "upb/json/parser.rl" { end_subobject_full(parser); } break; case 38: -#line 2538 "upb/json/parser.rl" +#line 2539 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 2915 "upb/json/parser.c" +#line 2916 "upb/json/parser.c" } } @@ -2928,32 +2929,32 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -#line 2390 "upb/json/parser.rl" +#line 2391 "upb/json/parser.rl" { p--; {cs = stack[--top]; if ( p == pe ) goto _test_eof; goto _again;} } break; case 30: -#line 2521 "upb/json/parser.rl" +#line 2522 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 33: -#line 2526 "upb/json/parser.rl" +#line 2527 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2528 "upb/json/parser.rl" +#line 2529 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2530 "upb/json/parser.rl" +#line 2531 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 37: -#line 2533 "upb/json/parser.rl" +#line 2534 "upb/json/parser.rl" { end_subobject_full(parser); } break; -#line 2957 "upb/json/parser.c" +#line 2958 "upb/json/parser.c" } } } @@ -2961,7 +2962,7 @@ goto _again;} } _out: {} } -#line 2566 "upb/json/parser.rl" +#line 2567 "upb/json/parser.rl" if (p != pe) { upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p); @@ -3008,13 +3009,13 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -#line 3012 "upb/json/parser.c" +#line 3013 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 2612 "upb/json/parser.rl" +#line 2613 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); @@ -3071,6 +3072,7 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab* symtab, upb_sink output, + upb_status *status, bool ignore_json_unknown) { #ifndef NDEBUG const size_t size_before = upb_arena_bytesallocated(arena); @@ -3080,7 +3082,7 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, p->arena = arena; p->method = method; - p->status = NULL; + p->status = status; p->limit = p->stack + UPB_JSON_MAX_DEPTH; p->accumulate_buf = NULL; p->accumulate_buf_size = 0; diff --git a/upb/json/parser.h b/upb/json/parser.h index 2a06fcf019..6f3eaa75d9 100644 --- a/upb/json/parser.h +++ b/upb/json/parser.h @@ -71,6 +71,7 @@ upb_json_parser* upb_json_parser_create(upb_arena* a, const upb_json_parsermethod* m, const upb_symtab* symtab, upb_sink output, + upb_status *status, bool ignore_json_unknown); upb_bytessink upb_json_parser_input(upb_json_parser* p); @@ -84,12 +85,12 @@ class upb::json::ParserPtr { ParserPtr(upb_json_parser* ptr) : ptr_(ptr) {} static ParserPtr Create(Arena* arena, ParserMethodPtr method, - SymbolTable* symtab, Sink output, + SymbolTable* symtab, Sink output, Status* status, bool ignore_json_unknown) { upb_symtab* symtab_ptr = symtab ? symtab->ptr() : nullptr; - return ParserPtr(upb_json_parser_create(arena->ptr(), method.ptr(), - symtab_ptr, output.sink(), - ignore_json_unknown)); + return ParserPtr(upb_json_parser_create( + arena->ptr(), method.ptr(), symtab_ptr, output.sink(), status->ptr(), + ignore_json_unknown)); } BytesSink input() { return upb_json_parser_input(ptr_); } diff --git a/upb/json/parser.rl b/upb/json/parser.rl index a117d0c4c5..6f27630754 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -304,8 +304,9 @@ static void json_parser_any_frame_set_payload_type( /* Initialize parser. */ parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type); upb_sink_reset(&frame->sink, h, encoder); - frame->parser = upb_json_parser_create(p->arena, parser_method, p->symtab, - frame->sink, p->ignore_json_unknown); + frame->parser = + upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink, + p->status, p->ignore_json_unknown); } static void json_parser_any_frame_free(upb_jsonparser_any_frame *frame) { @@ -2665,6 +2666,7 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab* symtab, upb_sink output, + upb_status *status, bool ignore_json_unknown) { #ifndef NDEBUG const size_t size_before = upb_arena_bytesallocated(arena); @@ -2674,7 +2676,7 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, p->arena = arena; p->method = method; - p->status = NULL; + p->status = status; p->limit = p->stack + UPB_JSON_MAX_DEPTH; p->accumulate_buf = NULL; p->accumulate_buf_size = 0; diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c index 5068225675..f1617dbe37 100644 --- a/upb/pb/decoder.c +++ b/upb/pb/decoder.c @@ -991,7 +991,7 @@ void upb_pbdecoder_reset(upb_pbdecoder *d) { } upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, - upb_sink sink) { + upb_sink sink, upb_status *status) { const size_t default_max_nesting = 64; #ifndef NDEBUG size_t size_before = upb_arena_bytesallocated(a); @@ -1010,7 +1010,7 @@ upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, d->arena = a; d->limit = d->stack + default_max_nesting - 1; d->stack_size = default_max_nesting; - d->status = NULL; + d->status = status; upb_pbdecoder_reset(d); upb_bytessink_reset(&d->input_, &m->input_handler_, d); diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h index 6fcef033ba..5adfba83b3 100644 --- a/upb/pb/decoder.h +++ b/upb/pb/decoder.h @@ -102,7 +102,7 @@ extern "C" { upb_pbdecoder *upb_pbdecoder_create(upb_arena *arena, const upb_pbdecodermethod *method, - upb_sink output); + upb_sink output, upb_status *status); const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d); upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d); uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d); @@ -127,9 +127,9 @@ class upb::pb::DecoderPtr { * * The sink must match the given method. */ static DecoderPtr Create(Arena *arena, DecoderMethodPtr method, - upb::Sink output) { - return DecoderPtr( - upb_pbdecoder_create(arena->ptr(), method.ptr(), output.sink())); + upb::Sink output, Status *status) { + return DecoderPtr(upb_pbdecoder_create(arena->ptr(), method.ptr(), + output.sink(), status->ptr())); } /* Returns the DecoderMethod this decoder is parsing from. */