Merge branch 'json-view/22-view-dump-fast' into json-view/15-view-bench

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-10 22:00:50 +02:00
commit 711c40dd96
6 files changed
+52 -15

No files matched your search

+7 -3
View File
@@ -337,14 +337,17 @@ def is_remote(url) -> bool:
def download(url, docs) -> str: def download(url, docs) -> str:
"""Download url into assets/external and return the path relative to docs.""" """Download url into assets/external and return the path relative to docs."""
u = urllib.parse.urlparse(url if not url.startswith('//') else 'https:' + url) u = urllib.parse.urlparse(url if not url.startswith('//') else 'https:' + url)
if u.scheme.lower() not in ('http', 'https'):
raise ValueError(f'not an http(s) URL: {url}')
req = urllib.request.Request(u.geturl(), headers={'User-Agent': USER_AGENT}) req = urllib.request.Request(u.geturl(), headers={'User-Agent': USER_AGENT})
with urllib.request.urlopen(req, timeout=20) as r: # (the scheme is checked above)
with urllib.request.urlopen(req, timeout=20) as r: # nosec B310
data = r.read() data = r.read()
ctype = r.headers.get_content_type() ctype = r.headers.get_content_type()
path = urllib.parse.unquote(u.path).lstrip('/') path = urllib.parse.unquote(u.path).lstrip('/')
ext = os.path.splitext(path)[1] ext = os.path.splitext(path)[1]
if u.query or not ext or path.endswith('/'): if u.query or not ext or path.endswith('/'):
digest = hashlib.sha1(url.encode()).hexdigest()[:12] digest = hashlib.sha1(url.encode(), usedforsecurity=False).hexdigest()[:12]
path = os.path.join(os.path.dirname(path), digest + CONTENT_TYPE_EXT.get(ctype, ext or '.bin')) path = os.path.join(os.path.dirname(path), digest + CONTENT_TYPE_EXT.get(ctype, ext or '.bin'))
rel = os.path.normpath(os.path.join('assets', 'external', u.hostname, path)) rel = os.path.normpath(os.path.join('assets', 'external', u.hostname, path))
out = os.path.join(docs, rel) out = os.path.join(docs, rel)
@@ -385,7 +388,8 @@ def localize_images(docs) -> None:
def load_mkdocs_yml() -> dict: def load_mkdocs_yml() -> dict:
"""Load mkdocs.yml, ignoring tags like !ENV and !!python/name.""" """Load mkdocs.yml, ignoring tags like !ENV and !!python/name."""
with open(MKDOCS_YML, encoding='utf-8') as f: with open(MKDOCS_YML, encoding='utf-8') as f:
return yaml.load(f, Loader=Loader) # (Loader is a yaml.SafeLoader)
return yaml.load(f, Loader=Loader) # nosec B506
def localize_site_urls(docs, site_url) -> None: def localize_site_urls(docs, site_url) -> None:
+1 -1
View File
@@ -66,7 +66,7 @@ template<typename BasicJsonType>
{ {
if (f.code == error_code::input_too_large) if (f.code == error_code::input_too_large)
{ {
// (the limit is detail::view::max_input_size: 4 GiB minus 16 bytes) // (the limit is detail::view::max_input_size(): 4 GiB minus 16 bytes)
NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr)); NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr));
} }
const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas); const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas);
+4 -1
View File
@@ -32,7 +32,10 @@ static_assert(static_cast<std::uint8_t>(value_t::null) == 0 && static_cast<std::
/// The largest input a document accepts, in bytes. Offsets and node counts are /// The largest input a document accepts, in bytes. Offsets and node counts are
/// 32 bits wide; the limit keeps 16 bytes (the width of the scanner's steps) /// 32 bits wide; the limit keeps 16 bytes (the width of the scanner's steps)
/// below 2^32, so that a position one step past the end of the text fits. /// below 2^32, so that a position one step past the end of the text fits.
static constexpr std::size_t max_input_size = 0xFFFFFFEFu; constexpr std::size_t max_input_size() noexcept
{
return 0xFFFFFFEFu;
}
/// node flags /// node flags
struct node_flags struct node_flags
+17 -3
View File
@@ -27,7 +27,8 @@
#define INCLUDE_NLOHMANN_JSON_VIEW_HPP_ #define INCLUDE_NLOHMANN_JSON_VIEW_HPP_
#include <algorithm> // all_of, min #include <algorithm> // all_of, min
#include <cstddef> // size_t #include <array> // array
#include <cstddef> // nullptr_t, size_t // IWYU pragma: keep
#include <cstdint> // uint8_t, uint32_t #include <cstdint> // uint8_t, uint32_t
#include <cstring> // memcpy, strlen #include <cstring> // memcpy, strlen
#include <iterator> // distance, input_iterator_tag, iterator_traits #include <iterator> // distance, input_iterator_tag, iterator_traits
@@ -45,6 +46,20 @@
#include <nlohmann/json.hpp> // IWYU pragma: export #include <nlohmann/json.hpp> // IWYU pragma: export
// json.hpp provides the library's types and macros used below (it includes
// the headers that define them); json_view.hpp must not include them again,
// because the amalgamated json_view.hpp only includes json.hpp
// IWYU pragma: no_include <version>
// IWYU pragma: no_include "nlohmann/detail/abi_config.hpp"
// IWYU pragma: no_include "nlohmann/detail/abi_macros.hpp"
// IWYU pragma: no_include "nlohmann/detail/input/input_adapters.hpp"
// IWYU pragma: no_include "nlohmann/detail/json_pointer.hpp"
// IWYU pragma: no_include "nlohmann/detail/meta/cpp_future.hpp"
// IWYU pragma: no_include "nlohmann/detail/string_concat.hpp"
// IWYU pragma: no_include "nlohmann/detail/value_t.hpp"
// IWYU pragma: no_include "nlohmann/json.hpp"
// IWYU pragma: no_include "nlohmann/json_fwd.hpp"
// the view builds on internals of the library: both must be the same version // the view builds on internals of the library: both must be the same version
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
#error "json_view.hpp requires json.hpp of the same version (3.12.0)" #error "json_view.hpp requires json.hpp of the same version (3.12.0)"
@@ -54,7 +69,6 @@
#include <nlohmann/detail/view/compare.hpp> #include <nlohmann/detail/view/compare.hpp>
#include <nlohmann/detail/view/document_data.hpp> #include <nlohmann/detail/view/document_data.hpp>
#include <nlohmann/detail/view/edit.hpp> #include <nlohmann/detail/view/edit.hpp>
#include <nlohmann/detail/view/edit_storage.hpp>
#include <nlohmann/detail/view/errors.hpp> #include <nlohmann/detail/view/errors.hpp>
#include <nlohmann/detail/view/image.hpp> #include <nlohmann/detail/view/image.hpp>
#include <nlohmann/detail/view/input.hpp> #include <nlohmann/detail/view/input.hpp>
@@ -1341,7 +1355,7 @@ class basic_json_document
d.discarded = true; d.discarded = true;
detail::view::parse_failure failure; detail::view::parse_failure failure;
bool ok = false; bool ok = false;
if (NLOHMANN_VIEW_UNLIKELY(size > detail::view::max_input_size)) if (NLOHMANN_VIEW_UNLIKELY(size > detail::view::max_input_size()))
{ {
failure.code = detail::view::error_code::input_too_large; failure.code = detail::view::error_code::input_too_large;
} }
+22 -6
View File
@@ -27,7 +27,8 @@
#define INCLUDE_NLOHMANN_JSON_VIEW_HPP_ #define INCLUDE_NLOHMANN_JSON_VIEW_HPP_
#include <algorithm> // all_of, min #include <algorithm> // all_of, min
#include <cstddef> // size_t #include <array> // array
#include <cstddef> // nullptr_t, size_t // IWYU pragma: keep
#include <cstdint> // uint8_t, uint32_t #include <cstdint> // uint8_t, uint32_t
#include <cstring> // memcpy, strlen #include <cstring> // memcpy, strlen
#include <iterator> // distance, input_iterator_tag, iterator_traits #include <iterator> // distance, input_iterator_tag, iterator_traits
@@ -45,6 +46,20 @@
#include <nlohmann/json.hpp> // IWYU pragma: export #include <nlohmann/json.hpp> // IWYU pragma: export
// json.hpp provides the library's types and macros used below (it includes
// the headers that define them); json_view.hpp must not include them again,
// because the amalgamated json_view.hpp only includes json.hpp
// IWYU pragma: no_include <version>
// IWYU pragma: no_include "nlohmann/detail/abi_config.hpp"
// IWYU pragma: no_include "nlohmann/detail/abi_macros.hpp"
// IWYU pragma: no_include "nlohmann/detail/input/input_adapters.hpp"
// IWYU pragma: no_include "nlohmann/detail/json_pointer.hpp"
// IWYU pragma: no_include "nlohmann/detail/meta/cpp_future.hpp"
// IWYU pragma: no_include "nlohmann/detail/string_concat.hpp"
// IWYU pragma: no_include "nlohmann/detail/value_t.hpp"
// IWYU pragma: no_include "nlohmann/json.hpp"
// IWYU pragma: no_include "nlohmann/json_fwd.hpp"
// the view builds on internals of the library: both must be the same version // the view builds on internals of the library: both must be the same version
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
#error "json_view.hpp requires json.hpp of the same version (3.12.0)" #error "json_view.hpp requires json.hpp of the same version (3.12.0)"
@@ -208,7 +223,10 @@ static_assert(static_cast<std::uint8_t>(value_t::null) == 0 && static_cast<std::
/// The largest input a document accepts, in bytes. Offsets and node counts are /// The largest input a document accepts, in bytes. Offsets and node counts are
/// 32 bits wide; the limit keeps 16 bytes (the width of the scanner's steps) /// 32 bits wide; the limit keeps 16 bytes (the width of the scanner's steps)
/// below 2^32, so that a position one step past the end of the text fits. /// below 2^32, so that a position one step past the end of the text fits.
static constexpr std::size_t max_input_size = 0xFFFFFFEFu; constexpr std::size_t max_input_size() noexcept
{
return 0xFFFFFFEFu;
}
/// node flags /// node flags
struct node_flags struct node_flags
@@ -2640,7 +2658,7 @@ template<typename BasicJsonType>
{ {
if (f.code == error_code::input_too_large) if (f.code == error_code::input_too_large)
{ {
// (the limit is detail::view::max_input_size: 4 GiB minus 16 bytes) // (the limit is detail::view::max_input_size(): 4 GiB minus 16 bytes)
NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr)); NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr));
} }
const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas); const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas);
@@ -4122,8 +4140,6 @@ class editor
} // namespace detail } // namespace detail
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END
// #include <nlohmann/detail/view/edit_storage.hpp>
// #include <nlohmann/detail/view/errors.hpp> // #include <nlohmann/detail/view/errors.hpp>
// #include <nlohmann/detail/view/image.hpp> // #include <nlohmann/detail/view/image.hpp>
@@ -8276,7 +8292,7 @@ class basic_json_document
d.discarded = true; d.discarded = true;
detail::view::parse_failure failure; detail::view::parse_failure failure;
bool ok = false; bool ok = false;
if (NLOHMANN_VIEW_UNLIKELY(size > detail::view::max_input_size)) if (NLOHMANN_VIEW_UNLIKELY(size > detail::view::max_input_size()))
{ {
failure.code = detail::view::error_code::input_too_large; failure.code = detail::view::error_code::input_too_large;
} }
+1 -1
View File
@@ -417,7 +417,7 @@ TEST_CASE("json_view")
{ {
// 32-bit offsets: the limit is 4 GiB minus 16 bytes (a margin below 2^32), // 32-bit offsets: the limit is 4 GiB minus 16 bytes (a margin below 2^32),
// which is what the exception message and the documentation say // which is what the exception message and the documentation say
const std::size_t limit = nlohmann::detail::view::max_input_size; const std::size_t limit = nlohmann::detail::view::max_input_size();
CHECK(limit == std::size_t{4294967279u}); CHECK(limit == std::size_t{4294967279u});
const oversized_input input{limit + 1}; const oversized_input input{limit + 1};