[Python-checkins] python/dist/src/Modules _sre.c,2.90,2.91

niemeyer@users.sourceforge.net niemeyer@users.sourceforge.net
Sun, 20 Apr 2003 00:35:46 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv16123/Modules

Modified Files:
	_sre.c 
Log Message:
More work on bug #672491 and patch #712900.

I've applied a modified version of Greg Chapman's patch. I've included
the fixes without introducing the reorganization mentioned, for the sake
of stability. Also, the second fix mentioned in the patch don't fix the
mentioned problem anymore, because of the change introduced by patch
#720991 (by Greg as well). The new fix wasn't complicated though, and is
included as well.

As a note. It seems that there are other places that require the
"protection" of LASTMARK_SAVE()/LASTMARK_RESTORE(), and are just waiting
for someone to find how to break them. Particularly, I belive that every
recursion of SRE_MATCH() should be protected by these macros. I won't
do that right now since I'm not completely sure about this, and we don't
have much time for testing until the next release.


Index: _sre.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v
retrieving revision 2.90
retrieving revision 2.91
diff -C2 -d -r2.90 -r2.91
*** _sre.c	20 Apr 2003 00:45:13 -0000	2.90
--- _sre.c	20 Apr 2003 07:35:44 -0000	2.91
***************
*** 338,354 ****
  }
  
- static void
- lastmark_restore(SRE_STATE *state, int lastmark)
- {
-     if (state->lastmark > lastmark) {
-         memset(
-             state->mark + lastmark + 1, 0,
-             (state->lastmark - lastmark) * sizeof(void*)
-             );
-         state->lastmark = lastmark;
-         state->lastindex = (lastmark == 0) ? -1 : (lastmark-1)/2+1;
-     }
- }
- 
  /* generate 8-bit version */
  
--- 338,341 ----
***************
*** 691,694 ****
--- 678,697 ----
  #endif
  
+ /* macros to preserve lastmark in case of backtracking */
+ #define LASTMARK_SAVE()     \
+     do { \
+         lastmark = state->lastmark; \
+         lastindex = state->lastindex; \
+     } while (0)
+ #define LASTMARK_RESTORE()  \
+     do { \
+         if (state->lastmark > lastmark) { \
+             memset(state->mark + lastmark + 1, 0, \
+                    (state->lastmark - lastmark) * sizeof(void*)); \
+             state->lastmark = lastmark; \
+             state->lastindex = lastindex; \
+         } \
+     } while (0)
+ 
  LOCAL(int)
  SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
***************
*** 701,705 ****
      int i, count;
      SRE_REPEAT* rp;
!     int lastmark;
      SRE_CODE chr;
  
--- 704,708 ----
      int i, count;
      SRE_REPEAT* rp;
!     int lastmark, lastindex;
      SRE_CODE chr;
  
***************
*** 928,932 ****
              /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
              TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
!             lastmark = state->lastmark;
              for (; pattern[0]; pattern += pattern[0]) {
                  if (pattern[1] == SRE_OP_LITERAL &&
--- 931,935 ----
              /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
              TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
!             LASTMARK_SAVE();
              for (; pattern[0]; pattern += pattern[0]) {
                  if (pattern[1] == SRE_OP_LITERAL &&
***************
*** 940,944 ****
                  if (i)
                      return i;
!                 lastmark_restore(state, lastmark);
              }
              return 0;
--- 943,947 ----
                  if (i)
                      return i;
!                 LASTMARK_RESTORE();
              }
              return 0;
***************
*** 980,985 ****
                  state->ptr = ptr;
                  return 1;
  
!             } else if (pattern[pattern[0]] == SRE_OP_LITERAL) {
                  /* tail starts with a literal. skip positions where
                     the rest of the pattern cannot possibly match */
--- 983,991 ----
                  state->ptr = ptr;
                  return 1;
+             }
  
!             LASTMARK_SAVE();
! 
!             if (pattern[pattern[0]] == SRE_OP_LITERAL) {
                  /* tail starts with a literal. skip positions where
                     the rest of the pattern cannot possibly match */
***************
*** 999,1007 ****
                      ptr--;
                      count--;
                  }
  
              } else {
                  /* general case */
-                 lastmark = state->lastmark;
                  while (count >= (int) pattern[1]) {
                      state->ptr = ptr;
--- 1005,1013 ----
                      ptr--;
                      count--;
+                     LASTMARK_RESTORE();
                  }
  
              } else {
                  /* general case */
                  while (count >= (int) pattern[1]) {
                      state->ptr = ptr;
***************
*** 1011,1015 ****
                      ptr--;
                      count--;
!                     lastmark_restore(state, lastmark);
                  }
              }
--- 1017,1021 ----
                      ptr--;
                      count--;
!                     LASTMARK_RESTORE();
                  }
              }
***************
*** 1056,1060 ****
                  int matchmax = ((int)pattern[2] == 65535);
                  int c;
!                 lastmark = state->lastmark;
                  while (matchmax || count <= (int) pattern[2]) {
                      state->ptr = ptr;
--- 1062,1066 ----
                  int matchmax = ((int)pattern[2] == 65535);
                  int c;
!                 LASTMARK_SAVE();
                  while (matchmax || count <= (int) pattern[2]) {
                      state->ptr = ptr;
***************
*** 1066,1069 ****
--- 1072,1076 ----
                      if (c < 0)
                          return c;
+                     LASTMARK_RESTORE();
                      if (c == 0)
                          break;
***************
*** 1072,1076 ****
                      count++;
                  }
-                 lastmark_restore(state, lastmark);
              }
              return 0;
--- 1079,1082 ----
***************
*** 1114,1117 ****
--- 1120,1125 ----
              TRACE(("|%p|%p|MAX_UNTIL %d\n", pattern, ptr, count));
  
+             LASTMARK_SAVE();
+ 
              if (count < rp->pattern[1]) {
                  /* not enough matches */
***************
*** 1123,1126 ****
--- 1131,1135 ----
                  rp->count = count - 1;
                  state->ptr = ptr;
+                 LASTMARK_RESTORE();
                  return 0;
              }
***************
*** 1130,1134 ****
                     match another item, do so */
                  rp->count = count;
-                 lastmark = state->lastmark;
                  i = mark_save(state, 0, lastmark);
                  if (i < 0)
--- 1139,1142 ----
***************
*** 1139,1143 ****
                      return i;
                  i = mark_restore(state, 0, lastmark);
!                 state->lastmark = lastmark;
                  if (i < 0)
                      return i;
--- 1147,1151 ----
                      return i;
                  i = mark_restore(state, 0, lastmark);
!                 LASTMARK_RESTORE();
                  if (i < 0)
                      return i;
***************
*** 1183,1186 ****
--- 1191,1196 ----
              }
  
+             LASTMARK_SAVE();
+ 
              /* see if the tail matches */
              state->repeat = rp->prev;
***************
*** 1192,1195 ****
--- 1202,1207 ----
              state->repeat = rp;
  
+             LASTMARK_RESTORE();
+ 
              if (count >= rp->pattern[2] && rp->pattern[2] != 65535)
                  return 0;
***************
*** 3085,3086 ****
--- 3097,3101 ----
  
  #endif /* !defined(SRE_RECURSIVE) */
+ 
+ /* vim:ts=4:sw=4:et
+ */