Lexer, parser, stream adapter, SAX: remove checks that invariants make dead

Branch coverage of the test suite and of 24k mutated inputs showed
these conditions as never taken; each is implied by the code around it:

- lexer: `next_unget` in get_codepoint_bulk() and scan_literal_bulk().
  unget() is only called at the end of scan_number(), in scan_comment()
  and in skip_bom(); every token scan starts with a plain get() in
  skip_whitespace() that consumes a pending unget, and nothing between
  that get() and the bulk helpers ungets (now asserts, as in
  get_after_string_run())
- lexer: `number_type == value_integer` in convert_integer(): both
  callers exclude value_float and the type has three values
- parser: `!context.empty()` in exception_message(): all callers pass a
  literal
- input_stream_adapter: `refill` in get_character_slow(): the function
  is only called after get_character() found the get area exhausted,
  and the variable recomputed that comparison
- json_sax_dom_callback_parser: `ref_stack.back()` in key() (the null
  case returned a few lines earlier, and the callback in between cannot
  reach ref_stack), `is_structured()` in end_object() (non-null entries
  are only pushed for objects and arrays), `!key_stack.empty()` in
  current_key() (a kept object pushed its key before any value)

No change in behaviour: a build that aborts on each removed side passes
the test suite, the fuzz corpora and 40k random documents through every
input adapter in four macro configurations.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-11-02 09:41:00 +01:00
1 parent 2301f01284
commit f093573828
5 files changed
+42 -54

No files matched your search

+3 -4
View File
@@ -1737,7 +1737,7 @@ class json_sax_dom_callback_parser : public json_sax_dom_error_state
key_stack.push_back(val);
// add discarded value at the given key and store the reference for later
if (keep && ref_stack.back())
if (keep)
{
auto& obj = *ref_stack.back()->m_data.m_value.object;
// a single lookup: insert the placeholder, or find the existing member
@@ -1794,7 +1794,7 @@ class json_sax_dom_callback_parser : public json_sax_dom_error_state
const string_t object_key = pop_container();
if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
if (!ref_stack.empty() && ref_stack.back())
{
// remove discarded value
remove_discarded_value(*ref_stack.back(), object_key);
@@ -1960,8 +1960,7 @@ class json_sax_dom_callback_parser : public json_sax_dom_error_state
*/
string_t current_key() const
{
if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_object()
&& !key_stack.empty())
if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_object())
{
return key_stack.back();
}