[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Avoid undefined behaviour when parsing the number -2147483648

From: Bruno Haible
Subject: Avoid undefined behaviour when parsing the number -2147483648
Date: Sun, 09 May 2021 01:46:25 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-206-generic; KDE/5.18.0; x86_64; ; )

When building m4-1.4.18b with CC="gcc -ftrapv" (in order to catch
undefined behaviour through signed integer overflow at runtime),
the test suite fails:

Checking ../../checks/189.eval
@ ../doc/m4.texi:6402: Origin of test
../../checks/189.eval: status was 2, expected 0
@ ../doc/m4.texi:6402: Origin of test
../../checks/189.eval: stdout mismatch
--- m4-tmp.6646/m4-xout 2021-05-09 00:52:24.655715842 +0200
+++ m4-tmp.6646/m4-out  2021-05-09 00:52:24.651715784 +0200
@@ -1,9 +1,2 @@
-overflow occurred
@ ../doc/m4.texi:6402: Origin of test
../../checks/189.eval: stderr mismatch
--- m4-tmp.6646/m4-xerr 2021-05-09 00:52:24.659715900 +0200
+++ m4-tmp.6646/m4-err  2021-05-09 00:52:24.651715784 +0200
@@ -0,0 +1 @@
+m4: internal error detected; please report this bug to <bug-m4@gnu.org>: 

In the debugger I see this:

(gdb) run
Starting program: /BUILD/m4-1.4.18b/build-64/src/m4 
define(`max_int', eval(`0x7fffffff'))

define(`min_int', incr(max_int))

eval(min_int` < 0')

Program received signal SIGABRT, Aborted.
0x00007ffff7a42438 in __GI_raise (sig=sig@entry=6) at 
54      ../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht 
(gdb) where
#0  0x00007ffff7a42438 in __GI_raise (sig=sig@entry=6) at 
#1  0x00007ffff7a4403a in __GI_abort () at abort.c:89
#2  0x00000000004458e5 in __addvsi3 ()
#3  0x000000000040c0b7 in eval_lex (val=0x7fffffffd22c) at ../../src/eval.c:180
#4  0x000000000040d2c3 in unary_term (et=MINUS, v1=0x7fffffffd22c) at 
#5  0x000000000040d18e in exp_term (et=MINUS, v1=0x7fffffffd22c) at 
#6  0x000000000040cfe2 in mult_term (et=MINUS, v1=0x7fffffffd22c) at 
#7  0x000000000040cee0 in add_term (et=MINUS, v1=0x7fffffffd22c) at 
#8  0x000000000040cd78 in shift_term (et=MINUS, v1=0x7fffffffd22c) at 
#9  0x000000000040cbea in cmp_term (et=MINUS, v1=0x7fffffffd22c) at 
#10 0x000000000040cac2 in equality_term (et=MINUS, v1=0x7fffffffd22c) at 
#11 0x000000000040c9f7 in and_term (et=MINUS, v1=0x7fffffffd22c) at 
#12 0x000000000040c92c in xor_term (et=MINUS, v1=0x7fffffffd22c) at 
#13 0x000000000040c861 in or_term (et=MINUS, v1=0x7fffffffd22c) at 
#14 0x000000000040c766 in logical_and_term (et=MINUS, v1=0x7fffffffd22c) at 
#15 0x000000000040c65d in logical_or_term (et=MINUS, v1=0x7fffffffd22c) at 
#16 0x000000000040c473 in evaluate (expr=0x67a1b0 "-2147483648 < 0", 
val=0x7fffffffd22c) at ../../src/eval.c:297
#17 0x00000000004068d6 in m4_eval (obs=0x673f30, argc=2, argv=0x67b190) at 
#18 0x00000000004130e4 in call_macro (sym=0x679670, argc=2, argv=0x67b190, 
expansion=0x673f30) at ../../src/macro.c:278
#19 0x0000000000413415 in expand_macro (sym=0x679670) at ../../src/macro.c:369
#20 0x0000000000412810 in expand_token (obs=0x0, t=TOKEN_WORD, 
td=0x7fffffffd490, line=3) at ../../src/macro.c:118
#21 0x0000000000412636 in expand_input () at ../../src/macro.c:68
#22 0x0000000000403a0c in process_file (name=0x4469e0 "-") at ../../src/m4.c:378
#23 0x00000000004042d1 in main (argc=1, argv=0x7fffffffd728) at 
(gdb) print *val
$1 = 214748364
(gdb) print base
$2 = 10
(gdb) print digit
$3 = 8

And there's actually a FIXME in the code at that location.

The attached patch fixes it: It avoids the undefined behaviour.

I did consider using strtol. It would not help much, because it does not
support base == 1 and also may have portability problems.

OK to push?

Attachment: 0001-Avoid-undefined-behaviour-when-parsing-the-number-21.patch
Description: Text Data

reply via email to

[Prev in Thread] Current Thread [Next in Thread]