From 24e8e45690dba93c984e9b09da96820c13530e30 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 8 Sep 2020 17:42:14 -0700 Subject: [PATCH] parser release has a precondition --- bench/bench.cpp | 4 ++-- example/pretty.cpp | 2 +- fuzzing/fuzz_parser.cpp | 24 ++++++++++++------------ include/boost/json/impl/parse.ipp | 2 +- include/boost/json/impl/parser.ipp | 8 +++----- include/boost/json/parser.hpp | 18 ++++++++++-------- test/parser.cpp | 22 +++++----------------- test/snippets.cpp | 23 +++++++++++------------ 8 files changed, 45 insertions(+), 58 deletions(-) diff --git a/bench/bench.cpp b/bench/bench.cpp index 3c1bc36b..46179cb9 100644 --- a/bench/bench.cpp +++ b/bench/bench.cpp @@ -279,7 +279,7 @@ public: p.write(s.data(), s.size(), ec); if(! ec) p.finish(ec); - auto jv = p.release(ec); + auto jv = p.release(); } } @@ -346,7 +346,7 @@ public: p.write(s.data(), s.size(), ec); if(! ec) p.finish(ec); - auto jv = p.release(ec); + auto jv = p.release(); } } diff --git a/example/pretty.cpp b/example/pretty.cpp index 47e5c5f3..62aa56f8 100644 --- a/example/pretty.cpp +++ b/example/pretty.cpp @@ -41,7 +41,7 @@ parse_file( char const* filename ) p.finish( ec ); if( ec ) return nullptr; - return p.release( ec ); + return p.release(); } void diff --git a/fuzzing/fuzz_parser.cpp b/fuzzing/fuzz_parser.cpp index d367668c..e9c02773 100644 --- a/fuzzing/fuzz_parser.cpp +++ b/fuzzing/fuzz_parser.cpp @@ -13,10 +13,11 @@ using namespace boost::json; bool -fuzz_parser(parse_options popt,string_view sv) +fuzz_parser( + parse_options opt, + string_view sv) { - - parser p(storage_ptr{},popt); + parser p(storage_ptr{}, opt); error_code ec; // This must be called once before parsing every new JSON @@ -31,9 +32,8 @@ fuzz_parser(parse_options popt,string_view sv) // Take ownership of the resulting value. if(! ec) { - value jv = p.release( ec ); - if(! ec ) - return serialize(jv).size()==42; + value jv = p.release(); + return serialize(jv).size()==42; } return false; } @@ -46,11 +46,11 @@ LLVMFuzzerTestOneInput( if(size<1) return 0; - parse_options popt; - popt.allow_comments=!!(data[0]&0x1); - popt.allow_trailing_commas=!!(data[0]&0x2); - popt.allow_invalid_utf8=!!(data[0]&0x4); - popt.max_depth= (data[0]>>3); + parse_options opt; + opt.allow_comments=!!(data[0]&0x1); + opt.allow_trailing_commas=!!(data[0]&0x2); + opt.allow_invalid_utf8=!!(data[0]&0x4); + opt.max_depth= (data[0]>>3); data+=1; size-=1; @@ -61,7 +61,7 @@ LLVMFuzzerTestOneInput( string_view view{ reinterpret_cast( data), size}; - fuzz_parser(popt,view); + fuzz_parser(opt,view); } catch(...) { diff --git a/include/boost/json/impl/parse.ipp b/include/boost/json/impl/parse.ipp index 071dae0b..4cfb232e 100644 --- a/include/boost/json/impl/parse.ipp +++ b/include/boost/json/impl/parse.ipp @@ -38,7 +38,7 @@ parse( p.finish(ec); if(ec) return nullptr; - return p.release(ec); + return p.release(); } value diff --git a/include/boost/json/impl/parser.ipp b/include/boost/json/impl/parser.ipp index 0e523bc1..c2dba8ee 100644 --- a/include/boost/json/impl/parser.ipp +++ b/include/boost/json/impl/parser.ipp @@ -268,12 +268,10 @@ finish(error_code& ec) value parser:: -release(error_code& ec) +release() { - if(p_.done()) - return p_.handler().st.release(); - ec = error::incomplete; - return nullptr; + BOOST_ASSERT(p_.done()); + return p_.handler().st.release(); } BOOST_JSON_NS_END diff --git a/include/boost/json/parser.hpp b/include/boost/json/parser.hpp index 756da16a..abf5186c 100644 --- a/include/boost/json/parser.hpp +++ b/include/boost/json/parser.hpp @@ -529,30 +529,32 @@ public: /** Return the parsed JSON as a @ref value. - If @ref done() returns `true`, then the - parsed value is returned. Otherwise, - the error is set to indicate failure. It + This returns the parsed value. is necessary to call @ref reset after calling this function in order to parse another JSON. + Undefined behavior results if the parser is + not done, or if an error occurred during + parsing. + + @par Preconditions + @code + this->done() == true + @endcode @par Complexity - Constant. @par Exception Safety - Strong guarantee. If an exception occurs, the valid operations are @ref reset or destruction. @return The parsed value. Ownership of this value is transferred to the caller. - - @param ec Set to the error, if any occurred. */ BOOST_JSON_DECL value - release(error_code& ec); + release(); }; BOOST_JSON_NS_END diff --git a/test/parser.cpp b/test/parser.cpp index 6915b15a..7f5731aa 100644 --- a/test/parser.cpp +++ b/test/parser.cpp @@ -70,7 +70,7 @@ public: if(BOOST_TEST(! ec)) p.finish(ec); BOOST_TEST(! ec); - return p.release(ec); + return p.release(); } void @@ -144,7 +144,7 @@ public: if(BOOST_TEST(! ec)) p.finish(ec); if(BOOST_TEST(! ec)) - f(p.release(ec), po); + f(p.release(), po); } } } @@ -302,7 +302,7 @@ public: p.finish(ec); if(BOOST_TEST(! ec)) check_round_trip( - p.release(ec)); + p.release()); } } } @@ -331,8 +331,7 @@ public: p.finish(ec); if(! BOOST_TEST(! ec)) return 0; - auto const jv = p.release(ec); - BOOST_TEST(! ec); + auto const jv = p.release(); double const d = jv.as_double(); grind_double(s, d); return d; @@ -773,14 +772,6 @@ public: p.reset(); } - // release before done - { - parser p; - error_code ec; - p.release(ec); - BOOST_TEST(ec == error::incomplete); - } - // write(char const*, size_t, error_code&) { { @@ -930,10 +921,7 @@ R"xx({ if(BOOST_TEST(! ec)) p.finish(ec); if(BOOST_TEST(! ec)) - { - BOOST_TEST(serialize(p.release(ec)) == out); - BOOST_TEST(! ec); - } + BOOST_TEST(serialize(p.release()) == out); } void diff --git a/test/snippets.cpp b/test/snippets.cpp index 6a87bc92..9d9baf2e 100644 --- a/test/snippets.cpp +++ b/test/snippets.cpp @@ -759,9 +759,11 @@ usingParsing() if( ! ec ) p.finish( ec ); + if( ec ) + return; // Take ownership of the resulting value. - value jv = p.release( ec ); + value jv = p.release(); // At this point the parser may be re-used by calling p.reset() again. @@ -785,12 +787,11 @@ usingParsing() p.write( "3,4,5]", 6, ec ); if(! ec) p.finish( ec ); + if( ec ) + return; // Take ownership of the resulting value. - if(! ec) - value jv = p.release( ec ); - - assert(! ec ); + value jv = p.release( ); // At this point the parser may be re-used by calling p.reset() again. @@ -812,9 +813,11 @@ usingParsing() p.write( "[1,2,3,4,5]", 11, ec ); if( ! ec ) p.finish( ec ); + if( ec ) + return; // The value will use the monotonic resource created above - value jv = p.release( ec ); + value jv = p.release(); } //] @@ -836,9 +839,7 @@ usingParsing() assert( ! ec ); - value jv = p.release( ec ); - - assert( ! ec ); + value jv = p.release(); // The intermediate storage that was used // for the last value will be reused here. @@ -850,9 +851,7 @@ usingParsing() assert( ! ec ); - jv = p.release( ec ); - - assert( ! ec ); + jv = p.release(); //] }