[regexp] Fix oob read in JSRegExp::HasCompiledCode

The JSRegExp's data fixed array is variable size depending on the
regexp kind.

Bug: v8:8572
Change-Id: I8f07b8e8d2a9a81e0905563fb701e1e3687cafb5
Reviewed-on: https://chromium-review.googlesource.com/c/1405034
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58741}
This commit is contained in:
Jakob Gruber 2019-01-10 15:49:55 +01:00 committed by Commit Bot
parent f3a23accad
commit 3c24404675
2 changed files with 17 additions and 8 deletions

View File

@ -79,8 +79,8 @@ void JSRegExp::SetDataAt(int index, Object value) {
}
bool JSRegExp::HasCompiledCode() const {
return DataAt(kIrregexpLatin1CodeIndex)->IsCode() ||
DataAt(kIrregexpUC16CodeIndex)->IsCode();
return TypeTag() == IRREGEXP && (DataAt(kIrregexpLatin1CodeIndex)->IsCode() ||
DataAt(kIrregexpUC16CodeIndex)->IsCode());
}
void JSRegExp::DiscardCompiledCodeForSerialization() {

View File

@ -831,11 +831,13 @@ void TestCustomSnapshotDataBlobWithIrregexpCode(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling) {
DisableAlwaysOpt();
const char* source =
"var re = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//;\n"
"function f() { return '/* a comment */'.search(re); }\n"
"function g() { return 'not a comment'.search(re); }\n"
"function h() { return '// this is a comment'.search(re); }\n"
"f(); f(); g(); g();";
"var re1 = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//;\n"
"function f() { return '/* a comment */'.search(re1); }\n"
"function g() { return 'not a comment'.search(re1); }\n"
"function h() { return '// this is a comment'.search(re1); }\n"
"var re2 = /a/;\n"
"function i() { return '/* a comment */'.search(re2); }\n"
"f(); f(); g(); g(); h(); h(); i(); i();\n";
v8::StartupData data1 =
CreateSnapshotDataBlob(function_code_handling, source);
@ -855,7 +857,7 @@ void TestCustomSnapshotDataBlobWithIrregexpCode(
// Check that compiled irregexp code has not been flushed prior to
// serialization.
i::Handle<i::JSRegExp> re =
Utils::OpenHandle(*CompileRun("re").As<v8::RegExp>());
Utils::OpenHandle(*CompileRun("re1").As<v8::RegExp>());
CHECK_EQ(re->HasCompiledCode(),
function_code_handling ==
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
@ -875,6 +877,13 @@ void TestCustomSnapshotDataBlobWithIrregexpCode(
CompileRun("h()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(-1, result.FromJust());
}
{
// Check that ATOM regexp remains valid.
i::Handle<i::JSRegExp> re =
Utils::OpenHandle(*CompileRun("re2").As<v8::RegExp>());
CHECK_EQ(re->TypeTag(), JSRegExp::ATOM);
CHECK(!re->HasCompiledCode());
}
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.