webkitgtk/backport-CVE-2023-28204.patch

103 lines
4.5 KiB
Diff
Raw Permalink Normal View History

From e34edaa74575ee13efcebdb7672b949a743ab32a Mon Sep 17 00:00:00 2001
From: Michael Saboff <msaboff@apple.com>
Date: Mon, 3 Apr 2023 20:25:08 -0700
Subject: [PATCH] [JSC] RegExpGlobalData::performMatch issue leading to OOB
read https://bugs.webkit.org/show_bug.cgi?id=254930 rdar://107436732
Reviewed by Alexey Shvayka.
Fixed two issues:
1) In YarrInterpreter.cpp::matchAssertionBOL() we were advancing the string position for non-BMP
characters. Since it is an assertion, we shouldn't advance the character position.
Made the same fix to matchAssertionEOL().
2) In StringPrototype.cpp::replaceUsingRegExpSearch(), we need to advance past both elements of
a non-BMP character for the case where the RegExp match is empty.
* JSTests/stress/string-replace-regexp-matchBOL-correct-advancing.js: New test.
* Source/JavaScriptCore/runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
* Source/JavaScriptCore/yarr/YarrInterpreter.cpp:
(JSC::Yarr::Interpreter::InputStream::readCheckedDontAdvance):
(JSC::Yarr::Interpreter::matchAssertionBOL):
(JSC::Yarr::Interpreter::matchAssertionEOL):
Canonical link: https://commits.webkit.org/259548.551@safari-7615-branch
---
.../runtime/StringPrototype.cpp | 10 ++++++++++
.../JavaScriptCore/yarr/YarrInterpreter.cpp | 19 +++++++++++++++++--
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 08104b1d..459295f7 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -603,6 +603,11 @@ static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(
startPosition++;
if (startPosition > sourceLen)
break;
+ if (U16_IS_LEAD(source[startPosition - 1]) && U16_IS_TRAIL(source[startPosition])) {
+ startPosition++;
+ if (startPosition > sourceLen)
+ break;
+ }
}
}
} else {
@@ -682,6 +687,11 @@ static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(
startPosition++;
if (startPosition > sourceLen)
break;
+ if (U16_IS_LEAD(source[startPosition - 1]) && U16_IS_TRAIL(source[startPosition])) {
+ startPosition++;
+ if (startPosition > sourceLen)
+ break;
+ }
}
} while (global);
}
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
index 95a848a1..d222e620 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
@@ -209,6 +209,21 @@ public:
}
return result;
}
+
+ int readCheckedDontAdvance(unsigned negativePositionOffest)
+ {
+ RELEASE_ASSERT(pos >= negativePositionOffest);
+ unsigned p = pos - negativePositionOffest;
+ ASSERT(p < length);
+ int result = input[p];
+ if (U16_IS_LEAD(result) && decodeSurrogatePairs && p + 1 < length && U16_IS_TRAIL(input[p + 1])) {
+ if (atEnd())
+ return -1;
+
+ result = U16_GET_SUPPLEMENTARY(result, input[p + 1]);
+ }
+ return result;
+ }
int readSurrogatePairChecked(unsigned negativePositionOffset)
{
@@ -482,13 +497,13 @@ public:
bool matchAssertionBOL(ByteTerm& term)
{
- return (input.atStart(term.inputPosition)) || (pattern->multiline() && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition + 1)));
+ return (input.atStart(term.inputPosition)) || (pattern->multiline() && testCharacterClass(pattern->newlineCharacterClass, input.readCheckedDontAdvance(term.inputPosition + 1)));
}
bool matchAssertionEOL(ByteTerm& term)
{
if (term.inputPosition)
- return (input.atEnd(term.inputPosition)) || (pattern->multiline() && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition)));
+ return (input.atEnd(term.inputPosition)) || (pattern->multiline() && testCharacterClass(pattern->newlineCharacterClass, input.readCheckedDontAdvance(term.inputPosition)));
return (input.atEnd()) || (pattern->multiline() && testCharacterClass(pattern->newlineCharacterClass, input.read()));
}
--
2.33.0