gbranden pushed a commit to branch master
in repository groff.
commit e0f26fa73f6e7628f84e4ad5abe4fd643ad836af
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Jul 15 09:45:24 2024 -0500
[troff]: Fix Savannah #64301 (2/15).
* src/roff/troff/number.cpp: Include `config.h` and `stdckdint.h`
headers.
(get_number, get_integer, is_valid_expression): Use `ckd_add()`,
`ckd_sub()`, and `ckd_mul()` instead of primitive operations, and
throw error diagnostic if arithmetic wraps.
(is_valid_expression): Remove manual detection of overflow.
---
ChangeLog | 6 +++++
src/roff/troff/number.cpp | 65 ++++++++++++++---------------------------------
2 files changed, 25 insertions(+), 46 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index aadaadf84..c3f671214 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
[troff]: Prevent traps on overflowing integer arithmetic.
* bootstrap.conf: Add "stdckdint" to `gnulib_modules`.
+ * src/roff/troff/number.cpp: Include `config.h` and
+ `stdckdint.h` headers.
+ (get_number, get_integer, is_valid_expression): Use `ckd_add()`,
+ `ckd_sub()`, and `ckd_mul()` instead of primitive operations,
+ and throw error diagnostic if arithmetic wraps.
+ (is_valid_expression): Remove manual detection of overflow.
2024-07-18 G. Branden Robinson <[email protected]>
diff --git a/src/roff/troff/number.cpp b/src/roff/troff/number.cpp
index 6a738767e..9ce2d2d80 100644
--- a/src/roff/troff/number.cpp
+++ b/src/roff/troff/number.cpp
@@ -16,6 +16,11 @@ for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdckdint.h>
#include "troff.h"
#include "hvunits.h"
@@ -162,10 +167,12 @@ bool get_number(units *res, unsigned char si, units
prev_value)
*res = u;
break;
case INCREMENT:
- *res = prev_value + u;
+ if (ckd_add(res, prev_value, u))
+ error("integer addition wrapped");
break;
case DECREMENT:
- *res = prev_value - u;
+ if (ckd_sub(res, prev_value, u))
+ error("integer subtraction wrapped");
break;
default:
assert(0 == "unhandled case returned by get_incr_number()");
@@ -183,10 +190,12 @@ bool get_integer(int *res, int prev_value)
*res = i;
break;
case INCREMENT:
- *res = prev_value + int(i);
+ if (ckd_add(res, prev_value, i))
+ error("integer addition wrapped");
break;
case DECREMENT:
- *res = prev_value - int(i);
+ if (ckd_sub(res, prev_value, i))
+ error("integer subtraction wrapped");
break;
default:
assert(0 == "unhandled case returned by get_incr_number()");
@@ -296,7 +305,6 @@ static bool is_valid_expression(units *u, int scaling_unit,
if (!is_valid_term(&u2, scaling_unit, is_parenthesized,
is_mandatory))
return false;
- bool had_overflow = false;
switch (op) {
case '<':
*u = *u < u2;
@@ -328,57 +336,22 @@ static bool is_valid_expression(units *u, int
scaling_unit,
*u = *u > 0 || u2 > 0;
break;
case '+':
- if (u2 < 0) {
- if (*u < INT_MIN - u2)
- had_overflow = true;
- }
- else if (u2 > 0) {
- if (*u > INT_MAX - u2)
- had_overflow = true;
- }
- if (had_overflow) {
- error("addition overflow");
+ if (ckd_add(u, *u, u2)) {
+ error("integer addition wrapped");
return false;
}
- *u += u2;
break;
case '-':
- if (u2 < 0) {
- if (*u > INT_MAX + u2)
- had_overflow = true;
- }
- else if (u2 > 0) {
- if (*u < INT_MIN + u2)
- had_overflow = true;
- }
- if (had_overflow) {
- error("subtraction overflow");
+ if (ckd_sub(u, *u, u2)) {
+ error("integer subtraction wrapped");
return false;
}
- *u -= u2;
break;
case '*':
- if (u2 < 0) {
- if (*u > 0) {
- if ((unsigned)*u > -(unsigned)INT_MIN / -(unsigned)u2)
- had_overflow = true;
- }
- else if (-(unsigned)*u > INT_MAX / -(unsigned)u2)
- had_overflow = true;
- }
- else if (u2 > 0) {
- if (*u > 0) {
- if (*u > INT_MAX / u2)
- had_overflow = true;
- }
- else if (-(unsigned)*u > -(unsigned)INT_MIN / u2)
- had_overflow = true;
- }
- if (had_overflow) {
- error("multiplication overflow");
+ if (ckd_mul(u, *u, u2)) {
+ error("integer multiplication wrapped");
return false;
}
- *u *= u2;
break;
case '/':
if (u2 == 0) {
_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit