test_char_set.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ppapi/tests/test_char_set.h"
  5. #include "ppapi/c/dev/ppb_char_set_dev.h"
  6. #include "ppapi/c/trusted/ppb_char_set_trusted.h"
  7. #include "ppapi/cpp/dev/memory_dev.h"
  8. #include "ppapi/cpp/module.h"
  9. #include "ppapi/tests/testing_instance.h"
  10. REGISTER_TEST_CASE(CharSet);
  11. TestCharSet::TestCharSet(TestingInstance* instance)
  12. : TestCase(instance),
  13. char_set_interface_(NULL) {
  14. }
  15. bool TestCharSet::Init() {
  16. char_set_interface_ = static_cast<const PPB_CharSet_Dev*>(
  17. pp::Module::Get()->GetBrowserInterface(PPB_CHAR_SET_DEV_INTERFACE));
  18. char_set_trusted_interface_ = static_cast<const PPB_CharSet_Trusted*>(
  19. pp::Module::Get()->GetBrowserInterface(PPB_CHARSET_TRUSTED_INTERFACE));
  20. return char_set_interface_ && char_set_trusted_interface_;
  21. }
  22. void TestCharSet::RunTests(const std::string& filter) {
  23. RUN_TEST(UTF16ToCharSetDeprecated, filter);
  24. RUN_TEST(UTF16ToCharSet, filter);
  25. RUN_TEST(CharSetToUTF16Deprecated, filter);
  26. RUN_TEST(CharSetToUTF16, filter);
  27. RUN_TEST(GetDefaultCharSet, filter);
  28. }
  29. // TODO(brettw) remove this when the old interface is removed.
  30. std::string TestCharSet::TestUTF16ToCharSetDeprecated() {
  31. // Empty string.
  32. std::vector<uint16_t> utf16;
  33. utf16.push_back(0);
  34. uint32_t utf8result_len = 0;
  35. pp::Memory_Dev memory;
  36. char* utf8result = char_set_interface_->UTF16ToCharSet(
  37. instance_->pp_instance(), &utf16[0], 0, "latin1",
  38. PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
  39. ASSERT_TRUE(utf8result);
  40. ASSERT_TRUE(utf8result[0] == 0);
  41. ASSERT_TRUE(utf8result_len == 0);
  42. memory.MemFree(utf8result);
  43. // Try round-tripping some English & Chinese from UTF-8 through UTF-16
  44. std::string utf8source("Hello, world. \xe4\xbd\xa0\xe5\xa5\xbd");
  45. utf16 = UTF8ToUTF16(utf8source);
  46. utf8result = char_set_interface_->UTF16ToCharSet(
  47. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  48. "Utf-8", PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
  49. ASSERT_TRUE(utf8source == std::string(utf8result, utf8result_len));
  50. memory.MemFree(utf8result);
  51. // Test an un-encodable character with various modes.
  52. utf16 = UTF8ToUTF16("h\xe4\xbd\xa0i");
  53. // Fail mode.
  54. utf8result_len = 1234; // Test that this gets 0'ed on failure.
  55. utf8result = char_set_interface_->UTF16ToCharSet(
  56. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  57. "latin1", PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
  58. ASSERT_TRUE(utf8result_len == 0);
  59. ASSERT_TRUE(utf8result == NULL);
  60. // Skip mode.
  61. utf8result = char_set_interface_->UTF16ToCharSet(
  62. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  63. "latin1", PP_CHARSET_CONVERSIONERROR_SKIP, &utf8result_len);
  64. ASSERT_TRUE(utf8result_len == 2);
  65. ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == 'i' &&
  66. utf8result[2] == 0);
  67. memory.MemFree(utf8result);
  68. // Substitute mode.
  69. utf8result = char_set_interface_->UTF16ToCharSet(
  70. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  71. "latin1", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
  72. ASSERT_TRUE(utf8result_len == 3);
  73. ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == '?' &&
  74. utf8result[2] == 'i' && utf8result[3] == 0);
  75. memory.MemFree(utf8result);
  76. // Try some invalid input encoding.
  77. utf16.clear();
  78. utf16.push_back(0xD800); // High surrogate.
  79. utf16.push_back('A'); // Not a low surrogate.
  80. utf8result = char_set_interface_->UTF16ToCharSet(
  81. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  82. "latin1", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
  83. ASSERT_TRUE(utf8result_len == 2);
  84. ASSERT_TRUE(utf8result[0] == '?' && utf8result[1] == 'A' &&
  85. utf8result[2] == 0);
  86. memory.MemFree(utf8result);
  87. // Invalid encoding name.
  88. utf8result = char_set_interface_->UTF16ToCharSet(
  89. instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
  90. "poopiepants", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
  91. ASSERT_TRUE(!utf8result);
  92. ASSERT_TRUE(utf8result_len == 0);
  93. PASS();
  94. }
  95. std::string TestCharSet::TestUTF16ToCharSet() {
  96. // Empty string.
  97. std::vector<uint16_t> utf16;
  98. utf16.push_back(0);
  99. std::string output_buffer;
  100. output_buffer.resize(1);
  101. uint32_t utf8result_len = 0;
  102. PP_Bool result = char_set_trusted_interface_->UTF16ToCharSet(
  103. &utf16[0], 0, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  104. &output_buffer[0], &utf8result_len);
  105. ASSERT_TRUE(result == PP_TRUE);
  106. ASSERT_TRUE(utf8result_len == 0);
  107. // No output buffer returns length of string.
  108. utf16 = UTF8ToUTF16("hello");
  109. utf8result_len = 0;
  110. result = char_set_trusted_interface_->UTF16ToCharSet(
  111. &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
  112. PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE, NULL, &utf8result_len);
  113. ASSERT_TRUE(result == PP_TRUE);
  114. ASSERT_TRUE(utf8result_len == 5);
  115. // Giving too small of a buffer just fills in that many items and gives us
  116. // the desired size.
  117. output_buffer.resize(100);
  118. utf8result_len = 2;
  119. output_buffer[utf8result_len] = '$'; // Barrier character.
  120. result = char_set_trusted_interface_->UTF16ToCharSet(
  121. &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
  122. PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  123. &output_buffer[0], &utf8result_len);
  124. ASSERT_TRUE(result == PP_TRUE);
  125. ASSERT_TRUE(utf8result_len == 5);
  126. ASSERT_TRUE(output_buffer[0] == 'h' && output_buffer[1] == 'e' &&
  127. output_buffer[2] == '$');
  128. // Try round-tripping some English & Chinese from UTF-8 through UTF-16
  129. std::string utf8source("Hello, world. \xe4\xbd\xa0\xe5\xa5\xbd");
  130. utf16 = UTF8ToUTF16(utf8source);
  131. output_buffer.resize(100);
  132. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  133. result = char_set_trusted_interface_->UTF16ToCharSet(
  134. &utf16[0], static_cast<uint32_t>(utf16.size()),
  135. "Utf-8", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
  136. &output_buffer[0], &utf8result_len);
  137. ASSERT_TRUE(result == PP_TRUE);
  138. output_buffer.resize(utf8result_len);
  139. ASSERT_TRUE(utf8source == output_buffer);
  140. // Test an un-encodable character with various modes.
  141. utf16 = UTF8ToUTF16("h\xe4\xbd\xa0i");
  142. // Fail mode, size should get 0'ed on failure.
  143. output_buffer.resize(100);
  144. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  145. result = char_set_trusted_interface_->UTF16ToCharSet(
  146. &utf16[0], static_cast<uint32_t>(utf16.size()),
  147. "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
  148. &output_buffer[0], &utf8result_len);
  149. ASSERT_TRUE(result == PP_FALSE);
  150. ASSERT_TRUE(utf8result_len == 0);
  151. // Skip mode.
  152. output_buffer.resize(100);
  153. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  154. result = char_set_trusted_interface_->UTF16ToCharSet(
  155. &utf16[0], static_cast<uint32_t>(utf16.size()),
  156. "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP,
  157. &output_buffer[0], &utf8result_len);
  158. ASSERT_TRUE(result == PP_TRUE);
  159. ASSERT_TRUE(utf8result_len == 2);
  160. ASSERT_TRUE(output_buffer[0] == 'h' && output_buffer[1] == 'i');
  161. // Substitute mode.
  162. output_buffer.resize(100);
  163. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  164. result = char_set_trusted_interface_->UTF16ToCharSet(
  165. &utf16[0], static_cast<uint32_t>(utf16.size()),
  166. "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  167. &output_buffer[0], &utf8result_len);
  168. ASSERT_TRUE(result == PP_TRUE);
  169. ASSERT_TRUE(utf8result_len == 3);
  170. output_buffer.resize(utf8result_len);
  171. ASSERT_TRUE(output_buffer == "h?i");
  172. // Try some invalid input encoding.
  173. output_buffer.resize(100);
  174. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  175. utf16.clear();
  176. utf16.push_back(0xD800); // High surrogate.
  177. utf16.push_back('A'); // Not a low surrogate.
  178. result = char_set_trusted_interface_->UTF16ToCharSet(
  179. &utf16[0], static_cast<uint32_t>(utf16.size()),
  180. "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  181. &output_buffer[0], &utf8result_len);
  182. ASSERT_TRUE(result == PP_TRUE);
  183. ASSERT_TRUE(utf8result_len == 2);
  184. ASSERT_TRUE(output_buffer[0] == '?' && output_buffer[1] == 'A');
  185. // Invalid encoding name.
  186. output_buffer.resize(100);
  187. utf8result_len = static_cast<uint32_t>(output_buffer.size());
  188. result = char_set_trusted_interface_->UTF16ToCharSet(
  189. &utf16[0], static_cast<uint32_t>(utf16.size()),
  190. "poopiepants", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  191. &output_buffer[0], &utf8result_len);
  192. ASSERT_TRUE(result == PP_FALSE);
  193. ASSERT_TRUE(utf8result_len == 0);
  194. PASS();
  195. }
  196. // TODO(brettw) remove this when the old interface is removed.
  197. std::string TestCharSet::TestCharSetToUTF16Deprecated() {
  198. pp::Memory_Dev memory;
  199. // Empty string.
  200. uint32_t utf16result_len;
  201. uint16_t* utf16result = char_set_interface_->CharSetToUTF16(
  202. instance_->pp_instance(), "", 0, "latin1",
  203. PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
  204. ASSERT_TRUE(utf16result);
  205. ASSERT_TRUE(utf16result_len == 0);
  206. ASSERT_TRUE(utf16result[0] == 0);
  207. memory.MemFree(utf16result);
  208. // Basic Latin1.
  209. char latin1[] = "H\xef";
  210. utf16result = char_set_interface_->CharSetToUTF16(
  211. instance_->pp_instance(), latin1, 2, "latin1",
  212. PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
  213. ASSERT_TRUE(utf16result);
  214. ASSERT_TRUE(utf16result_len == 2);
  215. ASSERT_TRUE(utf16result[0] == 'H' && utf16result[1] == 0xef &&
  216. utf16result[2] == 0);
  217. memory.MemFree(utf16result);
  218. // Invalid input encoding with FAIL.
  219. char badutf8[] = "A\xe4Z";
  220. utf16result = char_set_interface_->CharSetToUTF16(
  221. instance_->pp_instance(), badutf8, 3, "utf8",
  222. PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
  223. ASSERT_TRUE(!utf16result);
  224. ASSERT_TRUE(utf16result_len == 0);
  225. memory.MemFree(utf16result);
  226. // Invalid input with SKIP.
  227. utf16result = char_set_interface_->CharSetToUTF16(
  228. instance_->pp_instance(), badutf8, 3, "utf8",
  229. PP_CHARSET_CONVERSIONERROR_SKIP, &utf16result_len);
  230. ASSERT_TRUE(utf16result);
  231. ASSERT_TRUE(utf16result_len == 2);
  232. ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 'Z' &&
  233. utf16result[2] == 0);
  234. memory.MemFree(utf16result);
  235. // Invalid input with SUBSTITUTE.
  236. utf16result = char_set_interface_->CharSetToUTF16(
  237. instance_->pp_instance(), badutf8, 3, "utf8",
  238. PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf16result_len);
  239. ASSERT_TRUE(utf16result);
  240. ASSERT_TRUE(utf16result_len == 3);
  241. ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 0xFFFD &&
  242. utf16result[2] == 'Z' && utf16result[3] == 0);
  243. memory.MemFree(utf16result);
  244. // Invalid encoding name.
  245. utf16result = char_set_interface_->CharSetToUTF16(
  246. instance_->pp_instance(), badutf8, 3, "poopiepants",
  247. PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf16result_len);
  248. ASSERT_TRUE(!utf16result);
  249. ASSERT_TRUE(utf16result_len == 0);
  250. memory.MemFree(utf16result);
  251. PASS();
  252. }
  253. std::string TestCharSet::TestCharSetToUTF16() {
  254. std::vector<uint16_t> output_buffer;
  255. output_buffer.resize(100);
  256. // Empty string.
  257. output_buffer.resize(100);
  258. uint32_t utf16result_len = static_cast<uint32_t>(output_buffer.size());
  259. PP_Bool result = char_set_trusted_interface_->CharSetToUTF16(
  260. "", 0, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
  261. &output_buffer[0], &utf16result_len);
  262. ASSERT_TRUE(result);
  263. ASSERT_TRUE(utf16result_len == 0);
  264. ASSERT_TRUE(output_buffer[0] == 0);
  265. // Basic Latin1.
  266. output_buffer.resize(100);
  267. utf16result_len = static_cast<uint32_t>(output_buffer.size());
  268. char latin1[] = "H\xef";
  269. result = char_set_trusted_interface_->CharSetToUTF16(
  270. latin1, 2, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
  271. &output_buffer[0], &utf16result_len);
  272. ASSERT_TRUE(result);
  273. ASSERT_TRUE(utf16result_len == 2);
  274. ASSERT_TRUE(output_buffer[0] == 'H' && output_buffer[1] == 0xef);
  275. // Invalid input encoding with FAIL.
  276. output_buffer.resize(100);
  277. utf16result_len = static_cast<uint32_t>(output_buffer.size());
  278. char badutf8[] = "A\xe4Z";
  279. result = char_set_trusted_interface_->CharSetToUTF16(
  280. badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
  281. &output_buffer[0], &utf16result_len);
  282. ASSERT_TRUE(!result);
  283. ASSERT_TRUE(utf16result_len == 0);
  284. // Invalid input with SKIP.
  285. output_buffer.resize(100);
  286. utf16result_len = static_cast<uint32_t>(output_buffer.size());
  287. result = char_set_trusted_interface_->CharSetToUTF16(
  288. badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP,
  289. &output_buffer[0], &utf16result_len);
  290. ASSERT_TRUE(result);
  291. ASSERT_TRUE(utf16result_len == 2);
  292. ASSERT_TRUE(output_buffer[0] == 'A' && output_buffer[1] == 'Z');
  293. // Invalid input with SUBSTITUTE.
  294. output_buffer.resize(100);
  295. utf16result_len = static_cast<uint32_t>(output_buffer.size());
  296. result = char_set_trusted_interface_->CharSetToUTF16(
  297. badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  298. &output_buffer[0], &utf16result_len);
  299. ASSERT_TRUE(result);
  300. ASSERT_TRUE(utf16result_len == 3);
  301. ASSERT_TRUE(output_buffer[0] == 'A' && output_buffer[1] == 0xFFFD &&
  302. output_buffer[2] == 'Z');
  303. // Invalid encoding name.
  304. output_buffer.resize(100);
  305. utf16result_len = static_cast<uint32_t>(output_buffer.size());
  306. result = char_set_trusted_interface_->CharSetToUTF16(
  307. badutf8, 3, "poopiepants", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
  308. &output_buffer[0], &utf16result_len);
  309. ASSERT_TRUE(!result);
  310. ASSERT_TRUE(utf16result_len == 0);
  311. PASS();
  312. }
  313. std::string TestCharSet::TestGetDefaultCharSet() {
  314. // Test invalid instance.
  315. pp::Var result(pp::PASS_REF, char_set_interface_->GetDefaultCharSet(0));
  316. ASSERT_TRUE(result.is_undefined());
  317. // Just make sure the default char set is a nonempty string.
  318. result = pp::Var(pp::PASS_REF,
  319. char_set_interface_->GetDefaultCharSet(instance_->pp_instance()));
  320. ASSERT_TRUE(result.is_string());
  321. ASSERT_FALSE(result.AsString().empty());
  322. PASS();
  323. }
  324. std::vector<uint16_t> TestCharSet::UTF8ToUTF16(const std::string& utf8) {
  325. uint32_t result_len = 0;
  326. uint16_t* result = char_set_interface_->CharSetToUTF16(
  327. instance_->pp_instance(), utf8.c_str(),
  328. static_cast<uint32_t>(utf8.size()),
  329. "utf-8", PP_CHARSET_CONVERSIONERROR_FAIL, &result_len);
  330. std::vector<uint16_t> result_vector;
  331. if (!result)
  332. return result_vector;
  333. result_vector.assign(result, &result[result_len]);
  334. pp::Memory_Dev memory;
  335. memory.MemFree(result);
  336. return result_vector;
  337. }