summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2006-09-11 04:56:43 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2006-09-11 04:56:43 +0000
commitd28b0d4de83f21c85f273cbf8cba3f7b68e42ff5 (patch)
tree06a082aa5ac5539933bcd8744b5e019ed0331ce6 /src
parent6f2530cf3a9d58707b80872e8418772e5bf0c395 (diff)
downloadcoreutils-d28b0d4de83f21c85f273cbf8cba3f7b68e42ff5.tar.xz
(eval6): Fix buffer overrun, or bad performance, if
substr's last operand is very large. Performance problem reported by Sebastian Kreft.
Diffstat (limited to 'src')
-rw-r--r--src/expr.c12
1 files changed, 8 insertions, 4 deletions
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);