mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Handle negative numbers in QIntC::range_check (fuzz issue 26994)
This commit is contained in:
parent
4b4b31bf23
commit
9d64481571
@ -1,3 +1,8 @@
|
||||
2020-11-21 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Fix QIntC::range_check to handle negative numbers properly (fuzz
|
||||
issue 26994).
|
||||
|
||||
2020-11-11 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Treat a direct page object as a runtime error rather than a
|
||||
|
BIN
fuzz/qpdf_extra/26994.fuzz
Normal file
BIN
fuzz/qpdf_extra/26994.fuzz
Normal file
Binary file not shown.
@ -226,6 +226,11 @@ namespace QIntC // QIntC = qpdf Integer Conversion
|
||||
template <typename T>
|
||||
void range_check(T const& cur, T const& delta)
|
||||
{
|
||||
if ((delta > 0) != (cur > 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((delta > 0) &&
|
||||
((std::numeric_limits<T>::max() - cur) < delta))
|
||||
{
|
||||
@ -235,6 +240,15 @@ namespace QIntC // QIntC = qpdf Integer Conversion
|
||||
<< " would cause an integer overflow";
|
||||
throw std::range_error(msg.str());
|
||||
}
|
||||
else if ((delta < 0) &&
|
||||
((std::numeric_limits<T>::min() - cur) > delta))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg.imbue(std::locale::classic());
|
||||
msg << "adding " << delta << " to " << cur
|
||||
<< " would cause an integer underflow";
|
||||
throw std::range_error(msg.str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,29 @@ static void try_convert_real(
|
||||
std::cout << ((passed == exp_pass) ? " PASSED" : " FAILED") << std::endl;
|
||||
}
|
||||
|
||||
#define try_range_check(exp_pass, a, b) \
|
||||
try_range_check_real(#a " + " #b, exp_pass, a, b)
|
||||
|
||||
template <typename T>
|
||||
static void try_range_check_real(
|
||||
char const* description, bool exp_pass,
|
||||
T const& a, T const& b)
|
||||
{
|
||||
bool passed = false;
|
||||
try
|
||||
{
|
||||
QIntC::range_check(a, b);
|
||||
std::cout << description << ": okay";
|
||||
passed = true;
|
||||
}
|
||||
catch (std::range_error& e)
|
||||
{
|
||||
std::cout << description << ": " << e.what();
|
||||
passed = false;
|
||||
}
|
||||
std::cout << ((passed == exp_pass) ? " PASSED" : " FAILED") << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
uint32_t u1 = 3141592653U; // Too big for signed type
|
||||
@ -56,5 +79,22 @@ int main()
|
||||
try_convert(true, QIntC::to_uchar<char>, c2);
|
||||
try_convert(true, QIntC::to_char<char>, c2);
|
||||
|
||||
auto constexpr max_ll = std::numeric_limits<long long>::max();
|
||||
auto constexpr max_ull = std::numeric_limits<unsigned long long>::max();
|
||||
auto constexpr min_ll = std::numeric_limits<long long>::min();
|
||||
auto constexpr max_sc = std::numeric_limits<signed char>::max();
|
||||
try_range_check(true, 1, 2);
|
||||
try_range_check(true, -1, 2);
|
||||
try_range_check(true, -100, -200);
|
||||
try_range_check(true, max_ll, 0LL);
|
||||
try_range_check(false, max_ll, 1LL);
|
||||
try_range_check(true, max_ll, 0LL);
|
||||
try_range_check(false, max_ll, 1LL);
|
||||
try_range_check(true, max_ull, 0ULL);
|
||||
try_range_check(false, max_ull, 1ULL);
|
||||
try_range_check(true, min_ll, 0LL);
|
||||
try_range_check(false, min_ll, -1LL);
|
||||
try_range_check(false, max_sc, max_sc);
|
||||
try_range_check(true, '!', '#');
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,3 +13,16 @@ QIntC::to_uchar<int32_t>(i2): 81 Q PASSED
|
||||
QIntC::to_uchar<signed char>(c1): integer out of range converting ÷ from a 1-byte signed type to a 1-byte unsigned type PASSED
|
||||
QIntC::to_uchar<char>(c2): W W PASSED
|
||||
QIntC::to_char<char>(c2): W W PASSED
|
||||
1 + 2: okay PASSED
|
||||
-1 + 2: okay PASSED
|
||||
-100 + -200: okay PASSED
|
||||
max_ll + 0LL: okay PASSED
|
||||
max_ll + 1LL: adding 1 to 9223372036854775807 would cause an integer overflow PASSED
|
||||
max_ll + 0LL: okay PASSED
|
||||
max_ll + 1LL: adding 1 to 9223372036854775807 would cause an integer overflow PASSED
|
||||
max_ull + 0ULL: okay PASSED
|
||||
max_ull + 1ULL: adding 1 to 18446744073709551615 would cause an integer overflow PASSED
|
||||
min_ll + 0LL: okay PASSED
|
||||
min_ll + -1LL: adding -1 to -9223372036854775808 would cause an integer underflow PASSED
|
||||
max_sc + max_sc: adding to would cause an integer overflow PASSED
|
||||
'!' + '#': okay PASSED
|
||||
|
Loading…
Reference in New Issue
Block a user