From 68d6d51d8bf72936dd3921218c2ad8931e141ee0 Mon Sep 17 00:00:00 2001 From: David Klein Date: Fri, 26 Jun 2026 18:54:24 +0000 Subject: [PATCH] Fixed regex exec missing flags --- js/src/builtin/RegExp.cpp | 14 ++++- taint/test/mochitest/mochitest.ini | 1 + taint/test/mochitest/test_regexp_exec.html | 65 ++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 taint/test/mochitest/test_regexp_exec.html diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index b55a1047bb36..83a41dafd27a 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -132,6 +132,18 @@ bool js::CreateRegExpMatchResult(JSContext* cx, HandleRegExpShared re, Rooted src(cx, re->getSource()); RootedString srcStr(cx, EscapeRegExpPattern(cx, src)); + // Foxhound: build the flags string in canonical order (dgimsuvy) so the + // taint operation records the full regular expression, not just its body. + std::u16string flagsStr; + if (re->hasIndices()) flagsStr += 'd'; + if (re->global()) flagsStr += 'g'; + if (re->ignoreCase()) flagsStr += 'i'; + if (re->multiline()) flagsStr += 'm'; + if (re->dotAll()) flagsStr += 's'; + if (re->unicode()) flagsStr += 'u'; + if (re->unicodeSets()) flagsStr += 'v'; + if (re->sticky()) flagsStr += 'y'; + // Steps 28-29 and 33 a-d: Initialize the elements of the match result. // Store a Value for each match pair. for (size_t i = 0; i < numPairs; i++) { @@ -153,7 +165,7 @@ bool js::CreateRegExpMatchResult(JSContext* cx, HandleRegExpShared re, if (str->taint().hasTaint()) { str->taint().extend( TaintOperation("RegExp.prototype.exec", TaintLocationFromContext(cx), - { taintarg_jsstring_full(cx, srcStr), taintarg_jsstring(cx, str), taintarg(cx, i) })); + { taintarg_jsstring_full(cx, srcStr), flagsStr, taintarg_jsstring(cx, str), taintarg(cx, i) })); } arr->setDenseInitializedLength(i + 1); arr->initDenseElement(i, StringValue(str)); diff --git a/taint/test/mochitest/mochitest.ini b/taint/test/mochitest/mochitest.ini index 90b0ac76a830..2bf66b0d28fe 100644 --- a/taint/test/mochitest/mochitest.ini +++ b/taint/test/mochitest/mochitest.ini @@ -63,3 +63,4 @@ scheme = https [test_json_stringify.html] [test_toLowerCase.html] [test_normalize.html] +[test_regexp_exec.html] diff --git a/taint/test/mochitest/test_regexp_exec.html b/taint/test/mochitest/test_regexp_exec.html new file mode 100644 index 000000000000..dcf29f59b2ab --- /dev/null +++ b/taint/test/mochitest/test_regexp_exec.html @@ -0,0 +1,65 @@ + + + + + + Check that the RegExp.prototype.exec taint operation records both the + regular expression body and its flags + + + + + + + + +