From 575cdbbd31a438eee875597a508d9c72c56b793f Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 18 Jul 2013 18:09:09 +0000 Subject: [PATCH] Fix crash when using empty V8 strings with bindings (issue #1015). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1308 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/renderer/v8_impl.cc | 5 +- tests/unittests/v8_unittest.cc | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/libcef/renderer/v8_impl.cc b/libcef/renderer/v8_impl.cc index 408704706..ce25b55a3 100644 --- a/libcef/renderer/v8_impl.cc +++ b/libcef/renderer/v8_impl.cc @@ -1276,9 +1276,12 @@ void CefV8ValueImpl::InitString(CefString& value) { const cef_string_t* str = value.GetStruct(); if (str) { string_value_ = *str; - value.GetWritableStruct()->str = NULL; + cef_string_t* writable_struct = value.GetWritableStruct(); + writable_struct->str = NULL; + writable_struct->length = 0; } else { string_value_.str = NULL; + string_value_.length = 0; } } diff --git a/tests/unittests/v8_unittest.cc b/tests/unittests/v8_unittest.cc index 2c96b1ada..5053622ca 100644 --- a/tests/unittests/v8_unittest.cc +++ b/tests/unittests/v8_unittest.cc @@ -44,6 +44,7 @@ enum V8TestMode { V8TEST_DOUBLE_CREATE, V8TEST_DATE_CREATE, V8TEST_STRING_CREATE, + V8TEST_EMPTY_STRING_CREATE, V8TEST_ARRAY_CREATE, V8TEST_ARRAY_VALUE, V8TEST_OBJECT_CREATE, @@ -65,6 +66,7 @@ enum V8TestMode { V8TEST_FUNCTION_HANDLER_FAIL, V8TEST_FUNCTION_HANDLER_NO_OBJECT, V8TEST_FUNCTION_HANDLER_WITH_CONTEXT, + V8TEST_FUNCTION_HANDLER_EMPTY_STRING, V8TEST_CONTEXT_EVAL, V8TEST_CONTEXT_EVAL_EXCEPTION, V8TEST_CONTEXT_ENTERED, @@ -134,6 +136,9 @@ class V8RendererTest : public ClientApp::RenderDelegate { case V8TEST_STRING_CREATE: RunStringCreateTest(); break; + case V8TEST_EMPTY_STRING_CREATE: + RunEmptyStringCreateTest(); + break; case V8TEST_ARRAY_CREATE: RunArrayCreateTest(); break; @@ -197,6 +202,9 @@ class V8RendererTest : public ClientApp::RenderDelegate { case V8TEST_FUNCTION_HANDLER_WITH_CONTEXT: RunFunctionHandlerWithContextTest(); break; + case V8TEST_FUNCTION_HANDLER_EMPTY_STRING: + RunFunctionHandlerEmptyStringTest(); + break; case V8TEST_CONTEXT_EVAL: RunContextEvalTest(); break; @@ -403,6 +411,26 @@ class V8RendererTest : public ClientApp::RenderDelegate { DestroyTest(); } + void RunEmptyStringCreateTest() { + CefRefPtr value = CefV8Value::CreateString(CefString()); + EXPECT_TRUE(value.get()); + EXPECT_TRUE(value->IsString()); + EXPECT_STREQ("", value->GetStringValue().ToString().c_str()); + + EXPECT_FALSE(value->IsUndefined()); + EXPECT_FALSE(value->IsArray()); + EXPECT_FALSE(value->IsBool()); + EXPECT_FALSE(value->IsDate()); + EXPECT_FALSE(value->IsDouble()); + EXPECT_FALSE(value->IsFunction()); + EXPECT_FALSE(value->IsInt()); + EXPECT_FALSE(value->IsUInt()); + EXPECT_FALSE(value->IsNull()); + EXPECT_FALSE(value->IsObject()); + + DestroyTest(); + } + void RunArrayCreateTest() { CefRefPtr context = GetContext(); @@ -1421,6 +1449,66 @@ class V8RendererTest : public ClientApp::RenderDelegate { DestroyTest(); } + void RunFunctionHandlerEmptyStringTest() { + CefRefPtr context = GetContext(); + + class Handler : public CefV8Handler { + public: + Handler() {} + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE { + EXPECT_TRUE(object.get()); + CefRefPtr context = CefV8Context::GetCurrentContext(); + EXPECT_TRUE(context.get()); + CefRefPtr global = context->GetGlobal(); + EXPECT_TRUE(global.get()); + EXPECT_TRUE(global->IsSame(object)); + + EXPECT_EQ((size_t)1, arguments.size()); + EXPECT_TRUE(arguments[0]->IsString()); + EXPECT_STREQ("", arguments[0]->GetStringValue().ToString().c_str()); + + retval = CefV8Value::CreateString(CefString()); + + got_execute_.yes(); + return true; + } + + TrackCallback got_execute_; + + IMPLEMENT_REFCOUNTING(Handler); + }; + + // Enter the V8 context. + EXPECT_TRUE(context->Enter()); + + Handler* handler = new Handler; + CefRefPtr handlerPtr(handler); + + CefRefPtr func = + CefV8Value::CreateFunction("myfunc", handler); + EXPECT_TRUE(func.get()); + + CefV8ValueList args; + args.push_back(CefV8Value::CreateString(CefString())); + + CefRefPtr retval = func->ExecuteFunction(NULL, args); + EXPECT_TRUE(handler->got_execute_); + EXPECT_TRUE(retval.get()); + EXPECT_FALSE(func->HasException()); + + EXPECT_TRUE(retval->IsString()); + EXPECT_STREQ("", retval->GetStringValue().ToString().c_str()); + + // Exit the V8 context. + EXPECT_TRUE(context->Exit()); + + DestroyTest(); + } + void RunContextEvalTest() { CefRefPtr context = GetContext(); @@ -2071,6 +2159,7 @@ V8_TEST(UIntCreate, V8TEST_UINT_CREATE); V8_TEST(DoubleCreate, V8TEST_DOUBLE_CREATE); V8_TEST(DateCreate, V8TEST_DATE_CREATE); V8_TEST(StringCreate, V8TEST_STRING_CREATE); +V8_TEST(EmptyStringCreate, V8TEST_EMPTY_STRING_CREATE); V8_TEST(ArrayCreate, V8TEST_ARRAY_CREATE); V8_TEST(ArrayValue, V8TEST_ARRAY_VALUE); V8_TEST(ObjectCreate, V8TEST_OBJECT_CREATE); @@ -2092,6 +2181,7 @@ V8_TEST(FunctionHandlerException, V8TEST_FUNCTION_HANDLER_EXCEPTION); V8_TEST(FunctionHandlerFail, V8TEST_FUNCTION_HANDLER_FAIL); V8_TEST(FunctionHandlerNoObject, V8TEST_FUNCTION_HANDLER_NO_OBJECT); V8_TEST(FunctionHandlerWithContext, V8TEST_FUNCTION_HANDLER_WITH_CONTEXT); +V8_TEST(FunctionHandlerEmptyString, V8TEST_FUNCTION_HANDLER_EMPTY_STRING); V8_TEST(ContextEval, V8TEST_CONTEXT_EVAL); V8_TEST(ContextEvalException, V8TEST_CONTEXT_EVAL_EXCEPTION); V8_TEST_EX(ContextEntered, V8TEST_CONTEXT_ENTERED, NULL);