Re: Bug#470492: crm114: strange segfault with improper usage

Paolo <[email protected]>
Newsgroups gmane.mail.spam.crm114
Message-ID <20080401202442.GX25908@localhost>
On Tue, Apr 01, 2008 at 02:51:31PM -0400, Bill Y wrote:
> 
> I saw like three versions of the patch go by, and I'm waiting
> to see what things settle down to before I put the patch into
> mainline.
> 
> So- if it's settled- what's the patch?  :)

attached. Against latest src/.

-- 
paolo

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

_______________________________________________
Crm114-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/crm114-general
crmregex_tre.c_segv-080401.diff (text/plain, 9.2 KB)
--- crmregex_tre.c.orig	Wed Mar 26 02:50:00 2008
+++ crmregex_tre.c	Tue Apr  1 22:20:24 2008
@@ -25,6 +25,7 @@
 //  and include the routine declarations file
 #include "crm114.h"
 
+#if CRM_REGEX_CACHESIZE > 0
  //  Cache for regex compilations
 typedef struct {
   char *regex;
@@ -34,12 +35,8 @@
   int status;
 } REGEX_CACHE_BLOCK;
 
-
-#if CRM_REGEX_CACHESIZE > 0 
-
  REGEX_CACHE_BLOCK regex_cache[CRM_REGEX_CACHESIZE]
    = { { NULL, NULL, 0, 0, 0} } ;
-
 #endif
 
  
@@ -79,55 +76,66 @@
   //   We are cacheing.  Scan our cache set for the compiled versions
   //   of this regex.  Note that a length of 0 means "empty bucket".
   {
-    int i, j, found_it;
-    long rtsize = sizeof (regex_t);
+    int i;
+    int found_it = CRM_REGEX_CACHESIZE;
+    int rtsize = sizeof (regex_t);
     regex_t *ppreg_temp = NULL;
     char *regex_temp = NULL;
-    long rlen_temp = 0;
+    int rlen_temp = 0;
     int cflags_temp = 0;
     int status_temp = 0;
 
-    if (internal_trace) fprintf (stderr, "Checking the regex cache for %s\n",
-				 regex);
-    j = 0;
+    
+    if (internal_trace)
+    {
+      fprintf (stderr, "Checking the regex cache for '%s'\n", regex);
+      for (i=0; i < CRM_REGEX_CACHESIZE; i++) {
+	if (regex_cache[i].regex_len > 0) fprintf (stderr, 
+	  "  regex[%d]:'%s' cf=%#x(%#x) len=%d(%d)\n",
+	  i,regex_cache[i].regex,regex_cache[i].cflags,cflags,
+	  regex_cache[i].regex_len,regex_len);
+      }
 #ifdef REGEX_CACHE_LINEAR_SEARCH
+      fputs (" [<- rex cache linear]\n", stderr);
+    }
+    i=0;
     //
     //          Linear Search uses a strict LRU algorithm to cache
     //          the precompiled regexes.
     //
-    found_it = 0;
-    i = -1;
-    while (!found_it && i < CRM_REGEX_CACHESIZE)
+    while (i < CRM_REGEX_CACHESIZE)
       {
-	i++;
 	if (regex_len == regex_cache[i].regex_len
 	    && cflags == regex_cache[i].cflags
 	    && strncmp (regex_cache[i].regex, regex, regex_len) == 0)
 	  {
 	    //  We Found It!   Put it into the _temp vars...
-	    if (internal_trace) fprintf (stderr, "found it.\n");
 	    ppreg_temp  = regex_cache[i].preg;
 	    regex_temp  = regex_cache[i].regex;
 	    rlen_temp   = regex_len;
 	    cflags_temp = cflags;
 	    status_temp = regex_cache[i].status;
 	    found_it = i;
+	    break;
 	  };
+	i++;
       };
-#endif
+    if (internal_trace)
+    {
+#else
 #ifdef REGEX_CACHE_RANDOM_ACCESS
+      fputs (" [<- rex cache random]\n", stderr);
+    }
     //
     //             Random Access uses an associative cache based on 
     //             the hash of the regex (mod the size of the cache).
     //
-    found_it = 0;
     i = strnhash (regex, regex_len) % CRM_REGEX_CACHESIZE;
     if (regex_len == regex_cache[i].regex_len
 	&& cflags == regex_cache[i].cflags
 	&& strncmp (regex_cache[i].regex, regex, regex_len) == 0)
       {
 	//  We Found It!   Put it into the _temp vars...
-	if (internal_trace) fprintf (stderr, "found it.\n");
 	ppreg_temp  = regex_cache[i].preg;
 	regex_temp  = regex_cache[i].regex;
 	rlen_temp   = regex_len;
@@ -135,23 +143,32 @@
 	status_temp = regex_cache[i].status;
 	found_it = i;
       };
-#endif
+    if (internal_trace)
+    {
+      fprintf (stderr, 
+        "  strnhash (regex, regex_len) %% %d = %d\n", CRM_REGEX_CACHESIZE, i);
+#endif //REGEX_CACHE_RANDOM_ACCESS
+#endif //REGEX_CACHE_LINEAR_SEARCH
     
+      if (found_it == CRM_REGEX_CACHESIZE)
+	  fprintf (stderr, "couldn't find it\n");
+      else
+	  fprintf (stderr, "found it at [%d].\n",i);
+    }
     //    note that on exit, i now is the index where we EITHER found
     //     the good data, or failed to do so, and found_it tells us which.
     //
-    if ( ! (found_it))
+    if (found_it == CRM_REGEX_CACHESIZE)
       {    
 	//  We didn't find it.  Do the compilation instead, putting
 	//   the results into the _temp vars.
-	if (internal_trace) fprintf (stderr, "couldn't find it\n");
-	regex_temp = (char *) malloc (regex_len + 1);
+	regex_temp = (char *) calloc ((size_t) regex_len + 1, sizeof(char));
 	memcpy (regex_temp, regex, regex_len);
 	rlen_temp = regex_len;
 	cflags_temp = cflags;
 	if (internal_trace) 
-	  fprintf (stderr, "Compiling %s (len %ld).\n", regex_temp, rlen_temp);
-	ppreg_temp = (regex_t *) malloc (rtsize);
+	  fprintf (stderr, "Compiling '%s' (len %d).\n", regex_temp, rlen_temp);
+	ppreg_temp = (regex_t *) calloc (1, rtsize);
 	if (ppreg_temp == NULL) 
 	  fatalerror5 
 	    ("Unable to allocate a pattern register buffer header.  ",
@@ -162,25 +179,19 @@
 	//  We will always stuff the _temps in at 0
 	//   and pretend that this was at the last index, so it
 	//    moves everything else further down the list.
-	i = CRM_REGEX_CACHESIZE - 1;
-      };
-	
-    //   Either way, at this point, the _temp vars contain the new and
-    //    correct regex information; this information has vacated the slot
-    //     at index i, 
-
 
+	if (internal_trace)
 #ifdef REGEX_CACHE_LINEAR_SEARCH
-    //   If we're in linear search, we move 0 through i-1 down to 1
-    //   through i and then we stuff the _temp vars into the [i] cache
-    //   area.  Note that if it was the final slot (at
-    //   CRM_REGEX_CACHESIZE), we have to free the resources up or
-    //   we'll leak them.
-    //
-    //                           Free the resources first, if needed.
-    //
-    if (i == CRM_REGEX_CACHESIZE - 1)
-      {
+	  fputs (" [-> rex cache linear]\n", stderr);
+        //   If we're in linear search, we move 0 through i-1 down to 1
+        //   through i and then we stuff the _temp vars into the [i] cache
+        //   area.  Note that if it was the final slot (at
+        //   CRM_REGEX_CACHESIZE), we have to free the resources up or
+        //   we'll leak them.
+        //
+        //   Free the resources first, if needed.
+        //
+	i = CRM_REGEX_CACHESIZE - 1;
 	if (regex_cache[i].preg != NULL) 
 	  {
 	    regfree (regex_cache[i].preg);
@@ -189,41 +200,34 @@
 	if (regex_cache[i].regex != NULL) free (regex_cache[i].regex);
 	regex_cache[i].regex = NULL;
 	regex_cache[i].regex_len = 0;
-      };
-	  
 
-    //       If needed, slide 0 through i-1 down to 1..i, to make room
-    //       at [0]
-    //
-    if (i != 0)
-      {
-	for (j = i; j > 0; j--)
+	//       If needed, slide 0 through i-1 down to 1..i, to make room
+	//       at [0]
+	//
+	if (i != 0)
 	  {
-	    regex_cache[j].preg      = regex_cache[j-1].preg;
-	    regex_cache[j].regex     = regex_cache[j-1].regex;
-	    regex_cache[j].regex_len = regex_cache[j-1].regex_len;
-	    regex_cache[j].cflags    = regex_cache[j-1].cflags;
-	    regex_cache[j].status    = regex_cache[j-1].status;
-	  };
-      };
-
-    //   and always stuff the _temps (which are correct) in at [0]
-    regex_cache[0].preg      = ppreg_temp;
-    regex_cache[0].regex     = regex_temp;
-    regex_cache[0].regex_len = rlen_temp;
-    regex_cache[0].status    = status_temp;
-    regex_cache[0].cflags    = cflags_temp;
-#endif
+	    int j;
+	    for (j = i; j > 0; j--)
+	      {
+		regex_cache[j].preg      = regex_cache[j-1].preg;
+		regex_cache[j].regex     = regex_cache[j-1].regex;
+		regex_cache[j].regex_len = regex_cache[j-1].regex_len;
+		regex_cache[j].cflags    = regex_cache[j-1].cflags;
+		regex_cache[j].status    = regex_cache[j-1].status;
+	      };
+	    i=0;
+          };
 
+	//   and always stuff the _temps (which are correct) in at [0]
+#else
 #ifdef REGEX_CACHE_RANDOM_ACCESS
-    //
-    //      In a random access system, we just overwrite the single
-    //      slot that we expected our regex to be in...
-
-    //                           Free the resources first, if needed.
-    //
-    if (! found_it)
-      {
+	  fputs (" [-> rex cache random]\n", stderr);
+	//
+	//      In a random access system, we just overwrite the single
+	//      slot that we expected our regex to be in...
+	//
+	//      Free the resources first, if needed.
+	//
         if (regex_cache[i].preg != NULL)
           {
             regfree (regex_cache[i].preg);
@@ -232,25 +236,27 @@
         if (regex_cache[i].regex != NULL) free (regex_cache[i].regex);
         regex_cache[i].regex = NULL;
         regex_cache[i].regex_len = 0;
-      };
-
-    //   and  stuff the _temps (which are correct) in at [i]
-    regex_cache[i].preg      = ppreg_temp;
-    regex_cache[i].regex     = regex_temp;
-    regex_cache[i].regex_len = rlen_temp;
-    regex_cache[i].status    = status_temp;
-    regex_cache[i].cflags    = cflags_temp;
-
-#endif
 
+	//   and  stuff the _temps (which are correct) in at [i]
+#endif //REGEX_CACHE_RANDOM_ACCESS
+#endif //REGEX_CACHE_LINEAR_SEARCH
+	regex_cache[i].preg      = ppreg_temp;
+	regex_cache[i].regex     = regex_temp;
+	regex_cache[i].regex_len = rlen_temp;
+	regex_cache[i].status    = status_temp;
+	regex_cache[i].cflags    = cflags_temp;
+      };
     //  Just about done.  Set up the return preg..
-    if (internal_trace) 
-      fprintf (stderr, " About to return\n");
     memcpy (preg, ppreg_temp, rtsize);
-    return (regex_cache[i].status);    
+    if (internal_trace)
+      fprintf (stderr, " About to return:\n"
+        " preg->re_nsub=%d preg->value=%#x, i=%d, status=%d\n",
+        (int)preg->re_nsub, (int)preg->value, i, regex_cache[i].status);
+    return (regex_cache[i].status);
   };
-#endif
+#endif //CRM_REGEX_CACHESIZE == 0
 }
+
 //
 //
 //       How to do a regex execution from the compiled register
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.