Diff
Modified: trunk/LayoutTests/ChangeLog (105443 => 105444)
--- trunk/LayoutTests/ChangeLog 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/LayoutTests/ChangeLog 2012-01-19 21:57:11 UTC (rev 105444)
@@ -1,3 +1,17 @@
+2012-01-19 Geoffrey Garen <[email protected]>
+
+ Implicit creation of a regular _expression_ should eagerly check for syntax errors
+ https://bugs.webkit.org/show_bug.cgi?id=76642
+
+ Reviewed by Oliver Hunt.
+
+ * fast/js/code-serialize-paren-expected.txt:
+ * fast/js/script-tests/code-serialize-paren.js: This test was secretly
+ broken due to a regexp syntax error. Now fixed.
+
+ * fast/regex/syntax-errors-expected.txt: Added.
+ * fast/regex/syntax-errors.html: Added.
+
2012-01-13 Ryosuke Niwa <[email protected]>
Crash in CompositeEditCommand::ensureComposition
Modified: trunk/LayoutTests/fast/js/code-serialize-paren-expected.txt (105443 => 105444)
--- trunk/LayoutTests/fast/js/code-serialize-paren-expected.txt 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/LayoutTests/fast/js/code-serialize-paren-expected.txt 2012-01-19 21:57:11 UTC (rev 105444)
@@ -3,7 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS (function () { return (x + y) * z; }).toString().search('return.*\(') < 0 is true
+PASS (function () { return (x + y) * z; }).toString().search('return.*[(]') != -1 is true
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/js/script-tests/code-serialize-paren.js (105443 => 105444)
--- trunk/LayoutTests/fast/js/script-tests/code-serialize-paren.js 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/LayoutTests/fast/js/script-tests/code-serialize-paren.js 2012-01-19 21:57:11 UTC (rev 105444)
@@ -2,4 +2,4 @@
"This test checks whether converting function code to a string preserves semantically significant parentheses."
)
-shouldBeTrue("(function () { return (x + y) * z; }).toString().search('return.*\\(') < 0");
+shouldBeTrue("(function () { return (x + y) * z; }).toString().search('return.*[(]') != -1");
Added: trunk/LayoutTests/fast/regex/syntax-errors-expected.txt (0 => 105444)
--- trunk/LayoutTests/fast/regex/syntax-errors-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/regex/syntax-errors-expected.txt 2012-01-19 21:57:11 UTC (rev 105444)
@@ -0,0 +1,7 @@
+This test verifies that implicit creation of a regular _expression_ eagerly checks for syntax errors.
+
+If the test passes, you'll see pass messages below.
+
+PASS: "abc".search("[") should throw an exception and did: SyntaxError: Invalid regular _expression_: missing terminating ] for character class.
+PASS: "abc".match("[") should throw an exception and did: SyntaxError: Invalid regular _expression_: missing terminating ] for character class.
+
Added: trunk/LayoutTests/fast/regex/syntax-errors.html (0 => 105444)
--- trunk/LayoutTests/fast/regex/syntax-errors.html (rev 0)
+++ trunk/LayoutTests/fast/regex/syntax-errors.html 2012-01-19 21:57:11 UTC (rev 105444)
@@ -0,0 +1,26 @@
+<p>This test verifies that implicit creation of a regular _expression_ eagerly checks for syntax errors.</p>
+<p>If the test passes, you'll see pass messages below.</p>
+<pre id="console"></pre>
+
+<script>
+function log(s)
+{
+ document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+}
+
+function shouldThrow(program)
+{
+ try {
+ eval(program);
+ log("FAIL: " + program + " should throw an exception but didn't");
+ } catch (e) {
+ log("PASS: " + program + " should throw an exception and did: " + e + ".");
+ }
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+shouldThrow('"abc".search("[")');
+shouldThrow('"abc".match("[")');
+</script>
Modified: trunk/Source/_javascript_Core/ChangeLog (105443 => 105444)
--- trunk/Source/_javascript_Core/ChangeLog 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-01-19 21:57:11 UTC (rev 105444)
@@ -1,3 +1,24 @@
+2012-01-19 Geoffrey Garen <[email protected]>
+
+ Implicit creation of a regular _expression_ should eagerly check for syntax errors
+ https://bugs.webkit.org/show_bug.cgi?id=76642
+
+ Reviewed by Oliver Hunt.
+
+ This is a correctness fix and a slight optimization.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch): Check for syntax errors because that's the
+ correct behavior.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match): ASSERT that we aren't a syntax error. (One line
+ of code change, many lines of indentation change.)
+
+ Since we have no clients that try to match a RegExp that is a syntax error,
+ let's optimize out the check.
+
2012-01-19 Mark Hahnenberg <[email protected]>
Implement a new allocator for backing stores
Modified: trunk/Source/_javascript_Core/runtime/RegExp.cpp (105443 => 105444)
--- trunk/Source/_javascript_Core/runtime/RegExp.cpp 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/Source/_javascript_Core/runtime/RegExp.cpp 2012-01-19 21:57:11 UTC (rev 105444)
@@ -330,7 +330,6 @@
compile(&globalData, charSize);
}
-
int RegExp::match(JSGlobalData& globalData, const UString& s, int startOffset, Vector<int, 32>* ovector)
{
if (startOffset < 0)
@@ -343,55 +342,52 @@
if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
- if (m_state != ParseError) {
- compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
+ ASSERT(m_state != ParseError);
+ compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
- int offsetVectorSize = (m_numSubpatterns + 1) * 2;
- int* offsetVector;
- Vector<int, 32> nonReturnedOvector;
- if (ovector) {
- ovector->resize(offsetVectorSize);
- offsetVector = ovector->data();
- } else {
- nonReturnedOvector.resize(offsetVectorSize);
- offsetVector = nonReturnedOvector.data();
- }
+ int offsetVectorSize = (m_numSubpatterns + 1) * 2;
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
- ASSERT(offsetVector);
- // Initialize offsetVector with the return value (index 0) and the
- // first subpattern start indicies (even index values) set to -1.
- // No need to init the subpattern end indicies.
- for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
- offsetVector[j] = -1;
+ ASSERT(offsetVector);
+ // Initialize offsetVector with the return value (index 0) and the
+ // first subpattern start indicies (even index values) set to -1.
+ // No need to init the subpattern end indicies.
+ for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
+ offsetVector[j] = -1;
- int result;
+ int result;
#if ENABLE(YARR_JIT)
- if (m_state == JITCode) {
- if (s.is8Bit())
- result = Yarr::execute(m_representation->m_regExpJITCode, s.characters8(), startOffset, s.length(), offsetVector);
- else
- result = Yarr::execute(m_representation->m_regExpJITCode, s.characters16(), startOffset, s.length(), offsetVector);
+ if (m_state == JITCode) {
+ if (s.is8Bit())
+ result = Yarr::execute(m_representation->m_regExpJITCode, s.characters8(), startOffset, s.length(), offsetVector);
+ else
+ result = Yarr::execute(m_representation->m_regExpJITCode, s.characters16(), startOffset, s.length(), offsetVector);
#if ENABLE(YARR_JIT_DEBUG)
- matchCompareWithInterpreter(s, startOffset, offsetVector, result);
+ matchCompareWithInterpreter(s, startOffset, offsetVector, result);
#endif
- } else
+ } else
#endif
- result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
- ASSERT(result >= -1);
+ result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
+ ASSERT(result >= -1);
#if REGEXP_FUNC_TEST_DATA_GEN
- RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
+ RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
#endif
#if ENABLE(REGEXP_TRACING)
- if (result != -1)
- m_rtMatchFoundCount++;
+ if (result != -1)
+ m_rtMatchFoundCount++;
#endif
- return result;
- }
-
- return -1;
+ return result;
}
void RegExp::invalidateCode()
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (105443 => 105444)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2012-01-19 21:50:52 UTC (rev 105443)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2012-01-19 21:57:11 UTC (rev 105444)
@@ -826,6 +826,8 @@
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec), NoFlags);
+ if (!reg->isValid())
+ return throwVMError(exec, createSyntaxError(exec, reg->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
@@ -876,6 +878,8 @@
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec), NoFlags);
+ if (!reg->isValid())
+ return throwVMError(exec, createSyntaxError(exec, reg->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;