diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2006-09-11 04:56:43 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2006-09-11 04:56:43 +0000 |
commit | d28b0d4de83f21c85f273cbf8cba3f7b68e42ff5 (patch) | |
tree | 06a082aa5ac5539933bcd8744b5e019ed0331ce6 | |
parent | 6f2530cf3a9d58707b80872e8418772e5bf0c395 (diff) | |
download | coreutils-d28b0d4de83f21c85f273cbf8cba3f7b68e42ff5.tar.xz |
(eval6): Fix buffer overrun, or bad performance, if
substr's last operand is very large. Performance problem reported
by Sebastian Kreft.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/expr.c | 12 |
2 files changed, 14 insertions, 4 deletions
@@ -1,3 +1,9 @@ +2006-09-10 Paul Eggert <eggert@cs.ucla.edu> + + * src/expr.c (eval6): Fix buffer overrun, or bad performance, if + substr's last operand is very large. Performance problem reported + by Sebastian Kreft. + 2006-09-09 Jim Meyering <jim@meyering.net> * Makefile.maint (sc_prohibit_jm_in_m4): Don't hang when there diff --git a/src/expr.c b/src/expr.c index e0510fc10..99bbdd8fd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -551,21 +551,25 @@ eval6 (bool evaluate) } else if (nextarg ("substr")) { + size_t llen; l = eval6 (evaluate); i1 = eval6 (evaluate); i2 = eval6 (evaluate); tostring (l); + llen = strlen (l->u.s); if (!toarith (i1) || !toarith (i2) - || strlen (l->u.s) < i1->u.i + || llen < i1->u.i || i1->u.i <= 0 || i2->u.i <= 0) v = str_value (""); else { + size_t vlen = MIN (i2->u.i, llen - i1->u.i + 1); + char *vlim; v = xmalloc (sizeof *v); v->type = string; - v->u.s = strncpy (xmalloc (i2->u.i + 1), - l->u.s + i1->u.i - 1, i2->u.i); - v->u.s[i2->u.i] = 0; + v->u.s = xmalloc (vlen + 1); + vlim = mempcpy (v->u.s, l->u.s + i1->u.i - 1, vlen); + *vlim = '\0'; } freev (l); freev (i1); |