[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 @@
-1
-1
-overflow occurred
--2147483648
-0
--2
--2
@ ../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>:
Aborted
================================================================================
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
../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht
gefunden.
(gdb) where
#0 0x00007ffff7a42438 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:54
#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
../../src/eval.c:796
#5 0x000000000040d18e in exp_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:757
#6 0x000000000040cfe2 in mult_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:695
#7 0x000000000040cee0 in add_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:660
#8 0x000000000040cd78 in shift_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:607
#9 0x000000000040cbea in cmp_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:554
#10 0x000000000040cac2 in equality_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:517
#11 0x000000000040c9f7 in and_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:489
#12 0x000000000040c92c in xor_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:462
#13 0x000000000040c861 in or_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:435
#14 0x000000000040c766 in logical_and_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:404
#15 0x000000000040c65d in logical_or_term (et=MINUS, v1=0x7fffffffd22c) at
../../src/eval.c:373
#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
../../src/builtin.c:1115
#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
../../src/m4.c:696
(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?
0001-Avoid-undefined-behaviour-when-parsing-the-number-21.patch
Description: Text Data
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Avoid undefined behaviour when parsing the number -2147483648,
Bruno Haible <=