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