Skip to content

Commit

Permalink
heap-use-after-free | JSC::RegExpObject::execInline; JSC::regExpProto…
Browse files Browse the repository at this point in the history
…FuncExec

https://bugs.webkit.org/show_bug.cgi?id=259143
rdar://111502448

Reviewed by Yusuke Suzuki.

Fixed the saving and restoring of duplicate groups IDs for nested / counted Parens in the YARR
interpreter.  We only save the number of duplicate groups needed for the current parenthesis.
We were using the duplicate groups ID, which may exceed the number of duplicate IDs we need to
save.  Changed the code to save these ID using a counted index instead of their actual value.
Added an ASSERT in backupOffsetForDuplicateNamedGroup() where we calculate the offset in the
saved context buffer.

Added a new regression test case.

* JSTests/stress/regexp-duplicate-named-captures.js:
* Source/JavaScriptCore/yarr/YarrInterpreter.cpp:
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::ParenthesesDisjunctionContext):
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::restoreOutput):
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::backupOffsetForDuplicateNamedGroup):

Canonical link: https://commits.webkit.org/266009@main
  • Loading branch information
msaboff committed Jul 12, 2023
1 parent ecc7e57 commit 9257a50
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 5 deletions.
1 change: 1 addition & 0 deletions JSTests/stress/regexp-duplicate-named-captures.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,4 @@ testRegExp(/(?<A>)|(?<A>)*\k<A>/, "", ["", "", undefined], { A: "" });

// Test 31
testRegExp(/(?:(?<A>a)|(?<A>b)*)\k<A>/, "bb", ["bb",undefined,"b"], { A: "b" });
testRegExp(/((?<A>A+)(?<B>B+)(?<C>C+)(?<D>D+))+|((?<B>B+)(?<C>C+)(?<D>D+))+|((?<A>A+)(?<C>C+)(?<D>D+))+|((?<C>C+)(?<D>D+))+|((?<B>B+)(?<D>D+))+|((?<A>A+)(?<D>D+))+|((?<D>D+))/, "AAD", ["AAD", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "AAD", "AA", "D", undefined, undefined], { A: "AA", B: undefined, C: undefined, D: "D" });
16 changes: 11 additions & 5 deletions Source/JavaScriptCore/yarr/YarrInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ class Interpreter {
output[(firstSubpatternId << 1) + i] = offsetNoMatch;
}

unsigned nameGroupIdx = 0;
for (unsigned duplicateNamedGroupId : m_duplicateNamedGroups) {
subpatternAndGroupIdBackup[backupOffsetForDuplicateNamedGroup(duplicateNamedGroupId)] = output[m_pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)];
subpatternAndGroupIdBackup[backupOffsetForDuplicateNamedGroup(nameGroupIdx)] = output[m_pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)];
output[pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)] = 0;
++nameGroupIdx;
}

new (getDisjunctionContext()) DisjunctionContext();
Expand All @@ -167,8 +169,11 @@ class Interpreter {
for (unsigned i = 0; i < (m_numNestedSubpatterns << 1); ++i)
output[(firstSubpatternId << 1) + i] = subpatternAndGroupIdBackup[i];

for (unsigned duplicateNamedGroupId : m_duplicateNamedGroups)
output[m_pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)] = subpatternAndGroupIdBackup[backupOffsetForDuplicateNamedGroup(duplicateNamedGroupId)];
unsigned nameGroupIdx = 0;
for (unsigned duplicateNamedGroupId : m_duplicateNamedGroups) {
output[m_pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)] = subpatternAndGroupIdBackup[backupOffsetForDuplicateNamedGroup(nameGroupIdx)];
++nameGroupIdx;
}
}

DisjunctionContext* getDisjunctionContext()
Expand All @@ -178,8 +183,9 @@ class Interpreter {

unsigned backupOffsetForDuplicateNamedGroup(unsigned duplicateNamedGroup)
{
ASSERT(duplicateNamedGroup);
return (m_numNestedSubpatterns << 1) + duplicateNamedGroup - 1;
unsigned offset = (m_numNestedSubpatterns << 1) + duplicateNamedGroup;
ASSERT(offset < m_numBackupIds);
return offset;
}

static size_t allocationSize(unsigned numberOfSubpatterns, unsigned numDuplicateNamedGroups)
Expand Down

0 comments on commit 9257a50

Please sign in to comment.