parent
d7029c37aa
commit
cf9bf2d913
3 changed files with 61 additions and 14 deletions
11
src/json.hpp
11
src/json.hpp
|
@ -7135,13 +7135,10 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
|
static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
|
||||||
{
|
{
|
||||||
// make sure reading 1 byte is safe
|
|
||||||
check_length(v.size(), 1, idx);
|
|
||||||
|
|
||||||
// store and increment index
|
// store and increment index
|
||||||
const size_t current_idx = idx++;
|
const size_t current_idx = idx++;
|
||||||
|
|
||||||
switch (v[current_idx])
|
switch (v.at(current_idx))
|
||||||
{
|
{
|
||||||
// Integer 0x00..0x17 (0..23)
|
// Integer 0x00..0x17 (0..23)
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
@ -7322,7 +7319,7 @@ class basic_json
|
||||||
case 0x7f: // UTF-8 string (indefinite length)
|
case 0x7f: // UTF-8 string (indefinite length)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
string_t s = from_cbor_internal(v, idx);
|
string_t s = from_cbor_internal(v, idx);
|
||||||
result += s;
|
result += s;
|
||||||
|
@ -7418,7 +7415,7 @@ class basic_json
|
||||||
case 0x9f: // array (indefinite length)
|
case 0x9f: // array (indefinite length)
|
||||||
{
|
{
|
||||||
basic_json result = value_t::array;
|
basic_json result = value_t::array;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
result.push_back(from_cbor_internal(v, idx));
|
result.push_back(from_cbor_internal(v, idx));
|
||||||
}
|
}
|
||||||
|
@ -7518,7 +7515,7 @@ class basic_json
|
||||||
case 0xbf: // map (indefinite length)
|
case 0xbf: // map (indefinite length)
|
||||||
{
|
{
|
||||||
basic_json result = value_t::object;
|
basic_json result = value_t::object;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
|
|
|
@ -7135,13 +7135,10 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
|
static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
|
||||||
{
|
{
|
||||||
// make sure reading 1 byte is safe
|
|
||||||
check_length(v.size(), 1, idx);
|
|
||||||
|
|
||||||
// store and increment index
|
// store and increment index
|
||||||
const size_t current_idx = idx++;
|
const size_t current_idx = idx++;
|
||||||
|
|
||||||
switch (v[current_idx])
|
switch (v.at(current_idx))
|
||||||
{
|
{
|
||||||
// Integer 0x00..0x17 (0..23)
|
// Integer 0x00..0x17 (0..23)
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
@ -7322,7 +7319,7 @@ class basic_json
|
||||||
case 0x7f: // UTF-8 string (indefinite length)
|
case 0x7f: // UTF-8 string (indefinite length)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
string_t s = from_cbor_internal(v, idx);
|
string_t s = from_cbor_internal(v, idx);
|
||||||
result += s;
|
result += s;
|
||||||
|
@ -7418,7 +7415,7 @@ class basic_json
|
||||||
case 0x9f: // array (indefinite length)
|
case 0x9f: // array (indefinite length)
|
||||||
{
|
{
|
||||||
basic_json result = value_t::array;
|
basic_json result = value_t::array;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
result.push_back(from_cbor_internal(v, idx));
|
result.push_back(from_cbor_internal(v, idx));
|
||||||
}
|
}
|
||||||
|
@ -7518,7 +7515,7 @@ class basic_json
|
||||||
case 0xbf: // map (indefinite length)
|
case 0xbf: // map (indefinite length)
|
||||||
{
|
{
|
||||||
basic_json result = value_t::object;
|
basic_json result = value_t::object;
|
||||||
while (v[idx] != 0xff)
|
while (v.at(idx) != 0xff)
|
||||||
{
|
{
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
|
|
|
@ -610,4 +610,57 @@ TEST_CASE("regression tests")
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||||
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range);
|
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
|
||||||
|
{
|
||||||
|
// original test case: empty UTF-8 string (indefinite length)
|
||||||
|
std::vector<uint8_t> vec1 {0x7f};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: empty array (indefinite length)
|
||||||
|
std::vector<uint8_t> vec2 {0x9f};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: empty map (indefinite length)
|
||||||
|
std::vector<uint8_t> vec3 {0xbf};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
||||||
|
{
|
||||||
|
// original test case
|
||||||
|
std::vector<uint8_t> vec
|
||||||
|
{
|
||||||
|
0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
|
||||||
|
0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
|
||||||
|
0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
|
||||||
|
0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,
|
||||||
|
0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
|
||||||
|
};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: nonempty UTF-8 string (indefinite length)
|
||||||
|
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: nonempty array (indefinite length)
|
||||||
|
std::vector<uint8_t> vec2 {0x9f, 0x01};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: nonempty map (indefinite length)
|
||||||
|
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue