Changeset: 4e1010b8b745 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4e1010b8b745
Modified Files:
        monetdb5/modules/atoms/str.c
Branch: Jul2017
Log Message:

Fix out-of-bounds write (found by sanitizer).
Also, don't use memmove to copy overlapping memory if that's not needed.


diffs (56 lines):

diff --git a/monetdb5/modules/atoms/str.c b/monetdb5/modules/atoms/str.c
--- a/monetdb5/modules/atoms/str.c
+++ b/monetdb5/modules/atoms/str.c
@@ -2340,30 +2340,39 @@ STRSubstitute(str *res, const str *arg1,
        int repeat = *g;
        size_t lsrc = src ? strlen(src) : 0;
        size_t ldst = dst ? strlen(dst) : 0;
-       size_t l = s ? strLen(s) : 0;
-       size_t n = l + ldst;
-       str buf, fnd, end;
+       size_t l = strLen(s);
+       size_t n;
+       char *buf;
+       const char *pfnd;
+       char *fnd;
 
+       if (s == NULL || strcmp(s, str_nil) == 0) {
+               if ((*res = GDKstrdup(str_nil)) == NULL)
+                       throw(MAL, "str.substitute", MAL_MALLOC_FAIL);
+               return MAL_SUCCEED;
+       }
+
+       n = l + ldst;
        if (repeat && ldst > lsrc && lsrc) {
                n = (ldst * l) / lsrc;  /* max length */
        }
        buf = *res = GDKmalloc(n);
        if (*res == NULL)
                throw(MAL, "str.substitute", MAL_MALLOC_FAIL);
-       end = buf + l;
-       fnd = buf;
-       strcpy(buf, s ? s : "");
-       if (lsrc == 0)
-               return MAL_SUCCEED;
+
+       pfnd = s;
        do {
-               fnd = strstr(fnd < buf ? buf : fnd, src);
+               fnd = strstr(pfnd, src);
                if (fnd == NULL)
                        break;
-               memmove(fnd + ldst, fnd + lsrc, end - fnd);
-               memcpy(fnd, dst, ldst);
-               end += ldst - lsrc;
-               fnd += ldst;
+               n = fnd - pfnd;
+               strncpy(buf, pfnd, n);
+               buf += n;
+               strncpy(buf, dst, ldst);
+               buf += ldst;
+               pfnd = fnd + lsrc;
        } while (repeat);
+       strcpy(buf, pfnd);
        return MAL_SUCCEED;
 }
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to