From 8c22567a4943b64e67462ad43f40e6796d1e4064 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 10 Sep 2026 17:18:40 +0200 Subject: [PATCH] Address review: drop unneeded backslash-escapes and duplicate scan loop '"' does not need escaping in a char literal, unlike in a string literal. find_ascii_copyable_run() also duplicated the byte-at-a-time search that already exists as the loop's own scalar tail; break into it instead of re-deriving the offset in a second, near-identical loop. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/input/string_scan.hpp | 10 ++----- include/nlohmann/detail/output/serializer.hpp | 20 ++++++------- single_include/nlohmann/json.hpp | 30 ++++++++----------- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/include/nlohmann/detail/input/string_scan.hpp b/include/nlohmann/detail/input/string_scan.hpp index 144fc9a25..6af0e6c5d 100644 --- a/include/nlohmann/detail/input/string_scan.hpp +++ b/include/nlohmann/detail/input/string_scan.hpp @@ -101,7 +101,7 @@ inline std::size_t find_string_special(const unsigned char* data, std::size_t n) // \u007f under ensure_ascii). inline bool is_ascii_copyable(unsigned char c) noexcept { - return c >= 0x20u && c < 0x7Fu && c != '\"' && c != '\\'; + return c >= 0x20u && c < 0x7Fu && c != '"' && c != '\\'; } // return the index of the first byte in [data, data+n) that is NOT @@ -126,13 +126,7 @@ inline std::size_t find_ascii_copyable_run(const unsigned char* data, std::size_ | (v & high); // >= 0x80 if (stop != 0) { - for (std::size_t j = 0; j < 8; ++j) - { - if (!is_ascii_copyable(data[i + j])) - { - return i + j; - } - } + break; } } for (; i < n; ++i) diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 481cc38fa..bc41568c5 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -168,7 +168,7 @@ class serializer for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i) { put_indent(new_indent); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\": "); dump_internal(i->second, true, ensure_ascii, indent_step, new_indent, depth + 1); @@ -179,7 +179,7 @@ class serializer JSON_ASSERT(i != val.m_data.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend()); put_indent(new_indent); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\": "); dump_internal(i->second, true, ensure_ascii, indent_step, new_indent, depth + 1); @@ -196,7 +196,7 @@ class serializer auto i = val.m_data.m_value.object->cbegin(); for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i) { - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\":"); dump_internal(i->second, false, ensure_ascii, indent_step, current_indent, depth + 1); @@ -206,7 +206,7 @@ class serializer // last element JSON_ASSERT(i != val.m_data.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend()); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\":"); dump_internal(i->second, false, ensure_ascii, indent_step, current_indent, depth + 1); @@ -280,9 +280,9 @@ class serializer case value_t::string: { - put_char('\"'); + put_char('"'); dump_escaped(*val.m_data.m_value.string, ensure_ascii); - put_char('\"'); + put_char('"'); return; } @@ -473,7 +473,7 @@ class serializer put_indent(frame.child_indent); } - put_char('\"'); + put_char('"'); dump_escaped(frame.object_it->first, ensure_ascii); if (pretty_print) @@ -631,9 +631,9 @@ class serializer case value_t::string: { - put_char('\"'); + put_char('"'); dump_escaped(*val.m_data.m_value.string, ensure_ascii); - put_char('\"'); + put_char('"'); return; } @@ -915,7 +915,7 @@ class serializer case 0x22: // quotation mark { string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\"'; + string_buffer[bytes++] = '"'; break; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a2ce9474f..0277cbbd7 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -8335,7 +8335,7 @@ inline std::size_t find_string_special(const unsigned char* data, std::size_t n) // \u007f under ensure_ascii). inline bool is_ascii_copyable(unsigned char c) noexcept { - return c >= 0x20u && c < 0x7Fu && c != '\"' && c != '\\'; + return c >= 0x20u && c < 0x7Fu && c != '"' && c != '\\'; } // return the index of the first byte in [data, data+n) that is NOT @@ -8360,13 +8360,7 @@ inline std::size_t find_ascii_copyable_run(const unsigned char* data, std::size_ | (v & high); // >= 0x80 if (stop != 0) { - for (std::size_t j = 0; j < 8; ++j) - { - if (!is_ascii_copyable(data[i + j])) - { - return i + j; - } - } + break; } } for (; i < n; ++i) @@ -21522,7 +21516,7 @@ class serializer for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i) { put_indent(new_indent); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\": "); dump_internal(i->second, true, ensure_ascii, indent_step, new_indent, depth + 1); @@ -21533,7 +21527,7 @@ class serializer JSON_ASSERT(i != val.m_data.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend()); put_indent(new_indent); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\": "); dump_internal(i->second, true, ensure_ascii, indent_step, new_indent, depth + 1); @@ -21550,7 +21544,7 @@ class serializer auto i = val.m_data.m_value.object->cbegin(); for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i) { - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\":"); dump_internal(i->second, false, ensure_ascii, indent_step, current_indent, depth + 1); @@ -21560,7 +21554,7 @@ class serializer // last element JSON_ASSERT(i != val.m_data.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend()); - put_char('\"'); + put_char('"'); dump_escaped(i->first, ensure_ascii); put_literal("\":"); dump_internal(i->second, false, ensure_ascii, indent_step, current_indent, depth + 1); @@ -21634,9 +21628,9 @@ class serializer case value_t::string: { - put_char('\"'); + put_char('"'); dump_escaped(*val.m_data.m_value.string, ensure_ascii); - put_char('\"'); + put_char('"'); return; } @@ -21827,7 +21821,7 @@ class serializer put_indent(frame.child_indent); } - put_char('\"'); + put_char('"'); dump_escaped(frame.object_it->first, ensure_ascii); if (pretty_print) @@ -21985,9 +21979,9 @@ class serializer case value_t::string: { - put_char('\"'); + put_char('"'); dump_escaped(*val.m_data.m_value.string, ensure_ascii); - put_char('\"'); + put_char('"'); return; } @@ -22269,7 +22263,7 @@ class serializer case 0x22: // quotation mark { string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\"'; + string_buffer[bytes++] = '"'; break; }