15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_var_deprecated.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_testing_dev.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_var_deprecated.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/dev/scriptable_object_deprecated.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/private/var_private.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t kInvalidLength = static_cast<uint32_t>(-1); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kSetValueFunction[] = "SetValue"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ScriptableObject used by the var tests. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VarScriptableObject : public pp::deprecated::ScriptableObject { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarScriptableObject(TestVarDeprecated* v) : test_var_deprecated_(v) {} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::deprecated::ScriptableObject overrides. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasMethod(const pp::Var& name, pp::Var* exception); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var Call(const pp::Var& name, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<pp::Var>& args, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var* exception); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestVarDeprecated* test_var_deprecated_; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VarScriptableObject::HasMethod(const pp::Var& name, pp::Var* exception) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!name.is_string()) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name.AsString() == kSetValueFunction; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pp::Var VarScriptableObject::Call(const pp::Var& method_name, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<pp::Var>& args, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var* exception) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!method_name.is_string()) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = method_name.AsString(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == kSetValueFunction) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.size() != 1) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *exception = pp::Var("Bad argument to SetValue(<value>)"); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_var_deprecated_->set_var_from_page(pp::VarPrivate(args[0])); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pp::Var(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(VarDeprecated); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestVarDeprecated::Init() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_ = static_cast<const PPB_Var_Deprecated*>( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return var_interface_ && CheckTestingInterface(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVarDeprecated::RunTests(const std::string& filter) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(BasicString, filter); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(InvalidAndEmpty, filter); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(InvalidUtf8, filter); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(NullInputInUtf8Conversion, filter); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(ValidUtf8, filter); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(Utf8WithEmbeddedNulls, filter); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(VarToUtf8ForWrongType, filter); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(HasPropertyAndMethod, filter); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(PassReference, filter); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pp::deprecated::ScriptableObject* TestVarDeprecated::CreateTestObject() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new VarScriptableObject(this); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestBasicString() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t before_object = testing_interface_->GetLiveObjectsForInstance( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kStr[] = "Hello"; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t kStrLen(sizeof(kStr) - 1); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var str = var_interface_->VarFromUtf8(pp::Module::Get()->pp_module(), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStr, kStrLen); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_VARTYPE_STRING, str.type); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reading back the string should work. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t len = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* result = var_interface_->VarToUtf8(str, &len); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kStrLen, len); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, strncmp(kStr, result, kStrLen)); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy the string, readback should now fail. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_->Release(str); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(str, &len); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, len); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(NULL, result); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure nothing leaked. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(testing_interface_->GetLiveObjectsForInstance( 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance()) == before_object); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestInvalidAndEmpty() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var invalid_string; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_string.type = PP_VARTYPE_STRING; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_string.value.as_id = 31415926; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invalid strings should give NULL as the return value. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t len = std::numeric_limits<uint32_t>::max(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* result = var_interface_->VarToUtf8(invalid_string, &len); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, len); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(NULL, result); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same with vars that are not strings. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = std::numeric_limits<uint32_t>::max(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var int_var(42); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(int_var.pp_var(), &len); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, len); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(NULL, result); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty strings should return non-NULL. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var empty_string(""); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = std::numeric_limits<uint32_t>::max(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(empty_string.pp_var(), &len); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, len); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(NULL, result); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestInvalidUtf8() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // utf8じゃない (japanese for "is not utf8") in shift-jis encoding. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kSjisString[] = "utf8\x82\xb6\x82\xe1\x82\xc8\x82\xa2"; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var sjis(kSjisString); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sjis.is_null()) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Non-UTF8 string was permitted erroneously."; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestNullInputInUtf8Conversion() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test talks directly to the C interface to access edge cases that 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cannot be exercised via the C++ interface. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var converted_string; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0-length string should not dereference input string, and should produce 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an empty string. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converted_string = var_interface_->VarFromUtf8( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->pp_module(), NULL, 0); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (converted_string.type != PP_VARTYPE_STRING) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 length to return empty string."; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now convert it back. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t length = kInvalidLength; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* result = NULL; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(converted_string, &length); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 length string on conversion."; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected a non-null result for 0-lengthed string from VarToUtf8."; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_->Release(converted_string); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should not crash, and make an empty string. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* null_string = NULL; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var null_var(null_string); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!null_var.is_string() || null_var.AsString() != "") { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL input to make an empty string Var."; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestValidUtf8() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // From UTF8 string -> PP_Var. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chinese for "I am utf8." 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kValidUtf8[] = "\xe6\x88\x91\xe6\x98\xafutf8."; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var converted_string(kValidUtf8); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (converted_string.is_null()) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Unable to convert valid utf8 to var."; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we're already here, test PP_Var back to UTF8 string. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string returned_string = converted_string.AsString(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to check against 1 less than sizeof because the resulting string 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is technically not NULL terminated by API design. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (returned_string.size() != sizeof(kValidUtf8) - 1) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Unable to convert utf8 string back from var."; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (returned_string != kValidUtf8) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "String mismatches on conversion back from PP_Var."; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestUtf8WithEmbeddedNulls() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // From UTF8 string with embedded nulls -> PP_Var. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chinese for "also utf8." 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kUtf8WithEmbededNull[] = "\xe6\xb9\x9f\xe6\x98\xaf\0utf8."; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string orig_string(kUtf8WithEmbededNull, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kUtf8WithEmbededNull) -1); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var converted_string(orig_string); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (converted_string.is_null()) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Unable to convert utf8 with embedded nulls to var."; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we're already here, test PP_Var back to UTF8 string. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string returned_string = converted_string.AsString(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (returned_string.size() != orig_string.size()) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Unable to convert utf8 with embedded nulls back from var."; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (returned_string != orig_string) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "String mismatches on conversion back from PP_Var."; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestVarToUtf8ForWrongType() { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t length = kInvalidLength; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* result = NULL; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(PP_MakeUndefined(), &length); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 on string conversion from Void var."; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL on string conversion from Void var."; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length = kInvalidLength; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NULL; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(PP_MakeNull(), &length); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 on string conversion from Null var."; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL on string conversion from Null var."; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length = kInvalidLength; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NULL; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(PP_MakeBool(PP_TRUE), &length); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 on string conversion from Bool var."; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL on string conversion from Bool var."; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length = kInvalidLength; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NULL; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(PP_MakeInt32(1), &length); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 on string conversion from Int32 var."; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL on string conversion from Int32 var."; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length = kInvalidLength; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NULL; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = var_interface_->VarToUtf8(PP_MakeDouble(1.0), &length); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length != 0) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected 0 on string conversion from Double var."; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected NULL on string conversion from Double var."; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestHasPropertyAndMethod() { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarPrivate window = instance_->GetWindowObject(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(window.is_object()); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Regular property. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var exception; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(window.HasProperty("scrollX", &exception)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasMethod("scrollX", &exception)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Regular method (also counts as HasProperty). 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(window.HasProperty("find", &exception)); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(window.HasMethod("find", &exception)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nonexistant ones should return false and not set the exception. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasProperty("superEvilBit", &exception)); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasMethod("superEvilBit", &exception)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check exception and return false on invalid property name. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasProperty(3.14159, &exception)); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception = pp::Var(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception = pp::Var(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasMethod(3.14159, &exception)); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to use something not an object. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception = pp::Var(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarPrivate string_object("asdf"); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(string_object.HasProperty("find", &exception)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception = pp::Var(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(string_object.HasMethod("find", &exception)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to use an invalid object (need to use the C API). 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var invalid_object; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_object.type = PP_VARTYPE_OBJECT; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_object.value.as_id = static_cast<int64_t>(-1234567); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var exception2 = PP_MakeUndefined(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(var_interface_->HasProperty(invalid_object, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var("find").pp_var(), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &exception2)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_->Release(exception2); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception2 = PP_MakeUndefined(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(var_interface_->HasMethod(invalid_object, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var("find").pp_var(), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &exception2)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_->Release(exception2); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Getting a valid property/method when the exception is set returns false. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception = pp::Var("Bad something-or-other exception"); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasProperty("find", &exception)); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(window.HasMethod("find", &exception)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(exception.is_undefined()); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that when the page sends an object to the plugin via a function call, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the refcounting works properly (bug 79813). 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestVarDeprecated::TestPassReference() { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_from_page_ = pp::Var(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a JS object from the page to the plugin. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var exception; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var ret = instance_->ExecuteScript( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document.getElementById('plugin').SetValue(function(arg) {" 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return 'works' + arg;" 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})", 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &exception); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(exception.is_undefined()); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have gotten an object set for our var_from_page. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(var_from_page_.is_object()); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the reference counting works, the object should be valid. We can test 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this by executing it (it was a function we defined above) and it should 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return "works" concatenated with the argument. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarPrivate function(var_from_page_); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var result = var_from_page_.Call(pp::Var(), "nice"); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result.is_string()); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result.AsString() == "worksnice"); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset var_from_page_ so it doesn't seem like a leak to the var leak 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // checking code. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_from_page_ = pp::Var(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 397