diff --git a/include/nlohmann/detail/view/builder.hpp b/include/nlohmann/detail/view/builder.hpp index 938d6d73b..283cae075 100644 --- a/include/nlohmann/detail/view/builder.hpp +++ b/include/nlohmann/detail/view/builder.hpp @@ -1174,8 +1174,9 @@ indent_done: { ++p; } - else if (NLOHMANN_VIEW_LIKELY(cur() >= '1' && cur() <= '9')) + else if (!negative || NLOHMANN_VIEW_LIKELY(cur() >= '1' && cur() <= '9')) { + // (without a sign, the dispatch saw a digit) p = skip_digits(p + 1, e); } else diff --git a/include/nlohmann/detail/view/compare.hpp b/include/nlohmann/detail/view/compare.hpp index 239871f01..2d2c238b9 100644 --- a/include/nlohmann/detail/view/compare.hpp +++ b/include/nlohmann/detail/view/compare.hpp @@ -397,9 +397,9 @@ class view_side return m_view.size(); } - string_view_t string() const + string_view_t string() const noexcept { - return m_view.get_string(); + return {m_view.m_doc->str(*m_view.m_node), m_view.m_node->len}; } bool boolean() const noexcept @@ -522,9 +522,9 @@ class json_side return m_json->size(); } - string_view_t string() const + string_view_t string() const noexcept { - const auto& s = m_json->template get_ref(); + const auto& s = *m_json->template get_ptr(); return string_view_t(s.data(), s.size()); } diff --git a/include/nlohmann/detail/view/edit_storage.hpp b/include/nlohmann/detail/view/edit_storage.hpp index 10898f99f..34b804c46 100644 --- a/include/nlohmann/detail/view/edit_storage.hpp +++ b/include/nlohmann/detail/view/edit_storage.hpp @@ -158,7 +158,7 @@ inline void set_moved(document_data& d, node* n, node* seq, std::size_t cap) e.moved_cap[n->off] = cap; return; } - reserve_moved(d); + // every caller has called reserve_moved() (see above), so neither push_back() can throw e.moved.push_back(seq); e.moved_cap.push_back(cap); n->off = static_cast(e.moved.size() - 1); diff --git a/include/nlohmann/detail/view/errors.hpp b/include/nlohmann/detail/view/errors.hpp index de35d6a51..3c97cef5c 100644 --- a/include/nlohmann/detail/view/errors.hpp +++ b/include/nlohmann/detail/view/errors.hpp @@ -185,10 +185,6 @@ void value_range(const document_data& d, const node* n, std::size_t& start, std: end = p.end; return; } - if ((n->flags & node_flags::is_new) != 0 || n->off >= d.size) - { - return; - } // the open brackets: n, then the last element as long as it is a non-empty container std::size_t closing = 0; std::size_t pos = std::string::npos; diff --git a/include/nlohmann/detail/view/image.hpp b/include/nlohmann/detail/view/image.hpp index 9e57082de..e6680730f 100644 --- a/include/nlohmann/detail/view/image.hpp +++ b/include/nlohmann/detail/view/image.hpp @@ -787,10 +787,6 @@ inline void load_image(document_data& d, const std::uint8_t* image, std::size_t d.edits.reset(); d.base[2] = nullptr; d.owned.clear(); - if (d.owned_image.empty() || image != d.owned_image.data()) - { - d.owned_image.clear(); - } d.arena.clear(); d.indexes.clear(); d.index_slots.clear(); diff --git a/include/nlohmann/detail/view/serializer.hpp b/include/nlohmann/detail/view/serializer.hpp index 44e5a2861..deccec8e4 100644 --- a/include/nlohmann/detail/view/serializer.hpp +++ b/include/nlohmann/detail/view/serializer.hpp @@ -646,7 +646,7 @@ class view_serializer { invalid_utf8(s, n.len); // (the scan stopped at ill-formed UTF-8) } - write_codepoint(s[i], s + i, 1); // a quote, a backslash, or a control character + write_escaped(s[i]); // a quote, a backslash, or a control character ++i; } m_out.put('"'); @@ -1494,8 +1494,9 @@ class view_serializer static_cast(dumped); } // LCOV_EXCL_LINE (dump() throws: the callers pass only ill-formed UTF-8) - template - void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len) + /// write the escape sequence of a quote, a backslash or a control + /// character (the only bytes a run of plain output stops at) + void write_escaped(std::uint32_t codepoint) { switch (codepoint) { @@ -1523,12 +1524,7 @@ class view_serializer default: break; } - if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F)) - { - write_u_escape(codepoint); // (a single byte: the only caller passes s[i]) - return; - } - m_out.put(reinterpret_cast(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs) + write_u_escape(codepoint); // (a control character) } void write_u_escape(std::uint32_t u) diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp index bf64662e2..ea04acdbe 100644 --- a/single_include/nlohmann/json_view.hpp +++ b/single_include/nlohmann/json_view.hpp @@ -2479,8 +2479,9 @@ indent_done: { ++p; } - else if (NLOHMANN_VIEW_LIKELY(cur() >= '1' && cur() <= '9')) + else if (!negative || NLOHMANN_VIEW_LIKELY(cur() >= '1' && cur() <= '9')) { + // (without a sign, the dispatch saw a digit) p = skip_digits(p + 1, e); } else @@ -3549,9 +3550,9 @@ class view_side return m_view.size(); } - string_view_t string() const + string_view_t string() const noexcept { - return m_view.get_string(); + return {m_view.m_doc->str(*m_view.m_node), m_view.m_node->len}; } bool boolean() const noexcept @@ -3674,9 +3675,9 @@ class json_side return m_json->size(); } - string_view_t string() const + string_view_t string() const noexcept { - const auto& s = m_json->template get_ref(); + const auto& s = *m_json->template get_ptr(); return string_view_t(s.data(), s.size()); } @@ -5013,10 +5014,6 @@ void value_range(const document_data& d, const node* n, std::size_t& start, std: end = p.end; return; } - if ((n->flags & node_flags::is_new) != 0 || n->off >= d.size) - { - return; - } // the open brackets: n, then the last element as long as it is a non-empty container std::size_t closing = 0; std::size_t pos = std::string::npos; @@ -5475,7 +5472,7 @@ inline void set_moved(document_data& d, node* n, node* seq, std::size_t cap) e.moved_cap[n->off] = cap; return; } - reserve_moved(d); + // every caller has called reserve_moved() (see above), so neither push_back() can throw e.moved.push_back(seq); e.moved_cap.push_back(cap); n->off = static_cast(e.moved.size() - 1); @@ -7779,10 +7776,6 @@ inline void load_image(document_data& d, const std::uint8_t* image, std::size_t d.edits.reset(); d.base[2] = nullptr; d.owned.clear(); - if (d.owned_image.empty() || image != d.owned_image.data()) - { - d.owned_image.clear(); - } d.arena.clear(); d.indexes.clear(); d.index_slots.clear(); @@ -9097,7 +9090,7 @@ class view_serializer { invalid_utf8(s, n.len); // (the scan stopped at ill-formed UTF-8) } - write_codepoint(s[i], s + i, 1); // a quote, a backslash, or a control character + write_escaped(s[i]); // a quote, a backslash, or a control character ++i; } m_out.put('"'); @@ -9945,8 +9938,9 @@ class view_serializer static_cast(dumped); } // LCOV_EXCL_LINE (dump() throws: the callers pass only ill-formed UTF-8) - template - void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len) + /// write the escape sequence of a quote, a backslash or a control + /// character (the only bytes a run of plain output stops at) + void write_escaped(std::uint32_t codepoint) { switch (codepoint) { @@ -9974,12 +9968,7 @@ class view_serializer default: break; } - if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F)) - { - write_u_escape(codepoint); // (a single byte: the only caller passes s[i]) - return; - } - m_out.put(reinterpret_cast(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs) + write_u_escape(codepoint); // (a control character) } void write_u_escape(std::uint32_t u)