Keep track of the length of the string in ExpandVariables().
authorPascal Stumpf <Pascal.Stumpf@cubes.de>
Thu, 22 Nov 2012 13:27:26 +0000 (14:27 +0100)
committerJon Trulson <jon@radscan.com>
Sun, 25 Nov 2012 02:25:19 +0000 (19:25 -0700)
On OpenBSD, the 'S' option to malloc(3) enables guard pages (among other
things).  This loop could have triggered this trap when reading beyond the
buffer.  Also, the whole "while(*ip)" construct was based on the assumption that
the memory after the string is always zero-filled.

cde/programs/dtdocbook/instant/translate.c

index cb012702b59af7bf927d6cd9a59f47b240fb34a8..959833533011633f5cae25816e8f1f21c65de806 100644 (file)
@@ -197,14 +197,17 @@ ExpandVariables(
     char       *def_val, *s, *atval, *modifier;
     char       vbuf[500];
     int                lev;
+    size_t     len = 0, totlen;
 
     ip = in;
     op = out;
-    while (*ip) {
+    totlen = strlen(ip);
+    while (totlen >= len && *ip) {
        /* start of regular variable? */
        if (*ip == VDELIM && *(ip+1) == L_CURLY && *(ip+2) != '_') {
            ip++;
            ip++;               /* point at variable name */
+           len + 2;
            vp = vbuf;
            /*  Look for matching (closing) curly. (watch for nesting)
             *  We store the variable content in a tmp buffer, so we don't
@@ -216,11 +219,13 @@ ExpandVariables(
                if (*ip == R_CURLY) {
                    if (lev == 0) {
                        ip++;
+                       len++;
                        break;
                    }
                    else lev--;
                }
                *vp++ = *ip++;  /* copy to variable buffer */
+               len++;
            }
            *vp = EOS;
            /* vbuf now contains the variable name (stuff between curlys). */
@@ -270,6 +275,7 @@ ExpandVariables(
            }
        }
        *op++ = *ip++;
+       len++;
     }
     *op = EOS;         /* terminate string */
 }