mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 07:12:28 +00:00
Add QIntC::range_check_subtract
This commit is contained in:
parent
4a648b9a00
commit
ec09b91443
@ -1,5 +1,9 @@
|
||||
2021-11-04 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add QIntC::range_check_substract to do range checking on
|
||||
subtraction, which has different boundary conditions from
|
||||
addition.
|
||||
|
||||
* Bug fix: fix crash that could occur under certain conditions
|
||||
when using --pages with files that had form fields. Fixes #548.
|
||||
|
||||
|
@ -250,6 +250,34 @@ namespace QIntC // QIntC = qpdf Integer Conversion
|
||||
throw std::range_error(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void range_check_substract(T const& cur, T const& delta)
|
||||
{
|
||||
if ((delta >= 0) == (cur >= 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((delta > 0) &&
|
||||
((std::numeric_limits<T>::min() + delta) > cur))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg.imbue(std::locale::classic());
|
||||
msg << "subtracting " << delta << " from " << cur
|
||||
<< " would cause an integer underflow";
|
||||
throw std::range_error(msg.str());
|
||||
}
|
||||
else if ((delta < 0) &&
|
||||
((std::numeric_limits<T>::max() + delta) < cur))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg.imbue(std::locale::classic());
|
||||
msg << "subtracting " << delta << " from " << cur
|
||||
<< " would cause an integer overflow";
|
||||
throw std::range_error(msg.str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QINTC_HH
|
||||
|
@ -48,6 +48,29 @@ static void try_range_check_real(
|
||||
std::cout << ((passed == exp_pass) ? " PASSED" : " FAILED") << std::endl;
|
||||
}
|
||||
|
||||
#define try_range_check_subtract(exp_pass, a, b) \
|
||||
try_range_check_subtract_real(#a " - " #b, exp_pass, a, b)
|
||||
|
||||
template <typename T>
|
||||
static void try_range_check_subtract_real(
|
||||
char const* description, bool exp_pass,
|
||||
T const& a, T const& b)
|
||||
{
|
||||
bool passed = false;
|
||||
try
|
||||
{
|
||||
QIntC::range_check_substract(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
|
||||
@ -96,5 +119,14 @@ int main()
|
||||
try_range_check(false, min_ll, -1LL);
|
||||
try_range_check(false, max_sc, max_sc);
|
||||
try_range_check(true, '!', '#');
|
||||
try_range_check_subtract(true, 1, 2);
|
||||
try_range_check_subtract(true, -1, -2);
|
||||
try_range_check_subtract(true, 1, 10);
|
||||
try_range_check_subtract(true, -1, -10);
|
||||
try_range_check_subtract(false, 0LL, min_ll);
|
||||
try_range_check_subtract(false, 1LL, min_ll);
|
||||
try_range_check_subtract(true, 0LL, max_ll);
|
||||
try_range_check_subtract(true, -1LL, max_ll);
|
||||
try_range_check_subtract(false, -2LL, max_ll);
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,3 +26,12 @@ 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
|
||||
1 - 2: okay PASSED
|
||||
-1 - -2: okay PASSED
|
||||
1 - 10: okay PASSED
|
||||
-1 - -10: okay PASSED
|
||||
0LL - min_ll: subtracting -9223372036854775808 from 0 would cause an integer overflow PASSED
|
||||
1LL - min_ll: subtracting -9223372036854775808 from 1 would cause an integer overflow PASSED
|
||||
0LL - max_ll: okay PASSED
|
||||
-1LL - max_ll: okay PASSED
|
||||
-2LL - max_ll: subtracting 9223372036854775807 from -2 would cause an integer underflow PASSED
|
||||
|
Loading…
Reference in New Issue
Block a user