Bug 684815 - Fix a crash, a=LegNeato
authorMark Kaplan <mark.kaplan@m86security.com>
Wed, 14 Sep 2011 16:57:01 -0700
changeset 35188 c7190956f9708551ac21acebf6c08a01a2a9c500
parent 35187 f5dd7005daa85ccf07b8dce3fbe7cc55483ecce2
child 35189 3fb441425998de9665ad96e6771a4277d73e810b
push id1975
push userclegnitto@mozilla.com
push dateWed, 14 Sep 2011 23:57:09 +0000
reviewersLegNeato
bugs684815
milestone1.9.2.23pre
Bug 684815 - Fix a crash, a=LegNeato
js/src/jsregexp.cpp
--- a/js/src/jsregexp.cpp
+++ b/js/src/jsregexp.cpp
@@ -4146,17 +4146,17 @@ SimpleMatch(REGlobalData *gData, REMatch
 static JS_ALWAYS_INLINE REMatchState *
 ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
 {
     REMatchState *result = NULL;
     REBackTrackData *backTrackData;
     jsbytecode *nextpc, *testpc;
     REOp nextop;
     RECapture *cap;
-    REProgState *curState;
+    REProgState *curState=NULL;
     const jschar *startcp;
     size_t parenIndex, k;
     size_t parenSoFar = 0;
 
     jschar matchCh1, matchCh2;
     RECharSet *charSet;
 
     JSBool anchor;
@@ -4268,33 +4268,35 @@ ExecuteREBytecode(REGlobalData *gData, R
               case REOP_JUMP:
                 /*
                  * If we have not gotten a result here, it is because of an
                  * empty match.  Do the same thing REOP_EMPTY would do.
                  */
                 if (!result)
                     result = x;
 
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 pc += GET_OFFSET(pc);
                 op = (REOp) *pc++;
                 continue;
 
               /*
                * Occurs at last (successful) end of REOP_ALT,
                */
               case REOP_ENDALT:
                 /*
                  * If we have not gotten a result here, it is because of an
                  * empty match.  Do the same thing REOP_EMPTY would do.
                  */
                 if (!result)
                     result = x;
 
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 op = (REOp) *pc++;
                 continue;
 
               case REOP_LPAREN:
                 pc = ReadCompactIndex(pc, &parenIndex);
                 re_debug("[ %lu ]", (unsigned long) parenIndex);
                 JS_ASSERT(parenIndex < gData->regexp->parenCount);
                 if (parenIndex + 1 > parenSoFar)
@@ -4361,29 +4363,31 @@ ExecuteREBytecode(REGlobalData *gData, R
                 PUSH_STATE_STACK(gData);
                 if (!PushBackTrackState(gData, REOP_ASSERTNOTTEST,
                                         nextpc, x, x->cp, 0, 0)) {
                     goto bad;
                 }
                 continue;
 
               case REOP_ASSERTTEST:
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 --curState;
                 x->cp = gData->cpbegin + curState->index;
                 gData->backTrackSP =
                     (REBackTrackData *) ((char *)gData->backTrackStack +
                                          curState->u.assertion.top);
                 gData->cursz = curState->u.assertion.sz;
                 if (result)
                     result = x;
                 break;
 
               case REOP_ASSERTNOTTEST:
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 --curState;
                 x->cp = gData->cpbegin + curState->index;
                 gData->backTrackSP =
                     (REBackTrackData *) ((char *)gData->backTrackStack +
                                          curState->u.assertion.top);
                 gData->cursz = curState->u.assertion.sz;
                 result = (!result) ? x : NULL;
                 break;
@@ -4449,17 +4453,18 @@ ExecuteREBytecode(REGlobalData *gData, R
 
                 if (!result)
                     result = x;
                 continue;
 
               case REOP_REPEAT:
                 --curState;
                 do {
-                    --gData->stateStackTop;
+                    if(gData->stateStackTop)
+                        --gData->stateStackTop;
                     if (!result) {
                         /* Failed, see if we have enough children. */
                         if (curState->u.quantifier.min == 0)
                             goto repeatDone;
                         goto break_switch;
                     }
                     if (curState->u.quantifier.min == 0 &&
                         x->cp == gData->cpbegin + curState->index) {
@@ -4537,24 +4542,26 @@ ExecuteREBytecode(REGlobalData *gData, R
                     /* step over <next> */
                     pc += OFFSET_LEN;
                     op = (REOp) *pc++;
                 } else {
                     if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
                                             pc, x, x->cp, 0, 0)) {
                         goto bad;
                     }
-                    --gData->stateStackTop;
+                    if(gData->stateStackTop)
+                        --gData->stateStackTop;
                     pc = pc + GET_OFFSET(pc);
                     op = (REOp) *pc++;
                 }
                 continue;
 
               case REOP_MINIMALREPEAT:
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 --curState;
 
                 re_debug("{%d,%d}", curState->u.quantifier.min,
                          curState->u.quantifier.max);
 #define PREPARE_REPEAT()                                                      \
     JS_BEGIN_MACRO                                                            \
         curState->index = x->cp - gData->cpbegin;                             \
         curState->continue_op = REOP_MINIMALREPEAT;                           \
@@ -4598,17 +4605,18 @@ ExecuteREBytecode(REGlobalData *gData, R
                 curState->parenSoFar = parenSoFar;
                 PUSH_STATE_STACK(gData);
                 if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
                                         pc, x, x->cp,
                                         curState->parenSoFar,
                                         parenSoFar - curState->parenSoFar)) {
                     goto bad;
                 }
-                --gData->stateStackTop;
+                if(gData->stateStackTop)
+                    --gData->stateStackTop;
                 pc = pc + GET_OFFSET(pc);
                 op = (REOp) *pc++;
                 JS_ASSERT(op < REOP_LIMIT);
                 continue;
               default:
                 JS_ASSERT(JS_FALSE);
                 result = NULL;
             }
@@ -4641,16 +4649,17 @@ ExecuteREBytecode(REGlobalData *gData, R
             gData->cursz = backTrackData->sz;
             gData->backTrackSP =
                 (REBackTrackData *) ((char *)backTrackData - backTrackData->sz);
             x->cp = backTrackData->cp;
             pc = backTrackData->backtrack_pc;
             op = (REOp) backTrackData->backtrack_op;
             JS_ASSERT(op < REOP_LIMIT);
             gData->stateStackTop = backTrackData->saveStateStackTop;
+
             JS_ASSERT(gData->stateStackTop);
 
             memcpy(gData->stateStack, backTrackData + 1,
                    sizeof(REProgState) * backTrackData->saveStateStackTop);
             curState = &gData->stateStack[gData->stateStackTop - 1];
 
             if (backTrackData->parenCount) {
                 memcpy(&x->parens[backTrackData->parenIndex],