Index: test/cctest/test-strings.cc |
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc |
index 344fa2fe561d5018e0a0198ac8b46f2a64f8cb65..9793ae7f18fdd51dbef9d26e3566963b75247cb4 100644 |
--- a/test/cctest/test-strings.cc |
+++ b/test/cctest/test-strings.cc |
@@ -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 { |