Closed
Bug 223535
Opened 22 years ago
Closed 22 years ago
Regular expression with empty last alternative crashs, e.g. /x|/ [@ processOp]
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
VERIFIED
FIXED
People
(Reporter: zack-weg, Assigned: brendan)
References
()
Details
(Keywords: crash, regression)
Crash Data
Attachments
(1 file, 1 obsolete file)
1.95 KB,
patch
|
timeless
:
review+
shaver
:
superreview+
asa
:
approval1.6a+
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007
Build Identifier: js shell 20031024
A regular expression ending with '|' crashs at compile time.
Regression of the regexp rewrite landing (bug 85721).
Reproducible: Always
Steps to Reproduce:
1. Enter js shell
2. Type /|/
Actual Results:
Crash.
Expected Results:
Print /|/ .
Keywords: crash,
regression
if ((((RENode *)(result->kid))->op == REOP_FLAT)
&& (((RENode *)(result->u.kid2))->op == REOP_FLAT)
&& ((state->flags & JSREG_FOLD) == 0) ) {
- (RENode*)(result->kid) 0x00080101
op CXX0030: Error: expression cannot be evaluated
next CXX0030: Error: expression cannot be evaluated
kid CXX0030: Error: expression cannot be evaluated
+ u {...}
processOp(CompilerState * 0x0012ebec, REOpData * 0x00411648, RENode * *
0x00411c50, int 1) line 346 + 6 bytes
parseRegExp(CompilerState * 0x0012ebec) line 549 + 29 bytes
js_NewRegExp(JSContext * 0x002f6ca8, JSTokenStream * 0x00411228, JSString *
0x002f87b8, unsigned int 0, int 0) line 1581 + 9 bytes
js_NewRegExpObject(JSContext * 0x002f6ca8, JSTokenStream * 0x00411228, unsigned
short * 0x00411520, unsigned int 1, unsigned int 0) line 3722 + 23 bytes
js_GetToken(JSContext * 0x002f6ca8, JSTokenStream * 0x00411228) line 1180 + 51 bytes
js_PeekToken(JSContext * 0x002f6ca8, JSTokenStream * 0x00411228) line 642 + 13 bytes
Statements(JSContext * 0x002f6ca8, JSTokenStream * 0x00411228, JSTreeContext *
0x0012edd0) line 979 + 13 bytes
js_ParseTokenStream(JSContext * 0x002f6ca8, JSObject * 0x002f8348, JSTokenStream
* 0x00411228) line 414 + 17 bytes
JS_BufferIsCompilableUnit(JSContext * 0x002f6ca8, JSObject * 0x002f8348, const
char * 0x0012eea8, unsigned int 4) line 3104 + 17 bytes
Process(JSContext * 0x002f6ca8, JSObject * 0x002f8348, char * 0x00000000) line
384 + 31 bytes
Assignee: general → brendan
Severity: critical → blocker
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: blocking1.6a?
Summary: Regular expression with empty last alternative crashs, e.g. /x|/ → Regular expression with empty last alternative crashs, e.g. /x|/ [@ processOp]
the problem is here:
processOp(CompilerState *state, REOpData *opData, RENode **operandStack, intN
operandSP)
result->kid = operandStack[operandSP - 2];
result->u.kid2 = operandStack[operandSP - 1];
operandSP 1
So it's an ABR
Assignee | ||
Comment 3•22 years ago
|
||
Not my rewrite, but I checked it in (silly me).
The code tries to make an empty node for some cases, but seems to miss others.
I don't think the patch is going to recover from all such missed cases, although
it might. But it's still patching the symptom, not the cause.
/be
# Retest List, smdebug, generated Fri Oct 24 10:23:17 2003.
# Original test base was: All tests.
# 1355 of 1355 test(s) were completed, 153 failures reported.
js1_5/Array/regress-101964.js
js1_5/Regress/regress-192465.js
js1_5/Regress/regress-96128-n.js
all other failures are liveconnect (i should have told jsDriver to skip that but
i am not awake enough to do that). i cvs updated tests before running so i
should be current. None of these seem to relate to this regexps so i'm not
concerned.
For my reference, spidermonkey (current and a snapshot of mine from 08/31/2003)
and msjscript
evaluate:
t="o]";[t.match(/\]|0/),t.match(/\]|/),t.match(/]|0/),t.match(/]|/),t.match(/o|/),"_end_"]
to:
],,],,o,_end_
I exected something else.
Next: fun with ||'s
(first on boffo)
js> /||/
typein:2: SyntaxError: syntax error:
typein:2: /||/
typein:2: .^
js> /|||/
./run-mozilla.sh: line 72: 3272 Segmentation fault "$prog" ${1+"$@"}
mozhack@boffo:~/obj-i686-pc-linux-gnu-qt/dist/bin$
boffo is a tinderbox, so the code is whatever is current.
raistlin(patched):
I:\build\mozilla\js\src\WINNT5.0_DBG.OBJ>js
js> /1|2|/
/1|2|/
js> /(1|2|)|/
/(1|2|)|/
js> /(1|2|)|(1|)/
/(1|2|)|(1|)/
js> /(1|2|)|(1||)/
/(1|2|)|(1||)/
js> /(1|2|)|(1||)|/
/(1|2|)|(1||)|/
js> /(1|2|)|(1|.?|)|/
/(1|2|)|(1|.?|)|/
js> /(1|2|)|(1|.?|)|?/
7: SyntaxError: invalid quantifier ?:
7: /(1|2|)|(1|.?|)|?/
7: ^
js> /(1|2|)|(1|.?|)?|/
/(1|2|)|(1|.?|)?|/
js> /(1|2|)|(1|.?|)?|[]/
/(1|2|)|(1|.?|)?|[]/
js> /(1|2|)|(1|.?|)?|[]|/
/(1|2|)|(1|.?|)?|[]|/
js> /(1|2|)|(1|.?|)?|[]|(|[])/
/(1|2|)|(1|.?|)?|[]|(|[])/
js> /(1|2|)|(1|.?|)?|[]|(|[])|/
/(1|2|)|(1|.?|)?|[]|(|[])|/
js> /(1|2|)|(1|.?|)?|[]|(|[])|(?:|)}/
/(1|2|)|(1|.?|)?|[]|(|[])|(?:|)}/
js> /(1|2|)|(1|.?|)?|[]|(|[])|(?:|)||/
/(1|2|)|(1|.?|)?|[]|(|[])|(?:|)||/
js> /||/
/||/
js> /|||/
/|||/
js>
-- many |s:
(first on raistlin - patched)
js> a=[];a[1000000]=null;RegExp(a.join('|')).test("1")
Assertion failure: ((diff) >= -32768) && ((diff) <= 32767), at jsregexp.c:1380
emitREBytecode(CompilerState * 0x0012e4b8, JSRegExp * 0x22150020, int 1000000,
unsigned char * 0x22709ffb, RENode * 0x1fad49a0) line 1380 + 40 bytes
case REOP_ENDALT:
diff = pc - emitStateSP->nextTermFixup;
CHECK_OFFSET(diff);
I:\build\mozilla\js\src\WINNT5.0_OPT.OBJ.08_31_2003>js
js> a=[];a[1000000]=null;RegExp(a.join('|')).test("1")
true
IE reports an OOM error instead of crashing.
-- empties:
(first on raistlin - patched)
js> RegExp("")
//
js> RegExp(undefined)
/undefined/
js> RegExp(null)
RegExp(JSContext * 0x002f7398, JSObject * 0x002f8b48, unsigned int 1, long *
0x00414b74, long * 0x0012e64c) line 3676 + 46 bytes
ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval);
I:\build\mozilla\js\src\WINNT5.0_OPT.OBJ.08_31_2003>js
js> RegExp("")
//
js> RegExp(undefined)
/undefined/
js> RegExp(null)
(crash, no stack posted or investigated since it doesn't matter and i don't have
the source)
IE gives:
RegExp("")
//
RegExp(undefined)
//
RegExp(null)
/null/
Brendan: a few thoughts about my patch:
1. returning was wrong here:
if (!dummy)
return JS_FALSE;
should be goto out;
2. I don't think we can do it much better, i tried looking at a few other approaches
A. moving the if outside the while loop, but then i had to use the extra if in
pushOperand to mayberealloc the operandstack.
B. trying to recycle pushOperand - I couldn't find a way to use it that wouldn't
require a lot of messy hacking
C. splitting (which i didn't actually play with or reject)
while (operatorSP) {MAYBEADDDUMMY; OLDCODE;} ENDCODE;
into
while (operatorSP > 1) {OLDCODE;}
if (operatorSP) {ADDDUMMY; OLDCODE;}
ENDCODE
or:
if (!operatorSP) {ENDCODE;}
while (operatorSP > 1) {OLDCODE;}
ADDDUMMY; OLDCODE; ENDCODE;
Anyway, i really think there's only one case that it misses which is
regexpstring =~ m%|$%
i'm going to think about it a bit more, it might be the case that the place
where it tries to handle it is just wrong :) in which case my code copying
should be a move. Actually, that's what I was doing, i was trying to figure out
how to tickle the current code to actually make that dummy node. i was having a
really hard time doing that :).
Updated•22 years ago
|
Severity: blocker → critical
Comment 5•22 years ago
|
||
Testcase added to JS testsuite:
mozilla/js/tests/ecma_3/RegExp/regress-223535.js
Currently passing in the Rhino shell, crashing in SpiderMonkey (debug and opt).
Assignee | ||
Comment 6•22 years ago
|
||
I think this covers the missing case.
Timeless, no need to goto out before the stacks have been malloc'd (malloc
happy code here, as an aside, but the early return for empty regexp is ok -- it
just needs to propagate false if NewRENode failed).
/be
Assignee | ||
Updated•22 years ago
|
Attachment #134054 -
Flags: superreview?(shaver)
Attachment #134054 -
Flags: review?(timeless)
Assignee | ||
Updated•22 years ago
|
Status: NEW → ASSIGNED
Flags: blocking1.6a? → blocking1.6a+
Priority: -- → P1
Target Milestone: --- → mozilla1.6alpha
Updated•22 years ago
|
Priority: P1 → --
Target Milestone: mozilla1.6alpha → ---
Comment on attachment 134054 [details] [diff] [review]
proposed fix
i like it :)
# Retest List, smdebug, generated Fri Oct 24 15:55:38 2003.
# Original test base was: All tests.
# 1111 of 1111 test(s) were completed, 5 failures reported.
js1_5/Array/regress-101964.js
js1_5/Regress/regress-152646.js
js1_5/Regress/regress-192414.js
js1_5/Regress/regress-192465.js
js1_5/Regress/regress-96128-n.js
I'm not sure why the first run i made had 3 failures instead of 5, but i did a
run before this run and had 5 again.
Attachment #134054 -
Flags: review?(timeless) → review+
Comment 8•22 years ago
|
||
Comment on attachment 134054 [details] [diff] [review]
proposed fix
Sure. (Is it regexp week or something?)
Attachment #134054 -
Flags: superreview?(shaver) → superreview+
Assignee | ||
Updated•22 years ago
|
Attachment #134034 -
Attachment is obsolete: true
Assignee | ||
Updated•22 years ago
|
Attachment #134054 -
Flags: approval1.6a?
Comment 9•22 years ago
|
||
Comment on attachment 134054 [details] [diff] [review]
proposed fix
a=asa (on behalf of drivers) for checkin to 1.6alpha
Attachment #134054 -
Flags: approval1.6a? → approval1.6a+
Assignee | ||
Comment 10•22 years ago
|
||
Fixed.
/be
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Comment 11•22 years ago
|
||
Verified FIXED.
The above test now passes in the debug and optimized SpiderMonkey shell.
In fact all tests pass, in directory mozilla/js/tests/ecma_3/RegExp/ -
Status: RESOLVED → VERIFIED
Updated•20 years ago
|
Flags: testcase+
Updated•14 years ago
|
Crash Signature: [@ processOp]
You need to log in
before you can comment on or make changes to this bug.
Description
•