+2012-01-19 Geoffrey Garen <ggaren@apple.com>
+
+ 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 <mhahnenberg@apple.com>
Implement a new allocator for backing stores
compile(&globalData, charSize);
}
-
int RegExp::match(JSGlobalData& globalData, const UString& s, int startOffset, Vector<int, 32>* ovector)
{
if (startOffset < 0)
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()
* 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;
* 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;