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