Bug 1636495: Use JS::CheckRegExpSyntax in nsContentUtils::IsPatternMatching r=emilio

nsContentUtils::IsPatternMatching calls into SpiderMonkey several times to validate and execute a regexp. It assumes that JS::NewUCRegExpObject can only fail if the pattern is invalid. However, in the case of OOM or stack overflow, this is false.

In the previous patch, we added a new API for pattern matching. This patch uses the new function to clean up the error handling in IsPatternMatching.

Differential Revision: https://phabricator.services.mozilla.com/D74501
This commit is contained in:
Iain Ireland 2020-05-11 17:44:08 +00:00
parent 560559ea48
commit 96b0cd7868

View File

@ -6390,26 +6390,14 @@ nsContentUtils::FindInternalContentViewer(const nsACString& aType,
static void ReportPatternCompileFailure(nsAString& aPattern,
const Document* aDocument,
JS::MutableHandle<JS::Value> error,
JSContext* cx) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
JS::RootedValue exn(cx);
if (!JS_GetPendingException(cx, &exn)) {
return;
}
if (!exn.isObject()) {
// If pending exception is not an object, it should be OOM.
return;
}
JS::AutoSaveExceptionState savedExc(cx);
JS::RootedObject exnObj(cx, &exn.toObject());
JS::RootedObject exnObj(cx, &error.toObject());
JS::RootedValue messageVal(cx);
if (!JS_GetProperty(cx, exnObj, "message", &messageVal)) {
return;
}
MOZ_ASSERT(messageVal.isString());
JS::RootedString messageStr(cx, messageVal.toString());
MOZ_ASSERT(messageStr);
@ -6446,15 +6434,16 @@ Maybe<bool> nsContentUtils::IsPatternMatching(nsAString& aValue,
// Check if the pattern by itself is valid first, and not that it only becomes
// valid once we add ^(?: and )$.
{
JS::Rooted<JSObject*> testRe(
cx, JS::NewUCRegExpObject(
cx, static_cast<char16_t*>(aPattern.BeginWriting()),
aPattern.Length(), JS::RegExpFlag::Unicode));
if (!testRe) {
ReportPatternCompileFailure(aPattern, aDocument, cx);
return Some(true);
}
JS::RootedValue error(cx);
if (!JS::CheckRegExpSyntax(
cx, static_cast<char16_t*>(aPattern.BeginWriting()),
aPattern.Length(), JS::RegExpFlag::Unicode, &error)) {
return Nothing();
}
if (!error.isUndefined()) {
ReportPatternCompileFailure(aPattern, aDocument, &error, cx);
return Some(true);
}
// The pattern has to match the entire value.
@ -6465,8 +6454,9 @@ Maybe<bool> nsContentUtils::IsPatternMatching(nsAString& aValue,
cx,
JS::NewUCRegExpObject(cx, static_cast<char16_t*>(aPattern.BeginWriting()),
aPattern.Length(), JS::RegExpFlag::Unicode));
// We checked that the pattern is valid above.
MOZ_ASSERT(re, "Adding ^(?: and )$ shouldn't make a valid regexp invalid");
if (!re) {
return Nothing();
}
JS::Rooted<JS::Value> rval(cx, JS::NullValue());
size_t idx = 0;