🚑 fix for #416
This commit is contained in:
parent
767637877b
commit
cdd3b5a68c
3 changed files with 36 additions and 18 deletions
12
src/json.hpp
12
src/json.hpp
|
@ -6938,11 +6938,10 @@ class basic_json
|
||||||
case 0xca: // float 32
|
case 0xca: // float 32
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
check_length(v.size(), sizeof(float), 1);
|
|
||||||
float res;
|
float res;
|
||||||
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(float); // skip content bytes
|
idx += sizeof(float); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -6951,11 +6950,10 @@ class basic_json
|
||||||
case 0xcb: // float 64
|
case 0xcb: // float 64
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
check_length(v.size(), sizeof(double), 1);
|
|
||||||
double res;
|
double res;
|
||||||
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(double); // skip content bytes
|
idx += sizeof(double); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -7549,11 +7547,10 @@ class basic_json
|
||||||
case 0xfa: // Single-Precision Float (four-byte IEEE 754)
|
case 0xfa: // Single-Precision Float (four-byte IEEE 754)
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the float variable
|
// copy bytes in reverse order into the float variable
|
||||||
check_length(v.size(), sizeof(float), 1);
|
|
||||||
float res;
|
float res;
|
||||||
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(float); // skip content bytes
|
idx += sizeof(float); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -7561,12 +7558,11 @@ class basic_json
|
||||||
|
|
||||||
case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
|
case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
|
||||||
{
|
{
|
||||||
check_length(v.size(), sizeof(double), 1);
|
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
double res;
|
double res;
|
||||||
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(double); // skip content bytes
|
idx += sizeof(double); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -6938,11 +6938,10 @@ class basic_json
|
||||||
case 0xca: // float 32
|
case 0xca: // float 32
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
check_length(v.size(), sizeof(float), 1);
|
|
||||||
float res;
|
float res;
|
||||||
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(float); // skip content bytes
|
idx += sizeof(float); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -6951,11 +6950,10 @@ class basic_json
|
||||||
case 0xcb: // float 64
|
case 0xcb: // float 64
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
check_length(v.size(), sizeof(double), 1);
|
|
||||||
double res;
|
double res;
|
||||||
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(double); // skip content bytes
|
idx += sizeof(double); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -7517,7 +7515,6 @@ class basic_json
|
||||||
|
|
||||||
case 0xf9: // Half-Precision Float (two-byte IEEE 754)
|
case 0xf9: // Half-Precision Float (two-byte IEEE 754)
|
||||||
{
|
{
|
||||||
check_length(v.size(), 2, 1);
|
|
||||||
idx += 2; // skip two content bytes
|
idx += 2; // skip two content bytes
|
||||||
|
|
||||||
// code from RFC 7049, Appendix D, Figure 3:
|
// code from RFC 7049, Appendix D, Figure 3:
|
||||||
|
@ -7527,7 +7524,7 @@ class basic_json
|
||||||
// include at least decoding support for them even without such
|
// include at least decoding support for them even without such
|
||||||
// support. An example of a small decoder for half-precision
|
// support. An example of a small decoder for half-precision
|
||||||
// floating-point numbers in the C language is shown in Fig. 3.
|
// floating-point numbers in the C language is shown in Fig. 3.
|
||||||
const int half = (v[current_idx + 1] << 8) + v[current_idx + 2];
|
const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
|
||||||
const int exp = (half >> 10) & 0x1f;
|
const int exp = (half >> 10) & 0x1f;
|
||||||
const int mant = half & 0x3ff;
|
const int mant = half & 0x3ff;
|
||||||
double val;
|
double val;
|
||||||
|
@ -7549,11 +7546,10 @@ class basic_json
|
||||||
case 0xfa: // Single-Precision Float (four-byte IEEE 754)
|
case 0xfa: // Single-Precision Float (four-byte IEEE 754)
|
||||||
{
|
{
|
||||||
// copy bytes in reverse order into the float variable
|
// copy bytes in reverse order into the float variable
|
||||||
check_length(v.size(), sizeof(float), 1);
|
|
||||||
float res;
|
float res;
|
||||||
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
for (size_t byte = 0; byte < sizeof(float); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(float); // skip content bytes
|
idx += sizeof(float); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
@ -7561,12 +7557,11 @@ class basic_json
|
||||||
|
|
||||||
case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
|
case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
|
||||||
{
|
{
|
||||||
check_length(v.size(), sizeof(double), 1);
|
|
||||||
// copy bytes in reverse order into the double variable
|
// copy bytes in reverse order into the double variable
|
||||||
double res;
|
double res;
|
||||||
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
for (size_t byte = 0; byte < sizeof(double); ++byte)
|
||||||
{
|
{
|
||||||
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
|
reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
|
||||||
}
|
}
|
||||||
idx += sizeof(double); // skip content bytes
|
idx += sizeof(double); // skip content bytes
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -663,4 +663,31 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
|
||||||
|
{
|
||||||
|
// original test case
|
||||||
|
std::vector<uint8_t> vec1
|
||||||
|
{
|
||||||
|
0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
|
||||||
|
0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
||||||
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
|
||||||
|
0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
||||||
|
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
|
||||||
|
};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||||
|
|
||||||
|
// related test case: double-precision
|
||||||
|
std::vector<uint8_t> vec2
|
||||||
|
{
|
||||||
|
0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
|
||||||
|
0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
||||||
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
|
||||||
|
0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
||||||
|
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
|
||||||
|
};
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue