Skip to content

Commit 01a2b26

Browse files
authored
Merge pull request #5632 from tautschnig/strtol
strtol must not overflow
2 parents 2858b18 + 31147d7 commit 01a2b26

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
CORE
22
main.c
3-
3+
--signed-overflow-check
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
88
^warning: ignoring
9+
--
10+
Even with --signed-overflow-check enabled, verification should succeed here as
11+
strtol reports overflow condition with errno set to ERANGE.

src/ansi-c/library/stdlib.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,23 @@ inline long strtol(const char *nptr, char **endptr, int base)
353353
break;
354354

355355
in_number=1;
356-
long res_before=res;
357-
res=res*base+ch-sub;
358-
if(res<res_before)
356+
_Bool overflow = __CPROVER_overflow_mult(res, (long)base);
357+
#pragma CPROVER check push
358+
#pragma CPROVER check disable "signed-overflow"
359+
// This is now safe; still do it within the scope of the pragma to avoid an
360+
// unnecessary assertion to be generated.
361+
if(!overflow)
362+
res *= base;
363+
#pragma CPROVER check pop
364+
if(overflow || __CPROVER_overflow_plus(res, (long)(ch - sub)))
359365
{
360366
errno=ERANGE;
361367
if(sign=='-')
362368
return LONG_MIN;
363369
else
364370
return LONG_MAX;
365371
}
372+
res += ch - sub;
366373
}
367374

368375
if(endptr!=0)

0 commit comments

Comments
 (0)