(eval6): Fix buffer overrun, or bad performance, if
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 11 Sep 2006 04:56:43 +0000 (04:56 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 11 Sep 2006 04:56:43 +0000 (04:56 +0000)
substr's last operand is very large.  Performance problem reported
by Sebastian Kreft.

ChangeLog
src/expr.c

index 4896c20fced8b1504e7c495d87d2377ff621a847..ff97f70b5a5832511b3e72dea104e97d9374c577 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index e0510fc10e7b9693aa4b1e0f4bf880108f801ffe..99bbdd8fd4766409aabca10d8ca2fd2ce24f996a 100644 (file)
@@ -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);