From d347af119f8d913c1fc4e883860722897b00d13a Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Wed, 8 Apr 2020 14:30:21 +0000 Subject: [PATCH] Bug 1607405 - Validate regexp derived from pattern attribute before using it. r=emilio In particular, this correctly treats as invalid patterns like "a)(b" that only "become" valid due to the addition of the (?:) non-capturing group, that's originally used to allow the addition of ^ and $ anchors. Differential Revision: https://phabricator.services.mozilla.com/D70143 --HG-- extra : moz-landing-system : lando --- dom/base/nsContentUtils.cpp | 22 +++++++++++++------ ...lidation-validity-patternMismatch.html.ini | 21 ------------------ 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 4f1f1633c3f1..2c8855b05706 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -6495,6 +6495,19 @@ Maybe nsContentUtils::IsPatternMatching(nsAString& aValue, // regexp evaluation, not actual script execution. JSAutoRealm ar(cx, xpc::UnprivilegedJunkScope()); + // Check if the pattern by itself is valid first, and not that it only becomes + // valid once we add ^(?: and )$. + { + JS::Rooted testRe( + cx, JS::NewUCRegExpObject( + cx, static_cast(aPattern.BeginWriting()), + aPattern.Length(), JS::RegExpFlag::Unicode)); + if (!testRe) { + ReportPatternCompileFailure(aPattern, aDocument, cx); + return Some(true); + } + } + // The pattern has to match the entire value. aPattern.InsertLiteral(u"^(?:", 0); aPattern.AppendLiteral(")$"); @@ -6503,13 +6516,8 @@ Maybe nsContentUtils::IsPatternMatching(nsAString& aValue, cx, JS::NewUCRegExpObject(cx, static_cast(aPattern.BeginWriting()), aPattern.Length(), JS::RegExpFlag::Unicode)); - if (!re) { - // Remove extra patterns added above to report with the original pattern. - aPattern.Cut(0, 4); - aPattern.Cut(aPattern.Length() - 2, 2); - ReportPatternCompileFailure(aPattern, aDocument, cx); - return Some(true); - } + // We checked that the pattern is valid above. + MOZ_ASSERT(re, "Adding ^(?: and )$ shouldn't make a valid regexp invalid"); JS::Rooted rval(cx, JS::NullValue()); size_t idx = 0; diff --git a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html.ini b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html.ini index 43ff614827a8..efb8521b7a94 100644 --- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html.ini +++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html.ini @@ -1,34 +1,13 @@ [form-validation-validity-patternMismatch.html] - [[INPUT in URL status\] The pattern attribute tries to escape a group] - expected: FAIL - - [[INPUT in EMAIL status\] The pattern attribute tries to escape a group] - expected: FAIL - [[INPUT in EMAIL status\] Commas should be stripped from regex input, if multiple is present] expected: FAIL - [[INPUT in SEARCH status\] The pattern attribute tries to escape a group] - expected: FAIL - [[INPUT in EMAIL status\] The pattern attribute uses Unicode features, if multiple is present] expected: FAIL - [[INPUT in TEXT status\] The pattern attribute tries to escape a group] - expected: FAIL - - [[INPUT in TEL status\] The pattern attribute tries to escape a group] - expected: FAIL - - [[INPUT in PASSWORD status\] The pattern attribute tries to escape a group] - expected: FAIL - [[INPUT in EMAIL status\] The value(ABC) in unicode attribute matches the pattern attribute, if multiple is present] expected: FAIL - [[INPUT in EMAIL status\] The pattern attribute tries to escape a group, if multiple is present] - expected: FAIL - [[INPUT in EMAIL status\] The value attribute matches the pattern attribute, if multiple is present] expected: FAIL