mirror of
https://github.com/nlohmann/json.git
synced 2026-07-23 19:04:54 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3296a3ad8c | ||
|
|
3565f40229 |
@@ -15,6 +15,14 @@ guidance.
|
|||||||
|
|
||||||
For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.
|
For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.
|
||||||
|
|
||||||
|
## Unofficial packages
|
||||||
|
|
||||||
|
This project does not publish an official npm package. The npm package
|
||||||
|
[`nlohmann-json`](https://www.npmjs.com/package/nlohmann-json) (or similarly named packages) is not maintained or
|
||||||
|
endorsed by this project. See the
|
||||||
|
[package managers documentation](https://json.nlohmann.me/integration/package_managers/#npm) for supported
|
||||||
|
integration options.
|
||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|
||||||
- Explore security-related topics and contribute to tools and projects through
|
- Explore security-related topics and contribute to tools and projects through
|
||||||
|
|||||||
@@ -930,6 +930,12 @@ If you are using [CocoaPods](https://cocoapods.org), you can use the library by
|
|||||||
to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues
|
to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues
|
||||||
[here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
|
[here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
|
||||||
|
|
||||||
|
## npm
|
||||||
|
|
||||||
|
This project does not publish an official [npm](https://www.npmjs.com) package. The npm package
|
||||||
|
[`nlohmann-json`](https://www.npmjs.com/package/nlohmann-json) (or similarly named packages) is not maintained or
|
||||||
|
endorsed by this project. Use one of the package managers listed above, or integrate the single header directly.
|
||||||
|
|
||||||
## ESP-IDF and PlatformIO
|
## ESP-IDF and PlatformIO
|
||||||
|
|
||||||
There is no official package published to the [ESP-IDF Component Registry](https://components.espressif.com) or the
|
There is no official package published to the [ESP-IDF Component Registry](https://components.espressif.com) or the
|
||||||
|
|||||||
@@ -1846,6 +1846,29 @@ class binary_reader
|
|||||||
return get_ubjson_value(get_char ? get_ignore_noop() : current);
|
return get_ubjson_value(get_char ? get_ignore_noop() : current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief reject a negative UBJSON/BJData string length
|
||||||
|
|
||||||
|
String and key lengths are written with signed integer markers (i, I, l,
|
||||||
|
L). A negative value is malformed; without this check get_string() would
|
||||||
|
silently treat it as an empty string and leave the following bytes to be
|
||||||
|
misread as the next value. This mirrors the non-negative check the
|
||||||
|
optimized-container count path already performs in get_ubjson_size_value.
|
||||||
|
|
||||||
|
@param[in] len the string length read from the input
|
||||||
|
@return whether the length is valid (non-negative)
|
||||||
|
*/
|
||||||
|
template<typename NumberType>
|
||||||
|
bool check_ubjson_string_length(const NumberType len)
|
||||||
|
{
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||||
|
{
|
||||||
|
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
||||||
|
exception_message(input_format, "string length must not be negative", "string"), nullptr));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief reads a UBJSON string
|
@brief reads a UBJSON string
|
||||||
|
|
||||||
@@ -1883,25 +1906,25 @@ class binary_reader
|
|||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
std::int8_t len{};
|
std::int8_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
{
|
{
|
||||||
std::int16_t len{};
|
std::int16_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
{
|
||||||
std::int32_t len{};
|
std::int32_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
std::int64_t len{};
|
std::int64_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
|
|||||||
@@ -12395,6 +12395,29 @@ class binary_reader
|
|||||||
return get_ubjson_value(get_char ? get_ignore_noop() : current);
|
return get_ubjson_value(get_char ? get_ignore_noop() : current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief reject a negative UBJSON/BJData string length
|
||||||
|
|
||||||
|
String and key lengths are written with signed integer markers (i, I, l,
|
||||||
|
L). A negative value is malformed; without this check get_string() would
|
||||||
|
silently treat it as an empty string and leave the following bytes to be
|
||||||
|
misread as the next value. This mirrors the non-negative check the
|
||||||
|
optimized-container count path already performs in get_ubjson_size_value.
|
||||||
|
|
||||||
|
@param[in] len the string length read from the input
|
||||||
|
@return whether the length is valid (non-negative)
|
||||||
|
*/
|
||||||
|
template<typename NumberType>
|
||||||
|
bool check_ubjson_string_length(const NumberType len)
|
||||||
|
{
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||||
|
{
|
||||||
|
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
||||||
|
exception_message(input_format, "string length must not be negative", "string"), nullptr));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief reads a UBJSON string
|
@brief reads a UBJSON string
|
||||||
|
|
||||||
@@ -12432,25 +12455,25 @@ class binary_reader
|
|||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
std::int8_t len{};
|
std::int8_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
{
|
{
|
||||||
std::int16_t len{};
|
std::int16_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
{
|
||||||
std::int32_t len{};
|
std::int32_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
std::int64_t len{};
|
std::int64_t len{};
|
||||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
|
|||||||
@@ -2721,6 +2721,19 @@ TEST_CASE("BJData")
|
|||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing BJData string: expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x31", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing BJData string: expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x31", json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("negative length")
|
||||||
|
{
|
||||||
|
json _;
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vi = {'S', 'i', 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vi), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing BJData string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_bjdata(vi, true, false).is_discarded());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vl = {'S', 'l', 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vl), "[json.exception.parse_error.113] parse error at byte 6: syntax error while parsing BJData string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_bjdata(vl, true, false).is_discarded());
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("parse bjdata markers in ubjson")
|
SECTION("parse bjdata markers in ubjson")
|
||||||
{
|
{
|
||||||
// create a single-character string for all number types
|
// create a single-character string for all number types
|
||||||
|
|||||||
@@ -1862,6 +1862,31 @@ TEST_CASE("UBJSON")
|
|||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31", json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("negative length")
|
||||||
|
{
|
||||||
|
json _;
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vi = {'S', 'i', 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vi), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_ubjson(vi, true, false).is_discarded());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vI = {'S', 'I', 0xFF, 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vI), "[json.exception.parse_error.113] parse error at byte 4: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_ubjson(vI, true, false).is_discarded());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vl = {'S', 'l', 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vl), "[json.exception.parse_error.113] parse error at byte 6: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_ubjson(vl, true, false).is_discarded());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const vL = {'S', 'L', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vL), "[json.exception.parse_error.113] parse error at byte 10: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||||
|
CHECK(json::from_ubjson(vL, true, false).is_discarded());
|
||||||
|
|
||||||
|
// a length of zero remains valid and yields an empty string
|
||||||
|
std::vector<uint8_t> const v0 = {'S', 'i', 0};
|
||||||
|
CHECK(json::from_ubjson(v0) == json(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("array")
|
SECTION("array")
|
||||||
|
|||||||
Reference in New Issue
Block a user