View Issue Details

IDProjectCategoryView StatusLast Update
0000578LDMud 3.3Implementationpublic2018-01-29 21:57
Reporterzesstra Assigned Tozesstra  
PriorityhighSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Fixed in Version3.3.718 
Summary0000578: Potential crashes in regexplode(), process_string(), present_clone()
Descriptionf_regexplode(), process_string() and f_present_clone() in efuns.c may crash due to stack overflows if given large enough strings.
process_string() and f_present_clone() allocate temporary buffers on the stack holding the argument string.
f_regexplode() allocates only a structure of about 40 bytes per match, but if string and regexp match suffiently often, even this will exceed the available stack space. Low eval cost limits can be a workaround for the latter, as each match costs one tick. However, an 8MB stack will only have enough memory for about 174k Matches, so the eval cost limit has to be well below 174k.
Steps To Reproduceregexplode("ad"*50000000, "d", RE_OMIT_DELIM);
process_string(@@"+"a"*12000000+"@@");
present_clone("a"*12000000+"0000123");
TagsNo tags attached.
Attached Files
efuns_alloca_patch.diff (12,866 bytes)   
Index: efuns.c
===================================================================
--- efuns.c	(Revision 2431)
+++ efuns.c	(Arbeitskopie)
@@ -660,16 +660,18 @@
 
         /* Check every string in <v> if it matches and set res[]
          * accordingly.
+         * Allocate memory and push error handler on the stack.
          */
-        res = alloca(v_size * sizeof(*res));
+        res = xalloc_with_error_handler(v_size * sizeof(*res));
         if (!res)
         {
             free_regexp(reg);
-            inter_sp = sp;
-            errorf("Stack overflow in regexp()");
+            errorf("Out of memory (%zu bytes) in regexp()",
+                    v_size * sizeof(*res));
             /* NOTREACHED */
             return sp;
         }
+        sp = inter_sp;
 
         for (num_match = i = 0; i < v_size; i++) {
             string_t *line;
@@ -695,7 +697,6 @@
             {
                 const char * emsg = rx_error_message(rc, reg);
                 free_regexp(reg);
-                inter_sp = sp;
                 errorf("regexp: %s\n", emsg);
                 /* NOTREACHED */
                 return NULL;
@@ -712,9 +713,11 @@
                 continue;
             assign_svalue_no_free(&ret->item[j++], &v->item[i]);
         }
-
+        /* Free regexp and the intermediate buffer res by freeing the error
+         * handler. */
         free_regexp(reg);
-    }while(0);
+        free_svalue(sp--);
+    } while(0);
 
     free_svalue(sp--);
     free_svalue(sp--);
@@ -728,6 +731,46 @@
 } /* f_regexp() */
 
 /*-------------------------------------------------------------------------*/
+/* The found delimiter matches in f_regexplode() are kept in a list of these
+ * structures.
+ */
+struct regexplode_match {
+    size_t start, end;              /* Start and end of the match in text */
+    struct regexplode_match *next;  /* Next list element */
+};
+
+/* We need a special error handling for f_reg_explode(), because it allocates
+ * a chained list which we have to iterate and free. */
+struct regexplode_cleanup_s {
+    svalue_t sval;
+    regexp_t *reg;
+    struct regexplode_match *matchchain;
+};
+
+static void
+regexplode_error_handler( svalue_t * arg)
+/* The error handler: iterate over the chain of matches and free them.
+ * Note: it is static, but the compiler will have to emit a function and 
+ * symbol for this because the address of the function is taken and it is 
+ * therefore not suitable to be inlined.
+ */
+{
+    struct regexplode_cleanup_s *handler = (struct regexplode_cleanup_s *)arg;
+    
+    if (handler->reg)
+        free_regexp(handler->reg);
+    
+    if (handler->matchchain) {
+        struct regexplode_match *match = handler->matchchain;
+        while(match) {
+            struct regexplode_match *next = match->next;
+            xfree(match);
+            match = next;
+        }
+    }
+    xfree(handler);
+} /* regexplode_error_handler() */
+
 svalue_t *
 f_regexplode (svalue_t *sp)
 
@@ -744,49 +787,62 @@
  */
 
 {
-    /* The found delimiter matches are kept in a list of these
-     * structures which are allocated on the stack.
-     */
-    struct regexplode_match {
-        size_t start, end;              /* Start and end of the match in text */
-        struct regexplode_match *next;  /* Next list element */
-    };
 
     string_t *text;                    /* Input string */
     string_t *pattern;                 /* Delimiter pattern from the vm stack */
     regexp_t *reg;                     /* Compiled pattern */
     struct regexplode_match *matches;  /* List of matches */
-    struct regexplode_match **matchp;  /* Pointer to previous_match.next */
+    struct regexplode_match *lastmatch;  /* Pointer to previous_match.next */
     struct regexplode_match *match;    /* Current match structure */
     vector_t *ret;                     /* Result vector */
     svalue_t *svp;                     /* Next element in ret to fill in */
     int num_match;                     /* Number of matches */
-    int arraysize;                     /* Size of result array */
+    p_int arraysize;                   /* Size of result array */
     int       opt;                     /* RE options */
     int       rc;                      /* Result from rx_exec() */
     size_t    start;                   /* Start position for match */
+    /* cleanup structure holding the head of chain of matches */
+    struct regexplode_cleanup_s *cleanup;
 
+    
     /* Get the efun arguments */
-
     text = sp[-2].u.str;
     pattern = sp[-1].u.str;
     opt = (int)sp->u.number;
-
+    
+    /* allocate space for cleanup structure. */
+    cleanup = xalloc(sizeof(*cleanup));
+    if (!cleanup)
+        errorf("Out of memory (%zu bytes) for cleanup structure in "
+               "regexplode().\n",sizeof(*cleanup));
+    
+    /* allocate head of match list (this will actually be a dummy and will 
+     * NOT contain any valid match!) */
+    matches = xalloc(sizeof(*matches));
+    if (!matches)
+    {
+        xfree(cleanup);
+        errorf("Out of memory (%zu bytes) for match list in regexplode().\n",
+               sizeof(*matches));
+    }
+    cleanup->matchchain = matches;
+    /*  push error handler above the args on the stack */
+    sp = push_error_handler(regexplode_error_handler, &(cleanup->sval));
+    
     reg = rx_compile(pattern, opt, MY_FALSE);
     if (reg == 0) {
-        inter_sp = sp;
         errorf("Unrecognized search pattern");
         /* NOTREACHED */
         return sp;
     }
-
+    cleanup->reg = reg;
+    
     /* Loop over <text>, repeatedly matching it against the pattern,
      * until all matches have been found and recorded.
      */
     start = 0;
     num_match = 0;
-    matches = NULL;
-    matchp = &matches;
+    lastmatch = matches;    /* head of list */
     while ((rc = rx_exec(reg, text, start)) > 0)
     {
         if (add_eval_cost(1))
@@ -798,20 +854,21 @@
             break;
         }
 
-        match = alloca(sizeof *match);
+        match = xalloc(sizeof *match);
         if (!match)
         {
-            free_regexp(reg);
-            inter_sp = sp;
-            errorf("Stack overflow in regexplode()");
+            errorf("Out of memory (%zu bytes) in regexplode().\n",
+                   sizeof(*match));
             /* NOTREACHED */
             return sp;
         }
         rx_get_match(reg, text, &(match->start), &(match->end));
         start = match->end;
-        *matchp = match;
-        matchp = &match->next;
+        /* add match to the match list */
+        lastmatch->next = match;
+        lastmatch = match;
         num_match++;
+        
         if (start == mstrsize(text)
          || (match->start == start && ++start == mstrsize(text)) )
             break;
@@ -820,14 +877,12 @@
     if (rc < 0) /* Premature abort on error */
     {
         const char * emsg = rx_error_message(rc, reg);
-        free_regexp(reg);
-        inter_sp = sp;
         errorf("regexp: %s\n", emsg);
         /* NOTREACHED */
         return NULL;
     }
 
-    *matchp = 0; /* Terminate list properly */
+    lastmatch->next = 0; /* Terminate list properly */
 
     /* Prepare the result vector */
     if (opt & RE_OMIT_DELIM)
@@ -836,21 +891,19 @@
         arraysize = 2 * num_match + 1;
 
     if (max_array_size && arraysize > (long)max_array_size-1 ) {
-        free_regexp(reg);
-        inter_sp = sp;
-        errorf("Illegal array size: %d",arraysize);
+        errorf("Illegal array size: %"PRIdPINT".\n", arraysize);
         /* NOTREACHED */
         return sp;
     }
     ret = allocate_array(arraysize);
 
-    /* Walk down the list of matches, extracting the
-     * text parts and matched delimiters, copying them
-     * into ret.
+    /* Walk down the list of matches, extracting the text parts and matched 
+     * delimiters, copying them into ret. Remember not to start with the head
+     * of list (the dummy), but the one after.
      */
     svp = ret->item;
     start = 0;
-    for (match = matches; match; match = match->next) {
+    for (match = matches->next; match; match = match->next) {
         mp_int len;
         string_t *txt;
 
@@ -858,11 +911,13 @@
         len = match->start - start;
         if (len)
         {
-            memsafe(txt = mstr_extract(text, start, match->start-1), (size_t)len, "text before delimiter");
+            memsafe(txt = mstr_extract(text, start, match->start-1), 
+                    (size_t)len, "text before delimiter");
             put_string(svp, txt);
         }
         else
             put_ref_string(svp, STR_EMPTY);
+        
         svp++;
 
         /* Copy the matched delimiter */
@@ -876,6 +931,7 @@
             }
             else
                 put_ref_string(svp, STR_EMPTY);
+            
             svp++;
         }
 
@@ -897,15 +953,12 @@
             put_ref_string(svp, STR_EMPTY);
     }
 
-    /* Cleanup */
-    free_regexp(reg);
-    free_svalue(sp);
-    sp--;
-    free_svalue(sp);
-    sp--;
-    free_svalue(sp);
+    /* Cleanup: free error handler and 3 arguments. Freeing the error handler
+     * will free the regexp and the chain of matches. */
+    sp = pop_n_elems(4, sp);
 
     /* Return the result */
+    sp++;
     put_array(sp, ret);
     return sp;
 } /* f_regexplode() */
@@ -2708,10 +2761,11 @@
      */
     if (original)
     {
-        func = alloca(strlen(str)+1);
+        /* allocate memory and push error handler */
+        func = xalloc_with_error_handler(strlen(str)+1);
         if (!func)
-            errorf("Out of stack memory (%lu bytes)\n"
-                 , (unsigned long)(strlen(str)+1));
+            errorf("Out of memory (%zu bytes) in process_value().\n"
+                 , strlen(str)+1);
         strcpy(func, str);
     }
     else
@@ -2728,6 +2782,8 @@
      */
     if ( NULL == (func2 = find_tabled_str(func)) )
     {
+        /* free the error handler */
+        free_svalue(inter_sp--);
         return NULL;
     }
 
@@ -2746,6 +2802,8 @@
 
     if (!ob)
     {
+        /* free the error handler */
+        free_svalue(inter_sp--);
         return NULL;
     }
 
@@ -2764,11 +2822,17 @@
             narg++;
         }
     }
+    
+    /* Apply the function */
+    ret = apply(func2, ob, numargs);
 
-    /* Apply the function and see if adequate answer is returned.
+    /* Free func by freeing the error handler (if we allocated func).
+     * Has to be done now, after the arguments have been popped by apply().
      */
-    ret = apply(func2, ob, numargs);
-
+    if (original)
+        free_svalue(inter_sp--);
+    
+    /* see if adequate answer is returned by the apply(). */
     if (ret && ret->type == T_STRING)
         return ret->u.str;
         /* The svalue is stored statically in apply_return_value */
@@ -4430,9 +4494,11 @@
         char * end;
         char * sane_name;
         char * name0;  /* Intermediate name */
-
+        char * tmpbuf; /* intermediate buffer for stripping any #xxxx */
+        
         name0 = get_txt(sp[-1].u.str);
-
+        tmpbuf = NULL;
+        
         /* Normalize the given string and check if it is
          * in the shared string table. If not, we know that
          * there is no blueprint with that name
@@ -4454,17 +4520,24 @@
                 /* Not a digit: maybe a '#' */
                 if ('#' == c && len - i > 1)
                 {
-                    name0 = alloca((size_t)i + 1);
-                    if (!name0)
-                        errorf("Out of stack memory.\n");
-                    strncpy(name0, get_txt(sp[-1].u.str), (size_t)i);
+                    tmpbuf = xalloc((size_t)i + 1);
+                    if (!tmpbuf)
+                    {
+                        errorf("Out of memory (%ld bytes) for temporary "
+                               "buffer in present_clone().\n", i+1);
+                    }
+                    strncpy(tmpbuf, get_txt(sp[-1].u.str), (size_t)i);
                     name0[i] = '\0';
                 }
 
                 break; /* in any case */
             }
         }
-
+        /* if we got a clone name, tmpbuf is filled with the BP name. In any
+         * case, name0 contains now the name to be used. */
+        if (tmpbuf)
+            name0 = tmpbuf;
+        
         /* Now make the name sane */
         sane_name = (char *)make_name_sane(name0, !compat_mode);
 
@@ -4472,7 +4545,14 @@
             name = find_tabled_str(sane_name);
         else
             name = find_tabled_str(name0);
-
+        
+        /* tmpbuf (and name0 which might point to the same memory) is unneeded
+         * from now on. Setting both to NULL, just in case somebody uses 
+         * them later below. */
+        if (tmpbuf) {
+            xfree(tmpbuf);
+            tmpbuf = name0 = NULL;
+        }
     }
     else if (sp[-1].type == T_OBJECT)
     {
efuns_alloca_patch.diff (12,866 bytes)   
efuns_alloca_patch-V2.diff (11,701 bytes)   
Index: efuns.c
===================================================================
--- efuns.c	(Revision 2431)
+++ efuns.c	(Arbeitskopie)
@@ -660,16 +660,18 @@
 
         /* Check every string in <v> if it matches and set res[]
          * accordingly.
+         * Allocate memory and push error handler on the stack.
          */
-        res = alloca(v_size * sizeof(*res));
+        res = xalloc_with_error_handler(v_size * sizeof(*res));
         if (!res)
         {
             free_regexp(reg);
-            inter_sp = sp;
-            errorf("Stack overflow in regexp()");
+            errorf("Out of memory (%zu bytes) in regexp()",
+                    v_size * sizeof(*res));
             /* NOTREACHED */
             return sp;
         }
+        sp = inter_sp;
 
         for (num_match = i = 0; i < v_size; i++) {
             string_t *line;
@@ -695,7 +697,6 @@
             {
                 const char * emsg = rx_error_message(rc, reg);
                 free_regexp(reg);
-                inter_sp = sp;
                 errorf("regexp: %s\n", emsg);
                 /* NOTREACHED */
                 return NULL;
@@ -712,9 +713,11 @@
                 continue;
             assign_svalue_no_free(&ret->item[j++], &v->item[i]);
         }
-
+        /* Free regexp and the intermediate buffer res by freeing the error
+         * handler. */
         free_regexp(reg);
-    }while(0);
+        free_svalue(sp--);
+    } while(0);
 
     free_svalue(sp--);
     free_svalue(sp--);
@@ -728,6 +731,43 @@
 } /* f_regexp() */
 
 /*-------------------------------------------------------------------------*/
+/* The found delimiter matches in f_regexplode() are kept in a list of these
+ * structures.
+ */
+struct regexplode_match {
+    size_t start, end;              /* Start and end of the match in text */
+    struct regexplode_match *next;  /* Next list element */
+};
+
+/* We need a special error handling for f_reg_explode(). It allocates a
+ * chained list of regexplode_match structures in a mempool and the compiled
+ * regexp which we have to free.
+ */
+struct regexplode_cleanup_s {
+    svalue_t sval;
+    regexp_t *reg;
+    Mempool matchmempool;
+};
+
+static void
+regexplode_error_handler( svalue_t * arg)
+/* The error handler: delete the mempool and free the compiled regexp.
+ * Note: it is static, but the compiler will have to emit a function and 
+ * symbol for this because the address of the function is taken and it is 
+ * therefore not suitable to be inlined.
+ */
+{
+    struct regexplode_cleanup_s *handler = (struct regexplode_cleanup_s *)arg;
+    
+    if (handler->reg)
+        free_regexp(handler->reg);
+    
+    if (handler->matchmempool) {
+        mempool_delete(handler->matchmempool);
+    }
+    xfree(handler);
+} /* regexplode_error_handler() */
+
 svalue_t *
 f_regexplode (svalue_t *sp)
 
@@ -744,13 +784,6 @@
  */
 
 {
-    /* The found delimiter matches are kept in a list of these
-     * structures which are allocated on the stack.
-     */
-    struct regexplode_match {
-        size_t start, end;              /* Start and end of the match in text */
-        struct regexplode_match *next;  /* Next list element */
-    };
 
     string_t *text;                    /* Input string */
     string_t *pattern;                 /* Delimiter pattern from the vm stack */
@@ -761,25 +794,46 @@
     vector_t *ret;                     /* Result vector */
     svalue_t *svp;                     /* Next element in ret to fill in */
     int num_match;                     /* Number of matches */
-    int arraysize;                     /* Size of result array */
+    p_int arraysize;                   /* Size of result array */
     int       opt;                     /* RE options */
     int       rc;                      /* Result from rx_exec() */
     size_t    start;                   /* Start position for match */
+    Mempool   pool;                    /* Mempool for the list of matches */
+    /* cleanup structure holding the head of chain of matches */
+    struct regexplode_cleanup_s *cleanup;
 
+    
     /* Get the efun arguments */
-
     text = sp[-2].u.str;
     pattern = sp[-1].u.str;
     opt = (int)sp->u.number;
+    
+    /* allocate space for cleanup structure. */
+    cleanup = xalloc(sizeof(*cleanup));
+    if (!cleanup)
+        errorf("Out of memory (%zu bytes) for cleanup structure in "
+               "regexplode().\n",sizeof(*cleanup));
 
+    /* create mempool */
+    pool = new_mempool(size_mempool(sizeof(*matches)));
+    if (!pool)
+    {
+        xfree(cleanup);
+        errorf("Out of memory (%zu) for mempool in regexplode().\n",
+               sizeof(*matches));
+    }
+    cleanup->matchmempool = pool;
+    /*  push error handler above the args on the stack */
+    sp = push_error_handler(regexplode_error_handler, &(cleanup->sval));
+        
     reg = rx_compile(pattern, opt, MY_FALSE);
     if (reg == 0) {
-        inter_sp = sp;
         errorf("Unrecognized search pattern");
         /* NOTREACHED */
         return sp;
     }
-
+    cleanup->reg = reg;
+    
     /* Loop over <text>, repeatedly matching it against the pattern,
      * until all matches have been found and recorded.
      */
@@ -798,20 +852,21 @@
             break;
         }
 
-        match = alloca(sizeof *match);
+        match = mempool_alloc(pool, sizeof *match);
         if (!match)
         {
-            free_regexp(reg);
-            inter_sp = sp;
-            errorf("Stack overflow in regexplode()");
+            errorf("Out of memory (%zu bytes) in regexplode().\n",
+                   sizeof(*match));
             /* NOTREACHED */
             return sp;
         }
         rx_get_match(reg, text, &(match->start), &(match->end));
         start = match->end;
+        /* add match to the match list */
         *matchp = match;
         matchp = &match->next;
         num_match++;
+        
         if (start == mstrsize(text)
          || (match->start == start && ++start == mstrsize(text)) )
             break;
@@ -820,8 +875,6 @@
     if (rc < 0) /* Premature abort on error */
     {
         const char * emsg = rx_error_message(rc, reg);
-        free_regexp(reg);
-        inter_sp = sp;
         errorf("regexp: %s\n", emsg);
         /* NOTREACHED */
         return NULL;
@@ -836,17 +889,14 @@
         arraysize = 2 * num_match + 1;
 
     if (max_array_size && arraysize > (long)max_array_size-1 ) {
-        free_regexp(reg);
-        inter_sp = sp;
-        errorf("Illegal array size: %d",arraysize);
+        errorf("Illegal array size: %"PRIdPINT".\n", arraysize);
         /* NOTREACHED */
         return sp;
     }
     ret = allocate_array(arraysize);
 
-    /* Walk down the list of matches, extracting the
-     * text parts and matched delimiters, copying them
-     * into ret.
+    /* Walk down the list of matches, extracting the text parts and matched 
+     * delimiters, copying them into ret.
      */
     svp = ret->item;
     start = 0;
@@ -858,11 +908,13 @@
         len = match->start - start;
         if (len)
         {
-            memsafe(txt = mstr_extract(text, start, match->start-1), (size_t)len, "text before delimiter");
+            memsafe(txt = mstr_extract(text, start, match->start-1), 
+                    (size_t)len, "text before delimiter");
             put_string(svp, txt);
         }
         else
             put_ref_string(svp, STR_EMPTY);
+        
         svp++;
 
         /* Copy the matched delimiter */
@@ -876,6 +928,7 @@
             }
             else
                 put_ref_string(svp, STR_EMPTY);
+            
             svp++;
         }
 
@@ -897,15 +950,12 @@
             put_ref_string(svp, STR_EMPTY);
     }
 
-    /* Cleanup */
-    free_regexp(reg);
-    free_svalue(sp);
-    sp--;
-    free_svalue(sp);
-    sp--;
-    free_svalue(sp);
+    /* Cleanup: free error handler and 3 arguments. Freeing the error handler
+     * will free the regexp and the chain of matches. */
+    sp = pop_n_elems(4, sp);
 
     /* Return the result */
+    sp++;
     put_array(sp, ret);
     return sp;
 } /* f_regexplode() */
@@ -2708,10 +2758,11 @@
      */
     if (original)
     {
-        func = alloca(strlen(str)+1);
+        /* allocate memory and push error handler */
+        func = xalloc_with_error_handler(strlen(str)+1);
         if (!func)
-            errorf("Out of stack memory (%lu bytes)\n"
-                 , (unsigned long)(strlen(str)+1));
+            errorf("Out of memory (%zu bytes) in process_value().\n"
+                 , strlen(str)+1);
         strcpy(func, str);
     }
     else
@@ -2728,6 +2779,8 @@
      */
     if ( NULL == (func2 = find_tabled_str(func)) )
     {
+        /* free the error handler */
+        free_svalue(inter_sp--);
         return NULL;
     }
 
@@ -2746,6 +2799,8 @@
 
     if (!ob)
     {
+        /* free the error handler */
+        free_svalue(inter_sp--);
         return NULL;
     }
 
@@ -2764,11 +2819,17 @@
             narg++;
         }
     }
+    
+    /* Apply the function */
+    ret = apply(func2, ob, numargs);
 
-    /* Apply the function and see if adequate answer is returned.
+    /* Free func by freeing the error handler (if we allocated func).
+     * Has to be done now, after the arguments have been popped by apply().
      */
-    ret = apply(func2, ob, numargs);
-
+    if (original)
+        free_svalue(inter_sp--);
+    
+    /* see if adequate answer is returned by the apply(). */
     if (ret && ret->type == T_STRING)
         return ret->u.str;
         /* The svalue is stored statically in apply_return_value */
@@ -4430,9 +4491,11 @@
         char * end;
         char * sane_name;
         char * name0;  /* Intermediate name */
-
+        char * tmpbuf; /* intermediate buffer for stripping any #xxxx */
+        
         name0 = get_txt(sp[-1].u.str);
-
+        tmpbuf = NULL;
+        
         /* Normalize the given string and check if it is
          * in the shared string table. If not, we know that
          * there is no blueprint with that name
@@ -4454,17 +4517,24 @@
                 /* Not a digit: maybe a '#' */
                 if ('#' == c && len - i > 1)
                 {
-                    name0 = alloca((size_t)i + 1);
-                    if (!name0)
-                        errorf("Out of stack memory.\n");
-                    strncpy(name0, get_txt(sp[-1].u.str), (size_t)i);
+                    tmpbuf = xalloc((size_t)i + 1);
+                    if (!tmpbuf)
+                    {
+                        errorf("Out of memory (%ld bytes) for temporary "
+                               "buffer in present_clone().\n", i+1);
+                    }
+                    strncpy(tmpbuf, get_txt(sp[-1].u.str), (size_t)i);
                     name0[i] = '\0';
                 }
 
                 break; /* in any case */
             }
         }
-
+        /* if we got a clone name, tmpbuf is filled with the BP name. In any
+         * case, name0 contains now the name to be used. */
+        if (tmpbuf)
+            name0 = tmpbuf;
+        
         /* Now make the name sane */
         sane_name = (char *)make_name_sane(name0, !compat_mode);
 
@@ -4472,7 +4542,14 @@
             name = find_tabled_str(sane_name);
         else
             name = find_tabled_str(name0);
-
+        
+        /* tmpbuf (and name0 which might point to the same memory) is unneeded
+         * from now on. Setting both to NULL, just in case somebody uses 
+         * them later below. */
+        if (tmpbuf) {
+            xfree(tmpbuf);
+            tmpbuf = name0 = NULL;
+        }
     }
     else if (sp[-1].type == T_OBJECT)
     {
efuns_alloca_patch-V2.diff (11,701 bytes)   

Relationships

related to 0000553 resolvedGnomi LDMud 3.2 Backports of 3.3 fixes for 3.2.16 
child of 0000545 new LDMud 3.3 Usages of alloca() have to be checked for possible stack overflow 

Activities

zesstra

2008-09-29 16:18

administrator   ~0000796

Forgot regexp(), which is also affected, but in this case a huge array instead of a large string is needed and most muds limit the maximum array size.
I attached a patch for fixing these 4 issues in efuns.c, but have to do some more tests tomorrow.

zesstra

2008-10-01 14:08

administrator   ~0000797

I didn't like the repeated allocation of small structures on the heap. The curretn version of the patch uses a mempool for reducing the number of allocations and combines several structures in one block.

zesstra

2008-12-14 14:54

administrator   ~0000817

Applied the second patch (without 2 bugs) in r2446.

Issue History

Date Modified Username Field Change
2008-09-28 14:24 zesstra New Issue
2008-09-28 14:24 zesstra Status new => assigned
2008-09-28 14:24 zesstra Assigned To => zesstra
2008-09-28 14:25 zesstra Relationship added child of 0000545
2008-09-29 16:14 zesstra File Added: efuns_alloca_patch.diff
2008-09-29 16:18 zesstra Note Added: 0000796
2008-09-29 16:28 zesstra File Deleted: efuns_alloca_patch.diff
2008-09-29 16:29 zesstra File Added: efuns_alloca_patch.diff
2008-10-01 14:06 zesstra File Added: efuns_alloca_patch-V2.diff
2008-10-01 14:08 zesstra Note Added: 0000797
2008-11-17 15:38 Gnomi Relationship added related to 0000553
2008-12-14 14:54 zesstra Status assigned => resolved
2008-12-14 14:54 zesstra Fixed in Version => 3.3.718
2008-12-14 14:54 zesstra Resolution open => fixed
2008-12-14 14:54 zesstra Note Added: 0000817
2010-11-16 09:42 zesstra Source_changeset_attached => ldmud.git master f243fde3
2018-01-29 18:59 zesstra Source_changeset_attached => ldmud.git master f243fde3
2018-01-29 21:57 zesstra Source_changeset_attached => ldmud.git master f243fde3