Re: Strange segfault with improper usage

Paolo <[email protected]>
Newsgroups gmane.mail.spam.crm114
Message-ID <20080326145226.GM20978@localhost>
On Wed, Mar 26, 2008 at 02:46:52PM +0100, Ger Hobbelt wrote:
> @Paolo,
> 
> Could you please provide a snapshot of the files patched to fix this
> somewhere (CVS? other?).

it's only that crmregex_tre.c; the patch should apply cleanly against 
20080317-BlameJoeLangeway_VT which was in sf.net/src/.
Anyway, the patched crmregex_tre.c is attached.

I did have other hacks in my local w.dir, but on Milan's machine I finally
set for just that change.

-- 
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 (text/x-csrc, 9.6 KB)
//       CRM114 Regex redirection bounce package this file bounces
//       CRM114 regex requests to whichever regex package has been
//       compiled and linked in to CRM114.  
//
//       Adding a new regex package is relatively easy- just mimic the
//       ifdef stanzas below to map the functions 
// 
//         crm_regcomp
//         crm_regexec
//         crm_regerror
//         crm_regfree
//         crm_regversion
//
//      into whatever calls your preferred regex package uses.   
//
#include "crm114_sysincludes.h"
char * tre_version (void);
//
//  include any local crm114 configuration file
#include "crm114_config.h"

//  include the crm114 data structures file
#include "crm114_structs.h"

//  and include the routine declarations file
#include "crm114.h"

#if CRM_REGEX_CACHESIZE > 0 
//  Cache for regex compilations
typedef struct {
  char *regex;
  regex_t *preg;   // ptr to struct of {long, void*}
  long regex_len;
  int cflags;
  int status;
} REGEX_CACHE_BLOCK;

 REGEX_CACHE_BLOCK regex_cache[CRM_REGEX_CACHESIZE]
   = { { NULL, NULL, 0, 0, 0} } ;
#endif

 
//
//      How to do a register compilation
//
int crm_regcomp (regex_t *preg, char *regex, long regex_len, int cflags)
{
  //       compile it with the TRE regex compiler
  //
  //    bug workaround - many regex compilers don't compile the null
  //    regex correctly, but _do_ compile "()" correctly, which
  //    matches the same thing).
  if (regex_len == 0) 
    {
      return (regncomp (preg, "()", 2, cflags));
    };

  //   Are we cacheing compiled regexes?  Maybe not...
#if CRM_REGEX_CACHESIZE == 0
  if (internal_trace)
  {
    int i;
    fprintf (stderr, "\ncompiling regex '%s', len %ld, in hex: ", 
  	   regex, regex_len);
    for (i = 0; i < regex_len; i++)
      {
	fprintf (stderr, "%2X", regex[i]);
      };
    fprintf (stderr, "\n");
  }

  return ( regncomp (preg, regex, regex_len, cflags));

#else

  //   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;
    int found_it = CRM_REGEX_CACHESIZE;
    int rtsize = sizeof (regex_t);
    regex_t *ppreg_temp = NULL;
    char *regex_temp = NULL;
    int rlen_temp = 0;
    int cflags_temp = 0;
    int status_temp = 0;

    i=j=0;
    if (internal_trace)
    {
      fprintf (stderr, "Checking the regex cache for '%s'\n", regex);
      for (j=0; j < CRM_REGEX_CACHESIZE; j++) {
	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);
    }
    //
    //          Linear Search uses a strict LRU algorithm to cache
    //          the precompiled regexes.
    //
    while (i < 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...
	    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++;
      };
    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).
    //
    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...
	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;
      };
    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 == CRM_REGEX_CACHESIZE)
      {    
	//  We didn't find it.  Do the compilation instead, putting
	//   the results into the _temp vars.
	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 %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.  ",
	     "This is hopeless.  ", CRM_ENGINE_HERE);
	status_temp =
	  regncomp (ppreg_temp, regex_temp, rlen_temp, cflags_temp);
	
	//  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.

	if (internal_trace)
#ifdef REGEX_CACHE_LINEAR_SEARCH
	  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);
	    free (regex_cache[i].preg);
	  };
	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--)
	      {
		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
	  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);
            free (regex_cache[i].preg);
          };
        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]
#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..
    memcpy (preg, ppreg_temp, rtsize);
    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 //CRM_REGEX_CACHESIZE == 0
}

//
//
//       How to do a regex execution from the compiled register
//
int crm_regexec ( regex_t *preg, char *string, long string_len,
		 size_t nmatch, regmatch_t pmatch[], int eflags, 
		  char *aux_string)
{
  if (!string)
    {
      nonfatalerror5("crm_regexec - Regular Expression Execution Problem:\n",
		     "NULL pointer to the string to match .", CRM_ENGINE_HERE);
      return (REG_NOMATCH);
    };
  if (aux_string == NULL
      || strlen (aux_string) < 1)
    {
      return (regnexec (preg, string, string_len, nmatch, pmatch, eflags));
    }
  else
    {
      int i;
      //  parse out the aux string for approximation parameters
      regamatch_t mblock; 
      regaparams_t pblock;
      mblock.nmatch = nmatch;
      mblock.pmatch = pmatch;
      sscanf (aux_string, "%d %d %d %d", 
	      &pblock.cost_subst,
	      &pblock.cost_ins,
	      &pblock.max_cost,
	      &pblock.cost_del);
      if (user_trace)
	fprintf (stderr,
	 "Using approximate match.  Costs: Subst %d Ins %d Max %d Del %d \n",
		 pblock.cost_subst,
		 pblock.cost_ins,
		 pblock.max_cost,
		 pblock.cost_del);
      
      //  now we can run the actual match
      i = reganexec (preg, string, string_len, &mblock, pblock, eflags);
      if (user_trace)
	fprintf (stderr, "approximate Regex match returned %d .\n", i);
      return (i);
    };
}


size_t crm_regerror (int errorcode, regex_t *preg, char *errbuf,
		     size_t errbuf_size)

{
  return (regerror (errorcode, preg, errbuf, errbuf_size));
};

void crm_regfree (regex_t *preg)
{
#if CRM_REGEX_CACHESIZE > 0 
  //  nothing!  yes indeed, if we are using cacheing, we don't free 
  //  till and unless we decache, so crm_regfree is a noop.
  return;
#else
   return (regfree (preg));
#endif
};

char * crm_regversion ()
{
  static char vs[129];
  strcat (vs, (char *) tre_version ());
  return (vs);
};
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.