From 41226d0a03ef3e1f832af4c5cdda1e354fa4fce0 Mon Sep 17 00:00:00 2001 From: Qianqian Fang Date: Fri, 20 May 2022 03:41:51 -0400 Subject: [PATCH] prevent ndarray dimension vector from recusive array, nlohmann/json#3500 (#3502) --- include/nlohmann/detail/input/binary_reader.hpp | 7 +++++-- single_include/nlohmann/json.hpp | 7 +++++-- tests/src/unit-bjdata.cpp | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 10f8f000fe..f2dea07c8d 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -1938,7 +1938,7 @@ class binary_reader { std::pair size_and_type; size_t dimlen = 0; - bool is_ndarray = false; + bool is_ndarray = true; if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) { @@ -1994,7 +1994,6 @@ class binary_reader */ bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0) { - is_ndarray = false; if (prefix == 0) { prefix = get_ignore_noop(); @@ -2128,6 +2127,10 @@ class binary_reader { break; } + if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimention vector can only contain integers", "size"), nullptr)); + } std::vector dim; if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim))) { diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9ddddb17ce..e793abf1e4 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -10421,7 +10421,7 @@ class binary_reader { std::pair size_and_type; size_t dimlen = 0; - bool is_ndarray = false; + bool is_ndarray = true; if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) { @@ -10477,7 +10477,6 @@ class binary_reader */ bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0) { - is_ndarray = false; if (prefix == 0) { prefix = get_ignore_noop(); @@ -10611,6 +10610,10 @@ class binary_reader { break; } + if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimention vector can only contain integers", "size"), nullptr)); + } std::vector dim; if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim))) { diff --git a/tests/src/unit-bjdata.cpp b/tests/src/unit-bjdata.cpp index e9ce1b14e0..296a8864c6 100644 --- a/tests/src/unit-bjdata.cpp +++ b/tests/src/unit-bjdata.cpp @@ -2742,6 +2742,14 @@ TEST_CASE("BJData") std::vector vh = {'[', '$', 'h', '#', '[', '$', 'i', '#', 'i', 2, 2, 3}; CHECK(json::from_bjdata(vh, true, false).is_discarded()); + + std::vector vR = {'[', '$', 'i', '#', '[', 'i', 1, '[', ']', ']', 1}; + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vR), "[json.exception.parse_error.113] parse error at byte 8: syntax error while parsing BJData size: ndarray dimention vector can only contain integers", json::parse_error&); + CHECK(json::from_bjdata(vR, true, false).is_discarded()); + + std::vector vRo = {'[', '$', 'i', '#', '[', 'i', 0, '{', '}', ']', 1}; + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vRo), "[json.exception.parse_error.113] parse error at byte 8: syntax error while parsing BJData size: expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x7B", json::parse_error&); + CHECK(json::from_bjdata(vRo, true, false).is_discarded()); } SECTION("objects")