StringTest.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * Copyright 2011 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "tests/Test.h"
  8. #include "include/core/SkString.h"
  9. #include "src/core/SkStringUtils.h"
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12. #include <thread>
  13. static const char* gThirtyWideDecimal = "%30d";
  14. DEF_TEST(String, reporter) {
  15. SkString a;
  16. SkString b((size_t)0);
  17. SkString c("");
  18. SkString d(nullptr, 0);
  19. REPORTER_ASSERT(reporter, a.isEmpty());
  20. REPORTER_ASSERT(reporter, a == b && a == c && a == d);
  21. a.set("hello");
  22. b.set("hellox", 5);
  23. c.set(a);
  24. d.resize(5);
  25. memcpy(d.writable_str(), "helloz", 5);
  26. REPORTER_ASSERT(reporter, !a.isEmpty());
  27. REPORTER_ASSERT(reporter, a.size() == 5);
  28. REPORTER_ASSERT(reporter, a == b && a == c && a == d);
  29. REPORTER_ASSERT(reporter, a.equals("hello", 5));
  30. REPORTER_ASSERT(reporter, a.equals("hello"));
  31. REPORTER_ASSERT(reporter, !a.equals("help"));
  32. REPORTER_ASSERT(reporter, a.startsWith("hell"));
  33. REPORTER_ASSERT(reporter, a.startsWith('h'));
  34. REPORTER_ASSERT(reporter, !a.startsWith( "ell"));
  35. REPORTER_ASSERT(reporter, !a.startsWith( 'e'));
  36. REPORTER_ASSERT(reporter, a.startsWith(""));
  37. REPORTER_ASSERT(reporter, a.endsWith("llo"));
  38. REPORTER_ASSERT(reporter, a.endsWith('o'));
  39. REPORTER_ASSERT(reporter, !a.endsWith("ll" ));
  40. REPORTER_ASSERT(reporter, !a.endsWith('l'));
  41. REPORTER_ASSERT(reporter, a.endsWith(""));
  42. REPORTER_ASSERT(reporter, a.contains("he"));
  43. REPORTER_ASSERT(reporter, a.contains("ll"));
  44. REPORTER_ASSERT(reporter, a.contains("lo"));
  45. REPORTER_ASSERT(reporter, a.contains("hello"));
  46. REPORTER_ASSERT(reporter, !a.contains("hellohello"));
  47. REPORTER_ASSERT(reporter, a.contains(""));
  48. REPORTER_ASSERT(reporter, a.contains('e'));
  49. REPORTER_ASSERT(reporter, !a.contains('z'));
  50. SkString e(a);
  51. SkString f("hello");
  52. SkString g("helloz", 5);
  53. REPORTER_ASSERT(reporter, a == e && a == f && a == g);
  54. b.set("world");
  55. c = b;
  56. REPORTER_ASSERT(reporter, a != b && a != c && b == c);
  57. a.append(" world");
  58. e.append("worldz", 5);
  59. e.insert(5, " ");
  60. f.set("world");
  61. f.prepend("hello ");
  62. REPORTER_ASSERT(reporter, a.equals("hello world") && a == e && a == f);
  63. a.reset();
  64. b.resize(0);
  65. REPORTER_ASSERT(reporter, a.isEmpty() && b.isEmpty() && a == b);
  66. a.set("a");
  67. a.set("ab");
  68. a.set("abc");
  69. a.set("abcd");
  70. a.set("");
  71. a.appendS32(0x7FFFFFFFL);
  72. REPORTER_ASSERT(reporter, a.equals("2147483647"));
  73. a.set("");
  74. a.appendS32(0x80000001L);
  75. REPORTER_ASSERT(reporter, a.equals("-2147483647"));
  76. a.set("");
  77. a.appendS32(0x80000000L);
  78. REPORTER_ASSERT(reporter, a.equals("-2147483648"));
  79. a.set("");
  80. a.appendU32(0x7FFFFFFFUL);
  81. REPORTER_ASSERT(reporter, a.equals("2147483647"));
  82. a.set("");
  83. a.appendU32(0x80000001UL);
  84. REPORTER_ASSERT(reporter, a.equals("2147483649"));
  85. a.set("");
  86. a.appendU32(0xFFFFFFFFUL);
  87. REPORTER_ASSERT(reporter, a.equals("4294967295"));
  88. a.set("");
  89. a.appendS64(0x7FFFFFFFFFFFFFFFLL, 0);
  90. REPORTER_ASSERT(reporter, a.equals("9223372036854775807"));
  91. a.set("");
  92. a.appendS64(0x8000000000000001LL, 0);
  93. REPORTER_ASSERT(reporter, a.equals("-9223372036854775807"));
  94. a.set("");
  95. a.appendS64(0x8000000000000000LL, 0);
  96. REPORTER_ASSERT(reporter, a.equals("-9223372036854775808"));
  97. a.set("");
  98. a.appendS64(0x0000000001000000LL, 15);
  99. REPORTER_ASSERT(reporter, a.equals("000000016777216"));
  100. a.set("");
  101. a.appendS64(0xFFFFFFFFFF000000LL, 15);
  102. REPORTER_ASSERT(reporter, a.equals("-000000016777216"));
  103. a.set("");
  104. a.appendU64(0x7FFFFFFFFFFFFFFFULL, 0);
  105. REPORTER_ASSERT(reporter, a.equals("9223372036854775807"));
  106. a.set("");
  107. a.appendU64(0x8000000000000001ULL, 0);
  108. REPORTER_ASSERT(reporter, a.equals("9223372036854775809"));
  109. a.set("");
  110. a.appendU64(0xFFFFFFFFFFFFFFFFULL, 0);
  111. REPORTER_ASSERT(reporter, a.equals("18446744073709551615"));
  112. a.set("");
  113. a.appendU64(0x0000000001000000ULL, 15);
  114. REPORTER_ASSERT(reporter, a.equals("000000016777216"));
  115. a.printf("%i", 0);
  116. REPORTER_ASSERT(reporter, a.equals("0"));
  117. a.printf("%g", 3.14);
  118. REPORTER_ASSERT(reporter, a.equals("3.14"));
  119. a.printf("hello %s", "skia");
  120. REPORTER_ASSERT(reporter, a.equals("hello skia"));
  121. static const struct {
  122. SkScalar fValue;
  123. const char* fString;
  124. } gRec[] = {
  125. { 0, "0" },
  126. { SK_Scalar1, "1" },
  127. { -SK_Scalar1, "-1" },
  128. { SK_Scalar1/2, "0.5" },
  129. #if defined(SK_BUILD_FOR_WIN) && (_MSC_VER < 1900)
  130. { 3.4028234e38f, "3.4028235e+038" },
  131. { -3.4028234e38f, "-3.4028235e+038" },
  132. #else
  133. { 3.4028234e38f, "3.4028235e+38" },
  134. { -3.4028234e38f, "-3.4028235e+38" },
  135. #endif
  136. };
  137. for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
  138. a.reset();
  139. a.appendScalar(gRec[i].fValue);
  140. REPORTER_ASSERT(reporter, a.size() <= SkStrAppendScalar_MaxSize);
  141. if (!a.equals(gRec[i].fString)) {
  142. ERRORF(reporter, "received <%s> expected <%s>\n", a.c_str(), gRec[i].fString);
  143. }
  144. }
  145. REPORTER_ASSERT(reporter, SkStringPrintf("%i", 0).equals("0"));
  146. char buffer [40];
  147. memset(buffer, 'a', 40);
  148. REPORTER_ASSERT(reporter, buffer[18] == 'a');
  149. REPORTER_ASSERT(reporter, buffer[19] == 'a');
  150. REPORTER_ASSERT(reporter, buffer[20] == 'a');
  151. snprintf(buffer, 20, gThirtyWideDecimal, 0);
  152. REPORTER_ASSERT(reporter, buffer[18] == ' ');
  153. REPORTER_ASSERT(reporter, buffer[19] == 0);
  154. REPORTER_ASSERT(reporter, buffer[20] == 'a');
  155. REPORTER_ASSERT(reporter, SkStringPrintf("%i", 0).equals("0"));
  156. // 2000 is larger than the static buffer size inside SkString.cpp
  157. a = SkStringPrintf("%2000s", " ");
  158. REPORTER_ASSERT(reporter, a.size() == 2000);
  159. for (size_t i = 0; i < a.size(); ++i) {
  160. if (a[i] != ' ') {
  161. ERRORF(reporter, "SkStringPrintf fail: a[%d] = '%c'", i, a[i]);
  162. break;
  163. }
  164. }
  165. a.reset();
  166. a.printf("%2000s", " ");
  167. REPORTER_ASSERT(reporter, a.size() == 2000);
  168. for (size_t i = 0; i < a.size(); ++i) {
  169. if (a[i] != ' ') {
  170. ERRORF(reporter, "SkString::printf fail: a[%d] = '%c'", i, a[i]);
  171. break;
  172. }
  173. }
  174. a.appendf("%2000s", " ");
  175. REPORTER_ASSERT(reporter, a.size() == 4000);
  176. for (size_t i = 0; i < a.size(); ++i) {
  177. if (a[i] != ' ') {
  178. ERRORF(reporter, "SkString::appendf fail: a[%d] = '%c'", i, a[i]);
  179. break;
  180. }
  181. }
  182. }
  183. DEF_TEST(String_SkStrSplit, r) {
  184. SkTArray<SkString> results;
  185. SkStrSplit("a-_b_c-dee--f-_-_-g-", "-_", &results);
  186. REPORTER_ASSERT(r, results.count() == 6);
  187. REPORTER_ASSERT(r, results[0].equals("a"));
  188. REPORTER_ASSERT(r, results[1].equals("b"));
  189. REPORTER_ASSERT(r, results[2].equals("c"));
  190. REPORTER_ASSERT(r, results[3].equals("dee"));
  191. REPORTER_ASSERT(r, results[4].equals("f"));
  192. REPORTER_ASSERT(r, results[5].equals("g"));
  193. results.reset();
  194. SkStrSplit("\n", "\n", &results);
  195. REPORTER_ASSERT(r, results.count() == 0);
  196. results.reset();
  197. SkStrSplit("", "\n", &results);
  198. REPORTER_ASSERT(r, results.count() == 0);
  199. results.reset();
  200. SkStrSplit("a", "\n", &results);
  201. REPORTER_ASSERT(r, results.count() == 1);
  202. REPORTER_ASSERT(r, results[0].equals("a"));
  203. }
  204. DEF_TEST(String_SkStrSplit_All, r) {
  205. SkTArray<SkString> results;
  206. SkStrSplit("a-_b_c-dee--f-_-_-g-", "-_", kStrict_SkStrSplitMode, &results);
  207. REPORTER_ASSERT(r, results.count() == 13);
  208. REPORTER_ASSERT(r, results[0].equals("a"));
  209. REPORTER_ASSERT(r, results[1].equals(""));
  210. REPORTER_ASSERT(r, results[2].equals("b"));
  211. REPORTER_ASSERT(r, results[3].equals("c"));
  212. REPORTER_ASSERT(r, results[4].equals("dee"));
  213. REPORTER_ASSERT(r, results[5].equals(""));
  214. REPORTER_ASSERT(r, results[6].equals("f"));
  215. REPORTER_ASSERT(r, results[7].equals(""));
  216. REPORTER_ASSERT(r, results[8].equals(""));
  217. REPORTER_ASSERT(r, results[9].equals(""));
  218. REPORTER_ASSERT(r, results[10].equals(""));
  219. REPORTER_ASSERT(r, results[11].equals("g"));
  220. REPORTER_ASSERT(r, results[12].equals(""));
  221. results.reset();
  222. SkStrSplit("\n", "\n", kStrict_SkStrSplitMode, &results);
  223. REPORTER_ASSERT(r, results.count() == 2);
  224. REPORTER_ASSERT(r, results[0].equals(""));
  225. REPORTER_ASSERT(r, results[1].equals(""));
  226. results.reset();
  227. SkStrSplit("", "\n", kStrict_SkStrSplitMode, &results);
  228. REPORTER_ASSERT(r, results.count() == 0);
  229. results.reset();
  230. SkStrSplit("a", "\n", kStrict_SkStrSplitMode, &results);
  231. REPORTER_ASSERT(r, results.count() == 1);
  232. REPORTER_ASSERT(r, results[0].equals("a"));
  233. results.reset();
  234. SkStrSplit(",,", ",", kStrict_SkStrSplitMode, &results);
  235. REPORTER_ASSERT(r, results.count() == 3);
  236. REPORTER_ASSERT(r, results[0].equals(""));
  237. REPORTER_ASSERT(r, results[1].equals(""));
  238. REPORTER_ASSERT(r, results[2].equals(""));
  239. results.reset();
  240. SkStrSplit(",a,b,", ",", kStrict_SkStrSplitMode, &results);
  241. REPORTER_ASSERT(r, results.count() == 4);
  242. REPORTER_ASSERT(r, results[0].equals(""));
  243. REPORTER_ASSERT(r, results[1].equals("a"));
  244. REPORTER_ASSERT(r, results[2].equals("b"));
  245. REPORTER_ASSERT(r, results[3].equals(""));
  246. }
  247. // https://bugs.chromium.org/p/skia/issues/detail?id=7107
  248. DEF_TEST(String_Threaded, r) {
  249. SkString str("foo");
  250. std::thread threads[5];
  251. for (auto& thread : threads) {
  252. thread = std::thread([&] {
  253. SkString copy = str;
  254. (void)copy.equals("test");
  255. });
  256. }
  257. for (auto& thread : threads) {
  258. thread.join();
  259. }
  260. }
  261. // Ensure that the string allocate doesn't internally overflow any calculations, and accidentally
  262. // let us create a string with a requested length longer than we can manage.
  263. DEF_TEST(String_huge, r) {
  264. // start testing slightly below max 32
  265. size_t size = UINT32_MAX - 16;
  266. // See where we crash, and manually check that its at the right point.
  267. //
  268. // To test, change the false to true
  269. while (false) {
  270. // On a 64bit build, this should crash when size == 1 << 32, since we can't store
  271. // that length in the string's header (which has a u32 slot for the length).
  272. //
  273. // On a 32bit build, this should crash the first time around, since we can't allocate
  274. // anywhere near this amount.
  275. //
  276. SkString str(size);
  277. size += 1;
  278. }
  279. }
  280. DEF_TEST(String_fromUTF16, r) {
  281. // test data produced with `iconv`.
  282. const uint16_t test1[] = {
  283. 0xD835, 0xDCD0, 0xD835, 0xDCD1, 0xD835, 0xDCD2, 0xD835, 0xDCD3, 0xD835, 0xDCD4, 0x0020,
  284. 0xD835, 0xDCD5, 0xD835, 0xDCD6, 0xD835, 0xDCD7, 0xD835, 0xDCD8, 0xD835, 0xDCD9
  285. };
  286. REPORTER_ASSERT(r, SkStringFromUTF16(test1, SK_ARRAY_COUNT(test1)).equals("𝓐𝓑𝓒𝓓𝓔 𝓕𝓖𝓗𝓘𝓙"));
  287. const uint16_t test2[] = {
  288. 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0020, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A,
  289. };
  290. REPORTER_ASSERT(r, SkStringFromUTF16(test2, SK_ARRAY_COUNT(test2)).equals("ABCDE FGHIJ"));
  291. const uint16_t test3[] = {
  292. 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x0020, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA,
  293. };
  294. REPORTER_ASSERT(r, SkStringFromUTF16(test3, SK_ARRAY_COUNT(test3)).equals("αβγδε ζηθικ"));
  295. }