From dcacacf7d79a056008577ac2f55e7391361b2b80 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Fri, 29 Oct 1999 22:23:36 +0000 Subject: [PATCH] r=norris Fixed accidental eating of exceptions (match loop didn't terminate on failure). New ECMA definition (again) of back reference format. git-svn-id: svn://10.0.0.236/trunk@52275 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsregexp.c | 147 ++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 86 deletions(-) diff --git a/mozilla/js/src/jsregexp.c b/mozilla/js/src/jsregexp.c index c664c86c8bf..17c2b3237d9 100644 --- a/mozilla/js/src/jsregexp.c +++ b/mozilla/js/src/jsregexp.c @@ -941,7 +941,8 @@ ParseAtom(CompilerState *state) Yuk. Keeping the old style \n interpretation for 1.2 compatibility. */ - if (state->context->version <= JSVERSION_1_4) { + if (state->context->version != JSVERSION_DEFAULT && + state->context->version <= JSVERSION_1_4) { switch (c) { case '0': do_octal: @@ -994,57 +995,23 @@ do_octal: } } else { - if (cp < (state->cpend - 1) && cp[1] >= '0' && cp[1] <= '9') { - if (c >= '0' && c <= '3') { - if (c <= '7') { /* ZeroToThree OctalDigit */ - if (cp < (state->cpend - 2) - && cp[2] >= '0' && cp[2] <= '9') { - ren = NewRENode(state, REOP_FLAT1, NULL); - c = 64 * (uintN)JS7_UNDEC(c) - + 8 * (uintN)JS7_UNDEC(cp[1]) - + (uintN)JS7_UNDEC(cp[2]); - cp += 2; - } - else /*ZeroToThree OctalDigit lookahead != OctalDigit */ - goto twodigitescape; - } - else /* ZeroToThree EightOrNine */ - goto twodigitescape; - } - else { /* FourToNine DecimalDigit */ -twodigitescape: - num = 10 * (uintN)JS7_UNDEC(c) + (uintN)JS7_UNDEC(cp[1]); - if (num >= 10 && num <= state->parenCount) { - cp++; - goto backref; - } - if (c > '7' || cp[1] > '7') { - JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL, - JSMSG_INVALID_BACKREF); - return NULL; - } - ren = NewRENode(state, REOP_FLAT1, NULL); - c = 8 * (uintN)JS7_UNDEC(c) + (uintN)JS7_UNDEC(*++cp); - } + if (c == '0') { + ren = NewRENode(state, REOP_FLAT1, NULL); + c = 0; } - else { /* DecimalDigit lookahead != DecimalDigit */ - if (c == '0') { - ren = NewRENode(state, REOP_FLAT1, NULL); - c = 0; - } - else { - num = (uintN)JS7_UNDEC(c); -backref: - ren = NewRENode(state, REOP_BACKREF, NULL); - if (!ren) - return NULL; - ren->u.num = num - 1; /* \1 is numbered 0, etc. */ - /* Avoid common chr- and flags-setting code after switch. */ - ren->flags = RENODE_NONEMPTY; - goto bump_cp; - } + else { + num = (uintN)JS7_UNDEC(c); + for (c = *++cp; JS7_ISDEC(c); c = *++cp) + num = 10 * num + (uintN)JS7_UNDEC(c); + ren = NewRENode(state, REOP_BACKREF, NULL); + if (!ren) + return NULL; + ren->u.num = num - 1; /* \1 is numbered 0, etc. */ + /* Avoid common chr- and flags-setting code after switch. */ + ren->flags = RENODE_NONEMPTY; + goto bump_cp; } - } + } break; case 'x': @@ -1057,7 +1024,8 @@ backref: num <<= 4; num += JS7_UNHEX(c); } else { - if (state->context->version <= JSVERSION_1_4) + if (state->context->version != JSVERSION_DEFAULT && + state->context->version <= JSVERSION_1_4) cp--; /* back up so cp points to last hex char */ else goto nothex; /* ECMA 2 insists on pairs */ @@ -1298,35 +1266,35 @@ static JSBool matchChar(int flags, jschar c, jschar c2) } static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, - const jschar *cp); + const jschar *cp, JSBool *ok); static const jschar *matchGreedyKid(MatchState *state, RENode *ren, int kidCount, int maxKid, - const jschar *cp, const jschar *previousKid) + const jschar *cp, const jschar *previousKid, JSBool *ok) { const jschar *kidMatch; const jschar *match; - kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp); + kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp, ok); if (kidMatch == NULL) { - match = matchRENodes(state, ren->next, NULL, cp); + match = matchRENodes(state, ren->next, NULL, cp, ok); if (match == NULL) return NULL; else { if (previousKid != NULL) - matchRENodes(state, (RENode *)ren->kid, ren->next, previousKid); + matchRENodes(state, (RENode *)ren->kid, ren->next, previousKid, ok); return cp; } } else { if (kidMatch == cp) return kidMatch; /* no point pursuing an empty match forever */ if ((maxKid == 0) || (++kidCount < maxKid)) { - match = matchGreedyKid(state, ren, kidCount, maxKid, kidMatch, cp); + match = matchGreedyKid(state, ren, kidCount, maxKid, kidMatch, cp, ok); if (match != NULL) return match; } - match = matchRENodes(state, ren->next, NULL, kidMatch); + match = matchRENodes(state, ren->next, NULL, kidMatch, ok); if (match != NULL) { - matchRENodes(state, (RENode *)ren->kid, ren->next, cp); + matchRENodes(state, (RENode *)ren->kid, ren->next, cp, ok); return kidMatch; } else @@ -1336,19 +1304,19 @@ static const jschar *matchGreedyKid(MatchState *state, RENode *ren, static const jschar *matchNonGreedyKid(MatchState *state, RENode *ren, int kidCount, int maxKid, - const jschar *cp) + const jschar *cp, JSBool *ok) { const jschar *kidMatch; const jschar *match; - match = matchRENodes(state, ren->next, NULL, cp); + match = matchRENodes(state, ren->next, NULL, cp, ok); if (match != NULL) return cp; - kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp); + kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp, ok); if (kidMatch == NULL) return NULL; else { if (kidMatch == cp) return kidMatch; /* no point pursuing an empty match forever */ - return matchNonGreedyKid(state, ren, kidCount, maxKid, kidMatch); + return matchNonGreedyKid(state, ren, kidCount, maxKid, kidMatch, ok); } } @@ -1393,7 +1361,8 @@ static void calcBMSize(MatchState *state, RENode *ren) if (c > maxc) maxc = c; } - ren->u.ucclass.bmsize = (uint16)((size_t)(maxc + JS_BITS_PER_BYTE) / JS_BITS_PER_BYTE); + ren->u.ucclass.bmsize = (uint16)((size_t)(maxc + JS_BITS_PER_BYTE) + / JS_BITS_PER_BYTE); } static JSBool buildBitmap(MatchState *state, RENode *ren) @@ -1405,7 +1374,8 @@ static JSBool buildBitmap(MatchState *state, RENode *ren) const jschar *cp = ren->kid, *end = ren->u.kid2, *ocp; calcBMSize(state, ren); - ren->u.ucclass.bitmap = bitmap = JS_malloc(state->context, ren->u.ucclass.bmsize); + ren->u.ucclass.bitmap = bitmap = JS_malloc(state->context, + ren->u.ucclass.bmsize); if (!bitmap) { JS_ReportOutOfMemory(state->context); return JS_FALSE; @@ -1596,7 +1566,7 @@ static JSBool buildBitmap(MatchState *state, RENode *ren) } static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, - const jschar *cp) + const jschar *cp, JSBool *ok) { const jschar *cp2, *kidMatch, *lastKid, *source, *cpend = state->cpend; jschar c; @@ -1613,14 +1583,14 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, ren = (RENode *)ren->kid; continue; } - kidMatch = matchRENodes(state, (RENode *)ren->kid, stop, cp); + kidMatch = matchRENodes(state, (RENode *)ren->kid, stop, cp, ok); if (kidMatch != NULL) return kidMatch; break; case REOP_QUANT: lastKid = NULL; for (num = 0; num < ren->u.range.min; num++) { kidMatch = matchRENodes(state, (RENode *)ren->kid, - ren->next, cp); + ren->next, cp, ok); if (kidMatch == NULL) return NULL; lastKid = cp; @@ -1629,33 +1599,33 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, if (num == ren->u.range.max) break; if ((ren->flags & RENODE_MINIMAL) == 0) cp = matchGreedyKid(state, ren, num, - ren->u.range.max, cp, lastKid); + ren->u.range.max, cp, lastKid, ok); else cp = matchNonGreedyKid(state, ren, num, - ren->u.range.max, cp); + ren->u.range.max, cp, ok); if (cp == NULL) return NULL; break; case REOP_PLUS: kidMatch = matchRENodes(state, (RENode *)ren->kid, - ren->next, cp); + ren->next, cp, ok); if (kidMatch == NULL) return NULL; if ((ren->flags & RENODE_MINIMAL) == 0) { - cp = matchGreedyKid(state, ren, 1, 0, cp, NULL); + cp = matchGreedyKid(state, ren, 1, 0, cp, NULL, ok); if (cp == NULL) return NULL; } else { - cp = matchNonGreedyKid(state, ren, 1, 0, kidMatch); + cp = matchNonGreedyKid(state, ren, 1, 0, kidMatch, ok); if (cp == NULL) return NULL; } break; case REOP_STAR: if ((ren->flags & RENODE_MINIMAL) == 0) { - cp = matchGreedyKid(state, ren, 0, 0, cp, NULL); + cp = matchGreedyKid(state, ren, 0, 0, cp, NULL, ok); if (cp == NULL) return NULL; } else { - cp = matchNonGreedyKid(state, ren, 0, 0, cp); + cp = matchNonGreedyKid(state, ren, 0, 0, cp, ok); if (cp == NULL) return NULL; } break; @@ -1663,18 +1633,18 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, num = state->parenCount; if (ren->flags & RENODE_MINIMAL) { const jschar *restMatch = matchRENodes(state, ren->next, - stop, cp); + stop, cp, ok); if (restMatch != NULL) return restMatch; } kidMatch = matchRENodes(state, (RENode *)ren->kid, - ren->next, cp); + ren->next, cp, ok); if (kidMatch == NULL) { state->parenCount = num; break; } else { const jschar *restMatch = matchRENodes(state, ren->next, - stop, kidMatch); + stop, kidMatch, ok); if (restMatch == NULL) { /* need to undo the result of running the kid */ state->parenCount = num; @@ -1704,12 +1674,12 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, break; case REOP_ASSERT: kidMatch = matchRENodes(state, (RENode *)ren->kid, - ren->next, cp); + ren->next, cp, ok); if (kidMatch == NULL) return NULL; break; case REOP_ASSERT_NOT: kidMatch = matchRENodes(state, (RENode *)ren->kid, - ren->next, cp); + ren->next, cp, ok); if (kidMatch != NULL) return NULL; break; case REOP_BACKREF: @@ -1717,6 +1687,7 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, if (num >= state->parenCount) { JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL, JSMSG_BAD_BACKREF); + *ok = JS_FALSE; return NULL; } parsub = &state->parens[num]; @@ -1733,8 +1704,10 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, case REOP_CCLASS: if (cp != cpend) { if (ren->u.ucclass.bitmap == NULL) { - if (!buildBitmap(state, ren)) + if (!buildBitmap(state, ren)) { + *ok = JS_FALSE; return NULL; + } } c = *cp; b = (c >> 3); @@ -1766,7 +1739,7 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, case REOP_DOTSTARMIN: for (cp2 = cp; cp2 < cpend; cp2++) { const jschar *cp3 = matchRENodes(state, ren->next, - stop, cp2); + stop, cp2, ok); if (cp3 != NULL) return cp3; if (*cp2 == '\n') return NULL; @@ -1778,7 +1751,7 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, break; while (cp2 >= cp) { const jschar *cp3 = matchRENodes(state, ren->next, - stop, cp2); + stop, cp2, ok); if (cp3 != NULL) return cp3; cp2--; @@ -1895,7 +1868,7 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop, } static const jschar * -MatchRegExp(MatchState *state, RENode *ren, const jschar *cp) +MatchRegExp(MatchState *state, RENode *ren, const jschar *cp, JSBool *ok) { const jschar *cp2, *cp3; /* have to include the position beyond the last character @@ -1903,7 +1876,8 @@ MatchRegExp(MatchState *state, RENode *ren, const jschar *cp) for (cp2 = cp; cp2 <= state->cpend; cp2++) { state->skipped = cp2 - cp; state->parenCount = 0; - cp3 = matchRENodes(state, ren, NULL, cp2); + cp3 = matchRENodes(state, ren, NULL, cp2, ok); + if (!*ok) return NULL; if (cp3 != NULL) return cp3; } @@ -1969,7 +1943,8 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, * Call the recursive matcher to do the real work. Return null on mismatch * whether testing or not. On match, return an extended Array object. */ - cp = MatchRegExp(&state, re->ren, cp); + cp = MatchRegExp(&state, re->ren, cp, &ok); + if (!ok) goto out; if (!cp) { *rval = JSVAL_NULL; goto out;