mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibRegex: Fix crash when parse result exceeds max cache size
Before, If the cache was empty we would try and evict non-existant entries and crash. So the fix is to make sure that we don't saturate the cache with a single parse result.
This commit is contained in:
parent
99df80f81e
commit
83e46b3728
|
|
@ -77,3 +77,7 @@ test("v flag should enable unicode mode", () => {
|
|||
const re = new RegExp("a\\u{10FFFF}", "v");
|
||||
expect(re.test("a\u{10FFFF}")).toBe(true);
|
||||
});
|
||||
|
||||
test("parsing a large bytestring shouldn't crash", () => {
|
||||
RegExp(new Uint8Array(0x40000));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -48,6 +48,20 @@ static size_t s_cached_bytecode_size = 0;
|
|||
|
||||
static constexpr auto MaxRegexCachedBytecodeSize = 1 * MiB;
|
||||
|
||||
template<class Parser>
|
||||
static void cache_parse_result(regex::Parser::Result const& result, CacheKey<Parser> const& key)
|
||||
{
|
||||
auto bytecode_size = result.bytecode.size() * sizeof(ByteCodeValueType);
|
||||
if (bytecode_size > MaxRegexCachedBytecodeSize)
|
||||
return;
|
||||
|
||||
while (bytecode_size + s_cached_bytecode_size<Parser> > MaxRegexCachedBytecodeSize)
|
||||
s_cached_bytecode_size<Parser> -= s_parser_cache<Parser>.take_first().bytecode.size() * sizeof(ByteCodeValueType);
|
||||
|
||||
s_parser_cache<Parser>.set(key, result);
|
||||
s_cached_bytecode_size<Parser> += bytecode_size;
|
||||
}
|
||||
|
||||
template<class Parser>
|
||||
Regex<Parser>::Regex(ByteString pattern, typename ParserTraits<Parser>::OptionsType regex_options)
|
||||
: pattern_value(move(pattern))
|
||||
|
|
@ -61,12 +75,9 @@ Regex<Parser>::Regex(ByteString pattern, typename ParserTraits<Parser>::OptionsT
|
|||
parser_result = parser.parse();
|
||||
|
||||
run_optimization_passes();
|
||||
if (parser_result.error == regex::Error::NoError) {
|
||||
while (parser_result.bytecode.size() * sizeof(ByteCodeValueType) + s_cached_bytecode_size<Parser> > MaxRegexCachedBytecodeSize)
|
||||
s_cached_bytecode_size<Parser> -= s_parser_cache<Parser>.take_first().bytecode.size() * sizeof(ByteCodeValueType);
|
||||
s_parser_cache<Parser>.set({ pattern_value, regex_options }, parser_result);
|
||||
s_cached_bytecode_size<Parser> += parser_result.bytecode.size() * sizeof(ByteCodeValueType);
|
||||
}
|
||||
|
||||
if (parser_result.error == regex::Error::NoError)
|
||||
cache_parse_result<Parser>(parser_result, { pattern_value, regex_options });
|
||||
}
|
||||
|
||||
if (parser_result.error == regex::Error::NoError)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user