summaryrefslogtreecommitdiff
path: root/src/test.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2005-01-13 23:27:34 +0000
committerJim Meyering <jim@meyering.net>2005-01-13 23:27:34 +0000
commit24158efbdf6580b485c2aa3f478c4986c4ca1882 (patch)
tree5339ba1c53dbd27ffcc3cf6337fb378dd01bb4ca /src/test.c
parentb54fd550bd7edee561cc423d592cd391403108bf (diff)
downloadcoreutils-24158efbdf6580b485c2aa3f478c4986c4ca1882.tar.xz
(is_int): Don't overflow when evaluating integer constants.
Before, ./test $(echo 2^64|bc) -eq 0 && echo FAIL would print `FAIL'.
Diffstat (limited to 'src/test.c')
-rw-r--r--src/test.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/test.c b/src/test.c
index 386e17d2b..2caebd4de 100644
--- a/src/test.c
+++ b/src/test.c
@@ -2,7 +2,7 @@
/* Modified to run with the GNU shell by bfox. */
-/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -148,6 +148,7 @@ is_int (register char *string, intmax_t *result)
{
int sign;
intmax_t value;
+ char const *orig_string;
sign = 1;
value = 0;
@@ -162,6 +163,9 @@ is_int (register char *string, intmax_t *result)
if (!*string)
return false;
+ /* Save a pointer to the start, for diagnostics. */
+ orig_string = string;
+
/* We allow leading `-' or `+'. */
if (*string == '-' || *string == '+')
{
@@ -177,7 +181,17 @@ is_int (register char *string, intmax_t *result)
while (digit (*string))
{
if (result)
- value = (value * 10) + digit_value (*string);
+ {
+ intmax_t new_v = 10 * value + sign * (*string - '0');
+ if (0 < sign
+ ? (INTMAX_MAX / 10 < value || new_v < 0)
+ : (value < INTMAX_MIN / 10 || 0 < new_v))
+ test_syntax_error ((0 < sign
+ ? _("integer is too large: %s\n")
+ : _("integer is too small: %s\n")),
+ orig_string);
+ value = new_v;
+ }
string++;
}
@@ -190,10 +204,7 @@ is_int (register char *string, intmax_t *result)
return false;
if (result)
- {
- value *= sign;
- *result = value;
- }
+ *result = value;
return true;
}