Commit 0ce95e08 authored by jgruber's avatar jgruber Committed by Commit bot

[stubs] Add a test for canary crashes in SubStringStub

These crashes were caused by an invalid pointer stored in a tagged
variable in SubStringStub. This can be reproduced by calling the stub on
an external string and ensuring GC kicks in on the subsequent
allocation.

Only the TurboFan implementation of SubStringStub is affected, the current
PlatformStub implementation handles this case just fine.

BUG=chromium:649967

Review-Url: https://codereview.chromium.org/2374603003
Cr-Commit-Position: refs/heads/master@{#39772}
parent bda4774c
......@@ -40,6 +40,7 @@
#include "src/objects.h"
#include "src/unicode-decoder.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
// Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry
class MyRandomNumberGenerator {
......@@ -1319,6 +1320,46 @@ TEST(RobustSubStringStub) {
CheckException("%_SubString(slice, 0, 17);");
}
TEST(RobustSubStringStubExternalStrings) {
// Ensure that the specific combination of calling the SubStringStub on an
// external string and triggering a GC on string allocation does not crash.
// See crbug.com/649967.
FLAG_allow_natives_syntax = true;
#ifdef VERIFY_HEAP
FLAG_verify_heap = true;
#endif
CcTest::InitializeVM();
v8::HandleScope handle_scope(CcTest::isolate());
v8::Local<v8::String> underlying =
CompileRun(
"var str = 'abcdefghijklmnopqrstuvwxyz';"
"str")
->ToString(CcTest::isolate()->GetCurrentContext())
.ToLocalChecked();
CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString());
const int length = underlying->Length();
uc16* two_byte = NewArray<uc16>(length + 1);
underlying->Write(two_byte);
Resource* resource = new Resource(two_byte, length);
CHECK(underlying->MakeExternal(resource));
CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalTwoByteString());
v8::Local<v8::Script> script = v8_compile(v8_str("%_SubString(str, 5, 8)"));
// Trigger a GC on string allocation.
i::heap::SimulateFullSpace(CcTest::heap()->new_space());
v8::Local<v8::Value> result;
CHECK(script->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
.ToLocal(&result));
Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result));
CHECK_EQ(0, strcmp("fgh", string->ToCString().get()));
}
namespace {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment