[BACK]Return to regcomp.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / regex

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/regex/regcomp.c between version 1.29 and 1.30

version 1.29, 2009/02/12 05:06:54 version 1.30, 2011/10/09 18:23:00
Line 125  extern "C" {
Line 125  extern "C" {
 #endif  #endif
   
 /* === regcomp.c === */  /* === regcomp.c === */
 static void p_ere(struct parse *p, int stop);  static void p_ere(struct parse *p, int stop, size_t reclimit);
 static void p_ere_exp(struct parse *p);  static void p_ere_exp(struct parse *p, size_t reclimit);
 static void p_str(struct parse *p);  static void p_str(struct parse *p);
 static void p_bre(struct parse *p, int end1, int end2);  static void p_bre(struct parse *p, int end1, int end2, size_t reclimit);
 static int p_simp_re(struct parse *p, int starordinary);  static int p_simp_re(struct parse *p, int starordinary, size_t reclimit);
 static int p_count(struct parse *p);  static int p_count(struct parse *p);
 static void p_bracket(struct parse *p);  static void p_bracket(struct parse *p);
 static void p_b_term(struct parse *p, cset *cs);  static void p_b_term(struct parse *p, cset *cs);
Line 141  static int othercase(int ch);
Line 141  static int othercase(int ch);
 static void bothcases(struct parse *p, int ch);  static void bothcases(struct parse *p, int ch);
 static void ordinary(struct parse *p, int ch);  static void ordinary(struct parse *p, int ch);
 static void nonnewline(struct parse *p);  static void nonnewline(struct parse *p);
 static void repeat(struct parse *p, sopno start, int from, int to);  static void repeat(struct parse *p, sopno start, int from, int to, size_t reclimit);
 static int seterr(struct parse *p, int e);  static int seterr(struct parse *p, int e);
 static cset *allocset(struct parse *p);  static cset *allocset(struct parse *p);
 static void freeset(struct parse *p, cset *cs);  static void freeset(struct parse *p, cset *cs);
Line 163  static sopno dupl(struct parse *p, sopno
Line 163  static sopno dupl(struct parse *p, sopno
 static void doemit(struct parse *p, sop op, sopno opnd);  static void doemit(struct parse *p, sop op, sopno opnd);
 static void doinsert(struct parse *p, sop op, sopno opnd, sopno pos);  static void doinsert(struct parse *p, sop op, sopno opnd, sopno pos);
 static void dofwd(struct parse *p, sopno pos, sopno value);  static void dofwd(struct parse *p, sopno pos, sopno value);
 static void enlarge(struct parse *p, sopno size);  static int enlarge(struct parse *p, sopno size);
 static void stripsnug(struct parse *p, struct re_guts *g);  static void stripsnug(struct parse *p, struct re_guts *g);
 static void findmust(struct parse *p, struct re_guts *g);  static void findmust(struct parse *p, struct re_guts *g);
 static sopno pluscount(struct parse *p, struct re_guts *g);  static sopno pluscount(struct parse *p, struct re_guts *g);
Line 211  static int never = 0;  /* for use in ass
Line 211  static int never = 0;  /* for use in ass
 #define never   0               /* some <assert.h>s have bugs too */  #define never   0               /* some <assert.h>s have bugs too */
 #endif  #endif
   
   #define MEMLIMIT        0x8000000
   #define MEMSIZE(p) \
           ((p)->ncsalloc / CHAR_BIT * (p)->g->csetsize + \
           (p)->ncsalloc * sizeof(cset) + \
           (p)->ssize * sizeof(sop))
   #define RECLIMIT        256
   
 /*  /*
  - regcomp - interface for parser and compilation   - regcomp - interface for parser and compilation
  = extern int regcomp(regex_t *, const char *, int);   = extern int regcomp(regex_t *, const char *, int);
Line 260  regcomp(
Line 267  regcomp(
         if (g == NULL)          if (g == NULL)
                 return(REG_ESPACE);                  return(REG_ESPACE);
         p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */          p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
         p->strip = (sop *)malloc(p->ssize * sizeof(sop));          p->strip = malloc(p->ssize * sizeof(sop));
         p->slen = 0;          p->slen = 0;
         if (p->strip == NULL) {          if (p->strip == NULL) {
                 free(g);                  free(g);
Line 297  regcomp(
Line 304  regcomp(
         EMIT(OEND, 0);          EMIT(OEND, 0);
         g->firststate = THERE();          g->firststate = THERE();
         if (cflags&REG_EXTENDED)          if (cflags&REG_EXTENDED)
                 p_ere(p, OUT);                  p_ere(p, OUT, 0);
         else if (cflags&REG_NOSPEC)          else if (cflags&REG_NOSPEC)
                 p_str(p);                  p_str(p);
         else          else
                 p_bre(p, OUT, OUT);                  p_bre(p, OUT, OUT, 0);
         EMIT(OEND, 0);          EMIT(OEND, 0);
         g->laststate = THERE();          g->laststate = THERE();
   
Line 328  regcomp(
Line 335  regcomp(
   
 /*  /*
  - p_ere - ERE parser top level, concatenation and alternation   - p_ere - ERE parser top level, concatenation and alternation
  == static void p_ere(struct parse *p, int stop);   == static void p_ere(struct parse *p, int stop, size_t reclimit);
  */   */
 static void  static void
 p_ere(  p_ere(
     struct parse *p,      struct parse *p,
     int stop)                   /* character this ERE should end at */      int stop,                   /* character this ERE should end at */
       size_t reclimit)
 {  {
         char c;          char c;
         sopno prevback = 0;     /* pacify gcc */          sopno prevback = 0;     /* pacify gcc */
Line 343  p_ere(
Line 351  p_ere(
   
         _DIAGASSERT(p != NULL);          _DIAGASSERT(p != NULL);
   
           if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) {
                   p->error = REG_ESPACE;
                   return;
           }
   
         for (;;) {          for (;;) {
                 /* do a bunch of concatenated expressions */                  /* do a bunch of concatenated expressions */
                 conc = HERE();                  conc = HERE();
                 while (MORE() && (c = PEEK()) != '|' && c != stop)                  while (MORE() && (c = PEEK()) != '|' && c != stop)
                         p_ere_exp(p);                          p_ere_exp(p, reclimit);
                 REQUIRE(HERE() != conc, REG_EMPTY);     /* require nonempty */                  REQUIRE(HERE() != conc, REG_EMPTY);     /* require nonempty */
   
                 if (!EAT('|'))                  if (!EAT('|'))
Line 376  p_ere(
Line 389  p_ere(
   
 /*  /*
  - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op   - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
  == static void p_ere_exp(struct parse *p);   == static void p_ere_exp(struct parse *p, size_t reclimit);
  */   */
 static void  static void
 p_ere_exp(  p_ere_exp(
     struct parse *p)      struct parse *p,
       size_t reclimit)
 {  {
         char c;          char c;
         sopno pos;          sopno pos;
Line 404  p_ere_exp(
Line 418  p_ere_exp(
                         p->pbegin[subno] = HERE();                          p->pbegin[subno] = HERE();
                 EMIT(OLPAREN, subno);                  EMIT(OLPAREN, subno);
                 if (!SEE(')'))                  if (!SEE(')'))
                         p_ere(p, ')');                          p_ere(p, ')', reclimit);
                 if (subno < NPAREN) {                  if (subno < NPAREN) {
                         p->pend[subno] = HERE();                          p->pend[subno] = HERE();
                         assert(p->pend[subno] != 0);                          assert(p->pend[subno] != 0);
Line 506  p_ere_exp(
Line 520  p_ere_exp(
                                 count2 = INFINITY;                                  count2 = INFINITY;
                 } else          /* just a single number */                  } else          /* just a single number */
                         count2 = count;                          count2 = count;
                 repeat(p, pos, count, count2);                  repeat(p, pos, count, count2, 0);
                 if (!EAT('}')) {        /* error heuristics */                  if (!EAT('}')) {        /* error heuristics */
                         while (MORE() && PEEK() != '}')                          while (MORE() && PEEK() != '}')
                                 NEXT();                                  NEXT();
Line 544  p_str(
Line 558  p_str(
 /*  /*
  - p_bre - BRE parser top level, anchoring and concatenation   - p_bre - BRE parser top level, anchoring and concatenation
  == static void p_bre(struct parse *p, int end1, \   == static void p_bre(struct parse *p, int end1, \
  ==     int end2);   ==     int end2, size_t reclimit);
  * Giving end1 as OUT essentially eliminates the end1/end2 check.   * Giving end1 as OUT essentially eliminates the end1/end2 check.
  *   *
  * This implementation is a bit of a kludge, in that a trailing $ is first   * This implementation is a bit of a kludge, in that a trailing $ is first
Line 557  static void
Line 571  static void
 p_bre(  p_bre(
     struct parse *p,      struct parse *p,
     int end1,           /* first terminating character */      int end1,           /* first terminating character */
     int end2)           /* second terminating character */      int end2,           /* second terminating character */
       size_t reclimit)
 {  {
         sopno start;          sopno start;
         int first = 1;                  /* first subexpression? */          int first = 1;                  /* first subexpression? */
Line 565  p_bre(
Line 580  p_bre(
   
         _DIAGASSERT(p != NULL);          _DIAGASSERT(p != NULL);
   
           if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) {
                   p->error = REG_ESPACE;
                   return;
           }
   
         start = HERE();          start = HERE();
   
         if (EAT('^')) {          if (EAT('^')) {
Line 573  p_bre(
Line 593  p_bre(
                 p->g->nbol++;                  p->g->nbol++;
         }          }
         while (MORE() && !SEETWO(end1, end2)) {          while (MORE() && !SEETWO(end1, end2)) {
                 wasdollar = p_simp_re(p, first);                  wasdollar = p_simp_re(p, first, reclimit);
                 first = 0;                  first = 0;
         }          }
         if (wasdollar) {        /* oops, that was a trailing anchor */          if (wasdollar) {        /* oops, that was a trailing anchor */
Line 588  p_bre(
Line 608  p_bre(
   
 /*  /*
  - p_simp_re - parse a simple RE, an atom possibly followed by a repetition   - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
  == static int p_simp_re(struct parse *p, int starordinary);   == static int p_simp_re(struct parse *p, int starordinary, size_t reclimit);
  */   */
 static int                      /* was the simple RE an unbackslashed $? */  static int                      /* was the simple RE an unbackslashed $? */
 p_simp_re(  p_simp_re(
     struct parse *p,      struct parse *p,
     int starordinary)           /* is a leading * an ordinary character? */      int starordinary,           /* is a leading * an ordinary character? */
       size_t reclimit)
 {  {
         int c;          int c;
         int count;          int count;
Line 634  p_simp_re(
Line 655  p_simp_re(
                 EMIT(OLPAREN, subno);                  EMIT(OLPAREN, subno);
                 /* the MORE here is an error heuristic */                  /* the MORE here is an error heuristic */
                 if (MORE() && !SEETWO('\\', ')'))                  if (MORE() && !SEETWO('\\', ')'))
                         p_bre(p, '\\', ')');                          p_bre(p, '\\', ')', reclimit);
                 if (subno < NPAREN) {                  if (subno < NPAREN) {
                         p->pend[subno] = HERE();                          p->pend[subno] = HERE();
                         assert(p->pend[subno] != 0);                          assert(p->pend[subno] != 0);
Line 693  p_simp_re(
Line 714  p_simp_re(
                                 count2 = INFINITY;                                  count2 = INFINITY;
                 } else          /* just a single number */                  } else          /* just a single number */
                         count2 = count;                          count2 = count;
                 repeat(p, pos, count, count2);                  repeat(p, pos, count, count2, 0);
                 if (!EATTWO('\\', '}')) {       /* error heuristics */                  if (!EATTWO('\\', '}')) {       /* error heuristics */
                         while (MORE() && !SEETWO('\\', '}'))                          while (MORE() && !SEETWO('\\', '}'))
                                 NEXT();                                  NEXT();
Line 745  p_bracket(
Line 766  p_bracket(
         _DIAGASSERT(p != NULL);          _DIAGASSERT(p != NULL);
   
         cs = allocset(p);          cs = allocset(p);
           if (cs == NULL)
                   return;
   
         /* Dept of Truly Sickening Special-Case Kludges */          /* Dept of Truly Sickening Special-Case Kludges */
         if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]",          if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]",
Line 1101  nonnewline(
Line 1124  nonnewline(
   
 /*  /*
  - repeat - generate code for a bounded repetition, recursively if needed   - repeat - generate code for a bounded repetition, recursively if needed
  == static void repeat(struct parse *p, sopno start, int from, int to);   == static void repeat(struct parse *p, sopno start, int from, int to,
    == size_t reclimit);
  */   */
 static void  static void
 repeat(  repeat(
     struct parse *p,      struct parse *p,
     sopno start,                /* operand from here to end of strip */      sopno start,                /* operand from here to end of strip */
     int from,                   /* repeated from this number */      int from,                   /* repeated from this number */
     int to)                     /* to this number of times (maybe INFINITY) */      int to,                     /* to this number of times (maybe INFINITY) */
       size_t reclimit)
 {  {
         sopno finish;          sopno finish;
 #       define  N       2  #       define  N       2
Line 1119  repeat(
Line 1144  repeat(
   
         _DIAGASSERT(p != NULL);          _DIAGASSERT(p != NULL);
   
         finish = HERE();          if (reclimit++ > RECLIMIT)
                   p->error = REG_ESPACE;
         if (p->error != 0)      /* head off possible runaway recursion */          if (p->error)
                 return;                  return;
   
           finish = HERE();
   
         assert(from <= to);          assert(from <= to);
   
         switch (REP(MAP(from), MAP(to))) {          switch (REP(MAP(from), MAP(to))) {
Line 1135  repeat(
Line 1162  repeat(
         case REP(0, INF):               /* as x{1,}? */          case REP(0, INF):               /* as x{1,}? */
                 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */                  /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
                 INSERT(OCH_, start);            /* offset is wrong... */                  INSERT(OCH_, start);            /* offset is wrong... */
                 repeat(p, start+1, 1, to);                  repeat(p, start+1, 1, to, reclimit);
                 ASTERN(OOR1, start);                  ASTERN(OOR1, start);
                 AHEAD(start);                   /* ... fix it */                  AHEAD(start);                   /* ... fix it */
                 EMIT(OOR2, 0);                  EMIT(OOR2, 0);
Line 1155  repeat(
Line 1182  repeat(
                 ASTERN(O_CH, THERETHERE());                  ASTERN(O_CH, THERETHERE());
                 copy = dupl(p, start+1, finish+1);                  copy = dupl(p, start+1, finish+1);
                 assert(copy == finish+4);                  assert(copy == finish+4);
                 repeat(p, copy, 1, to-1);                  repeat(p, copy, 1, to-1, reclimit);
                 break;                  break;
         case REP(1, INF):               /* as x+ */          case REP(1, INF):               /* as x+ */
                 INSERT(OPLUS_, start);                  INSERT(OPLUS_, start);
Line 1163  repeat(
Line 1190  repeat(
                 break;                  break;
         case REP(N, N):                 /* as xx{m-1,n-1} */          case REP(N, N):                 /* as xx{m-1,n-1} */
                 copy = dupl(p, start, finish);                  copy = dupl(p, start, finish);
                 repeat(p, copy, from-1, to-1);                  repeat(p, copy, from-1, to-1, reclimit);
                 break;                  break;
         case REP(N, INF):               /* as xx{n-1,INF} */          case REP(N, INF):               /* as xx{n-1,INF} */
                 copy = dupl(p, start, finish);                  copy = dupl(p, start, finish);
                 repeat(p, copy, from-1, to);                  repeat(p, copy, from-1, to, reclimit);
                 break;                  break;
         default:                        /* "can't happen" */          default:                        /* "can't happen" */
                 SETERROR(REG_ASSERT);   /* just in case */                  SETERROR(REG_ASSERT);   /* just in case */
Line 1218  allocset(
Line 1245  allocset(
                 nc = p->ncsalloc;                  nc = p->ncsalloc;
                 assert(nc % CHAR_BIT == 0);                  assert(nc % CHAR_BIT == 0);
                 nbytes = nc / CHAR_BIT * css;                  nbytes = nc / CHAR_BIT * css;
                   if (MEMSIZE(p) > MEMLIMIT)
                           goto oomem;
                 if (p->g->sets == NULL)                  if (p->g->sets == NULL)
                         p->g->sets = malloc(nc * sizeof(cset));                          p->g->sets = malloc(nc * sizeof(cset));
                 else                  else
Line 1234  allocset(
Line 1263  allocset(
                         (void) memset((char *)p->g->setbits + (nbytes - css),                          (void) memset((char *)p->g->setbits + (nbytes - css),
                                                                 0, css);                                                                  0, css);
                 else {                  else {
   oomem:
                         no = 0;                          no = 0;
                         SETERROR(REG_ESPACE);                          SETERROR(REG_ESPACE);
                         /* caller's responsibility not to do set ops */                          /* caller's responsibility not to do set ops */
                           return NULL;
                 }                  }
         }          }
   
         assert(p->g->sets != NULL);     /* xxx */  
         cs = &p->g->sets[no];          cs = &p->g->sets[no];
         cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);          cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
         cs->mask = 1 << ((no) % CHAR_BIT);          cs->mask = 1 << ((no) % CHAR_BIT);
Line 1620  dupl(
Line 1650  dupl(
         assert(finish >= start);          assert(finish >= start);
         if (len == 0)          if (len == 0)
                 return(ret);                  return(ret);
         enlarge(p, p->ssize + len);     /* this many unexpected additions */          if (!enlarge(p, p->ssize + len))/* this many unexpected additions */
         assert(p->ssize >= p->slen + len);                  return ret;
         (void)memcpy(p->strip + p->slen, p->strip + start,          (void)memcpy(p->strip + p->slen, p->strip + start,
             (size_t)len * sizeof(sop));              (size_t)len * sizeof(sop));
         p->slen += len;          p->slen += len;
Line 1654  doemit(
Line 1684  doemit(
   
         /* deal with undersized strip */          /* deal with undersized strip */
         if (p->slen >= p->ssize)          if (p->slen >= p->ssize)
                 enlarge(p, (p->ssize+1) / 2 * 3);       /* +50% */                  if (!enlarge(p, (p->ssize+1) / 2 * 3))  /* +50% */
         assert(p->slen < p->ssize);                          return;
   
         /* finally, it's all reduced to the easy case */          /* finally, it's all reduced to the easy case */
         p->strip[p->slen++] = SOP(op, opnd);          p->strip[p->slen++] = SOP(op, opnd);
Line 1727  dofwd(
Line 1757  dofwd(
  - enlarge - enlarge the strip   - enlarge - enlarge the strip
  == static void enlarge(struct parse *p, sopno size);   == static void enlarge(struct parse *p, sopno size);
  */   */
 static void  static int
 enlarge(  enlarge(
     struct parse *p,      struct parse *p,
     sopno size)      sopno size)
 {  {
         sop *sp;          sop *sp;
           sopno osize;
   
         _DIAGASSERT(p != NULL);          _DIAGASSERT(p != NULL);
   
         if (p->ssize >= size)          if (p->ssize >= size)
                 return;                  return 1;
   
         sp = (sop *)realloc(p->strip, size*sizeof(sop));          osize = p->ssize;
           p->ssize = size;
           if (MEMSIZE(p) > MEMLIMIT)
                   goto oomem;
           sp = realloc(p->strip, p->ssize * sizeof(sop));
         if (sp == NULL) {          if (sp == NULL) {
   oomem:
                   p->ssize = osize;
                 SETERROR(REG_ESPACE);                  SETERROR(REG_ESPACE);
                 return;                  return 0;
         }          }
         p->strip = sp;          p->strip = sp;
         p->ssize = size;          return 1;
 }  }
   
 /*  /*

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

CVSweb <webmaster@jp.NetBSD.org>