Commit c956219e authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

* Remember to check for end of string even where we

  know the character class must match.
Thanks to Mads and Christian for finding this bug
Review URL: http://codereview.chromium.org/18750

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1150 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1efdae68
...@@ -1835,6 +1835,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, ...@@ -1835,6 +1835,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
// ASCII optimizations for us. // ASCII optimizations for us.
macro_assembler->GoTo(on_failure); macro_assembler->GoTo(on_failure);
} }
if (check_offset) {
macro_assembler->CheckPosition(cp_offset, on_failure);
}
return; return;
} }
...@@ -1842,10 +1845,8 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, ...@@ -1842,10 +1845,8 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
!cc->is_negated() && !cc->is_negated() &&
ranges->at(0).IsEverything(max_char)) { ranges->at(0).IsEverything(max_char)) {
// This is a common case hit by non-anchored expressions. // This is a common case hit by non-anchored expressions.
// TODO(erikcorry): We should have a macro assembler instruction that just
// checks for end of string without loading the character.
if (check_offset) { if (check_offset) {
macro_assembler->LoadCurrentCharacter(cp_offset, on_failure); macro_assembler->CheckPosition(cp_offset, on_failure);
} }
return; return;
} }
...@@ -2477,7 +2478,7 @@ bool AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) { ...@@ -2477,7 +2478,7 @@ bool AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) {
switch (type_) { switch (type_) {
case AT_END: { case AT_END: {
Label ok; Label ok;
assembler->LoadCurrentCharacter(trace->cp_offset(), &ok); assembler->CheckPosition(trace->cp_offset(), &ok);
assembler->GoTo(trace->backtrack()); assembler->GoTo(trace->backtrack());
assembler->Bind(&ok); assembler->Bind(&ok);
break; break;
......
...@@ -71,6 +71,9 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler { ...@@ -71,6 +71,9 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
uc16 minus, uc16 minus,
uc16 mask, uc16 mask,
Label* on_not_equal); Label* on_not_equal);
// Checks whether the given offset from the current position is before
// the end of the string.
virtual void CheckPosition(int cp_offset, Label* on_outside_input);
virtual bool CheckSpecialCharacterClass(uc16 type, virtual bool CheckSpecialCharacterClass(uc16 type,
int cp_offset, int cp_offset,
bool check_offset, bool check_offset,
...@@ -171,10 +174,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler { ...@@ -171,10 +174,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// This function must not trigger a garbage collection. // This function must not trigger a garbage collection.
static Address GrowStack(Address stack_top); static Address GrowStack(Address stack_top);
// Checks whether the given offset from the current position is before
// the end of the string.
void CheckPosition(int cp_offset, Label* on_outside_input);
// The ebp-relative location of a regexp register. // The ebp-relative location of a regexp register.
Operand register_location(int register_index); Operand register_location(int register_index);
......
...@@ -111,6 +111,12 @@ class RegExpMacroAssembler { ...@@ -111,6 +111,12 @@ class RegExpMacroAssembler {
virtual void CheckNotRegistersEqual(int reg1, virtual void CheckNotRegistersEqual(int reg1,
int reg2, int reg2,
Label* on_not_equal) = 0; Label* on_not_equal) = 0;
// Checks whether the given offset from the current position is before
// the end of the string. May overwrite the current character.
virtual void CheckPosition(int cp_offset, Label* on_outside_input) {
LoadCurrentCharacter(cp_offset, on_outside_input, true);
}
// Check whether a standard/default character class matches the current // Check whether a standard/default character class matches the current
// character. Returns false if the type of special character class does // character. Returns false if the type of special character class does
// not have custom support. // not have custom support.
......
...@@ -332,3 +332,7 @@ assertFalse(/()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasldkas)/.test('xy%%%y'), 'qt5'); ...@@ -332,3 +332,7 @@ assertFalse(/()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasldkas)/.test('xy%%%y'), 'qt5');
assertFalse(/()x\1y([0-7]%%%x|[0-6]%%%y)/.test('xy7%%%y'), 'qt6'); assertFalse(/()x\1y([0-7]%%%x|[0-6]%%%y)/.test('xy7%%%y'), 'qt6');
assertFalse(/xy([0-7]%%%x|[0-6]%%%y)/.test('xy7%%%y'), 'qt7'); assertFalse(/xy([0-7]%%%x|[0-6]%%%y)/.test('xy7%%%y'), 'qt7');
assertFalse(/x([0-7]%%%x|[0-6]%%%y)/.test('x7%%%y'), 'qt8'); assertFalse(/x([0-7]%%%x|[0-6]%%%y)/.test('x7%%%y'), 'qt8');
// Don't hang on this one.
/[^\xfe-\xff]*/.test("");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment