diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-07-03 17:06:53 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-07-03 17:06:53 +0000 |
commit | d2847c84e479c1373f3d0a638d79a0f68947a31d (patch) | |
tree | 5afce084f790622c9c99f9b1f8da1d2015af52ff /tests | |
parent | 79478e78b713eeb8ba084ef4847a31dc2664c91f (diff) | |
download | paxutils-d2847c84e479c1373f3d0a638d79a0f68947a31d.tar.gz |
(get_size): Rewrite to avoid numeric overflow.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/genfile.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/tests/genfile.c b/tests/genfile.c index 4ac042c..142af43 100644 --- a/tests/genfile.c +++ b/tests/genfile.c @@ -191,8 +191,10 @@ static char const * const pattern_args[] = { "default", "zeros", 0 }; static enum pattern const pattern_types[] = {DEFAULT_PATTERN, ZEROS_PATTERN}; static int -xlat_suffix (off_t *vp, char *p) +xlat_suffix (off_t *vp, const char *p) { + off_t val = *vp; + if (p[1]) return 1; switch (p[0]) @@ -213,19 +215,33 @@ xlat_suffix (off_t *vp, char *p) default: return 1; } - return 0; + return *vp <= val; } static off_t get_size (const char *str, int allow_zero) { - char *p; - off_t n; + const char *p; + off_t v = 0; - n = strtoul (str, &p, 0); - if (n < 0 || (!allow_zero && n == 0) || (*p && xlat_suffix (&n, p))) - error (EXIT_FAILURE, 0, _("Invalid size: %s"), str); - return n; + for (p = str; *p; p++) + { + int digit = *p - '0'; + off_t x = v * 10; + if (9 < (unsigned) digit) + { + if (xlat_suffix (&v, p)) + error (EXIT_FAILURE, 0, _("Invalid size: %s"), str); + else + break; + } + else if (x / 10 != v) + error (EXIT_FAILURE, 0, _("Number out of allowed range: %s"), str); + v = x + digit; + if (v < 0) + error (EXIT_FAILURE, 0, _("Negative size: %s"), str); + } + return v; } void |