diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 3a1163ac0d7..f410012d660 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -18,7 +18,7 @@ use js::jsapi::{
NewUCRegExpObject, ObjectIsDate, RegExpFlag_Unicode, RegExpFlags,
};
use js::jsval::UndefinedValue;
-use js::rust::jsapi_wrapped::{ExecuteRegExpNoStatics, ObjectIsRegExp};
+use js::rust::jsapi_wrapped::{CheckRegExpSyntax, ExecuteRegExpNoStatics, ObjectIsRegExp};
use js::rust::{HandleObject, MutableHandleObject};
use net_traits::blob_url_store::get_blob_origin;
use net_traits::filemanager_thread::FileManagerThreadMsg;
@@ -2917,7 +2917,7 @@ fn round_halves_positive(n: f64) -> f64 {
// https://html.spec.whatwg.org/multipage/#compiled-pattern-regular-expression
fn compile_pattern(cx: SafeJSContext, pattern_str: &str, out_regex: MutableHandleObject) -> bool {
// First check if pattern compiles...
- if new_js_regex(cx, pattern_str, out_regex) {
+ if check_js_regex_syntax(cx, pattern_str) {
// ...and if it does make pattern that matches only the entirety of string
let pattern_str = format!("^(?:{})$", pattern_str);
new_js_regex(cx, &pattern_str, out_regex)
@@ -2926,6 +2926,35 @@ fn compile_pattern(cx: SafeJSContext, pattern_str: &str, out_regex: MutableHandl
}
}
+#[allow(unsafe_code)]
+/// Check if the pattern by itself is valid first, and not that it only becomes
+/// valid once we add ^(?: and )$.
+fn check_js_regex_syntax(cx: SafeJSContext, pattern: &str) -> bool {
+ let pattern: Vec = pattern.encode_utf16().collect();
+ unsafe {
+ rooted!(in(*cx) let mut exception = UndefinedValue());
+
+ let valid = CheckRegExpSyntax(
+ *cx,
+ pattern.as_ptr(),
+ pattern.len(),
+ RegExpFlags {
+ flags_: RegExpFlag_Unicode,
+ },
+ &mut exception.handle_mut(),
+ );
+
+ if !valid {
+ JS_ClearPendingException(*cx);
+ return false;
+ }
+
+ // TODO(cybai): report `exception` to devtools
+ // exception will be `undefined` if the regex is valid
+ exception.is_undefined()
+ }
+}
+
#[allow(unsafe_code)]
fn new_js_regex(cx: SafeJSContext, pattern: &str, mut out_regex: MutableHandleObject) -> bool {
let pattern: Vec = pattern.encode_utf16().collect();