Index: test/cctest/test-strings.cc |
=================================================================== |
--- test/cctest/test-strings.cc (revision 1687) |
+++ test/cctest/test-strings.cc (working copy) |
@@ -387,3 +387,60 @@ |
CHECK_EQ(kNoChar, buffer[j]); |
} |
} |
+ |
+ |
+class TwoByteResource: public v8::String::ExternalStringResource { |
+ public: |
+ explicit TwoByteResource(const uint16_t* data, size_t length) |
+ : data_(data), length_(length) { } |
+ virtual ~TwoByteResource() { } |
+ |
+ const uint16_t* data() const { return data_; } |
+ size_t length() const { return length_; } |
+ |
+ private: |
+ const uint16_t* data_; |
+ size_t length_; |
+}; |
+ |
+ |
+TEST(ExternalCrBug9746) { |
+ InitializeVM(); |
+ v8::HandleScope handle_scope; |
+ |
+ // This set of tests verifies that the workaround for Chromium bug 9746 |
+ // works correctly. In certain situations the external resource of a symbol |
+ // is collected while the symbol is still part of the symbol table. |
+ static uint16_t two_byte_data[] = { |
+ 't', 'w', 'o', '-', 'b', 'y', 't', 'e', ' ', 'd', 'a', 't', 'a' |
+ }; |
+ static size_t two_byte_length = |
+ sizeof(two_byte_data) / sizeof(two_byte_data[0]); |
+ static const char* one_byte_data = "two-byte data"; |
+ |
+ // Allocate an external string resource and external string. |
+ TwoByteResource* resource = new TwoByteResource(two_byte_data, |
+ two_byte_length); |
+ Handle<String> string = Factory::NewExternalStringFromTwoByte(resource); |
+ Vector<const char> one_byte_vec = CStrVector(one_byte_data); |
+ Handle<String> compare = Factory::NewStringFromAscii(one_byte_vec); |
+ |
+ // Verify the correct behaviour before "collecting" the external resource. |
+ CHECK(string->IsEqualTo(one_byte_vec)); |
+ CHECK(string->Equals(*compare)); |
+ |
+ // "Collect" the external resource manually by setting the external resource |
+ // pointer to NULL. Then redo the comparisons, they should not match AND |
+ // not crash. |
+ Handle<ExternalTwoByteString> external(ExternalTwoByteString::cast(*string)); |
+ external->set_resource(NULL); |
+ CHECK_EQ(false, string->IsEqualTo(one_byte_vec)); |
+#if !defined(DEBUG) |
+ // These tests only work in non-debug as there are ASSERTs in the code that |
+ // do prevent the ability to even get into the broken code when running the |
+ // debug version of V8. |
+ CHECK_EQ(false, string->Equals(*compare)); |
+ CHECK_EQ(false, compare->Equals(*string)); |
+ CHECK_EQ(false, string->Equals(Heap::empty_string())); |
+#endif // !defined(DEBUG) |
+} |