github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/cmd/libsnap-confine-private/string-utils-test.c (about) 1 /* 2 * Copyright (C) 2016-2017 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 18 #include "string-utils.h" 19 #include "string-utils.c" 20 21 #include <glib.h> 22 23 static void test_sc_streq(void) 24 { 25 g_assert_false(sc_streq(NULL, NULL)); 26 g_assert_false(sc_streq(NULL, "text")); 27 g_assert_false(sc_streq("text", NULL)); 28 g_assert_false(sc_streq("foo", "bar")); 29 g_assert_false(sc_streq("foo", "barbar")); 30 g_assert_false(sc_streq("foofoo", "bar")); 31 g_assert_true(sc_streq("text", "text")); 32 g_assert_true(sc_streq("", "")); 33 } 34 35 static void test_sc_endswith(void) 36 { 37 // NULL doesn't end with anything, nothing ends with NULL 38 g_assert_false(sc_endswith("", NULL)); 39 g_assert_false(sc_endswith(NULL, "")); 40 g_assert_false(sc_endswith(NULL, NULL)); 41 // Empty string ends with an empty string 42 g_assert_true(sc_endswith("", "")); 43 // Ends-with (matches) 44 g_assert_true(sc_endswith("foobar", "bar")); 45 g_assert_true(sc_endswith("foobar", "ar")); 46 g_assert_true(sc_endswith("foobar", "r")); 47 g_assert_true(sc_endswith("foobar", "")); 48 g_assert_true(sc_endswith("bar", "bar")); 49 // Ends-with (non-matches) 50 g_assert_false(sc_endswith("foobar", "quux")); 51 g_assert_false(sc_endswith("", "bar")); 52 g_assert_false(sc_endswith("b", "bar")); 53 g_assert_false(sc_endswith("ba", "bar")); 54 } 55 56 static void test_sc_startswith(void) 57 { 58 // NULL doesn't start with anything, nothing starts with NULL 59 g_assert_false(sc_startswith("", NULL)); 60 g_assert_false(sc_startswith(NULL, "")); 61 g_assert_false(sc_startswith(NULL, NULL)); 62 // Empty string starts with an empty string 63 g_assert_true(sc_startswith("", "")); 64 // Starts-with (matches) 65 g_assert_true(sc_startswith("foobar", "foo")); 66 g_assert_true(sc_startswith("foobar", "fo")); 67 g_assert_true(sc_startswith("foobar", "f")); 68 g_assert_true(sc_startswith("foobar", "")); 69 g_assert_true(sc_startswith("bar", "bar")); 70 // Starts-with (non-matches) 71 g_assert_false(sc_startswith("foobar", "quux")); 72 g_assert_false(sc_startswith("", "bar")); 73 g_assert_false(sc_startswith("b", "bar")); 74 g_assert_false(sc_startswith("ba", "bar")); 75 } 76 77 static void test_sc_must_snprintf(void) 78 { 79 char buf[5] = { 0 }; 80 sc_must_snprintf(buf, sizeof buf, "1234"); 81 g_assert_cmpstr(buf, ==, "1234"); 82 } 83 84 static void test_sc_must_snprintf__fail(void) 85 { 86 if (g_test_subprocess()) { 87 char buf[5]; 88 sc_must_snprintf(buf, sizeof buf, "12345"); 89 g_test_message("expected sc_must_snprintf not to return"); 90 g_test_fail(); 91 return; 92 } 93 g_test_trap_subprocess(NULL, 0, 0); 94 g_test_trap_assert_failed(); 95 g_test_trap_assert_stderr("cannot format string: 1234\n"); 96 } 97 98 // Check that appending to a buffer works OK. 99 static void test_sc_string_append(void) 100 { 101 union { 102 char bigbuf[6]; 103 struct { 104 signed char canary1; 105 char buf[4]; 106 signed char canary2; 107 }; 108 } data = { 109 .buf = { 110 'f', '\0', 0xFF, 0xFF},.canary1 = ~0,.canary2 = ~0, 111 }; 112 113 // Sanity check, ensure that the layout of structures is as spelled above. 114 // (first canary1, then buf and finally canary2. 115 g_assert_cmpint(((char *)&data.buf[0]) - ((char *)&data.canary1), ==, 116 1); 117 g_assert_cmpint(((char *)&data.buf[4]) - ((char *)&data.canary2), ==, 118 0); 119 120 sc_string_append(data.buf, sizeof data.buf, "oo"); 121 122 // Check that we didn't corrupt either canary. 123 g_assert_cmpint(data.canary1, ==, ~0); 124 g_assert_cmpint(data.canary2, ==, ~0); 125 126 // Check that we got the result that was expected. 127 g_assert_cmpstr(data.buf, ==, "foo"); 128 } 129 130 // Check that appending an empty string to a full buffer is valid. 131 static void test_sc_string_append__empty_to_full(void) 132 { 133 union { 134 char bigbuf[6]; 135 struct { 136 signed char canary1; 137 char buf[4]; 138 signed char canary2; 139 }; 140 } data = { 141 .buf = { 142 'f', 'o', 'o', '\0'},.canary1 = ~0,.canary2 = ~0, 143 }; 144 145 // Sanity check, ensure that the layout of structures is as spelled above. 146 // (first canary1, then buf and finally canary2. 147 g_assert_cmpint(((char *)&data.buf[0]) - ((char *)&data.canary1), ==, 148 1); 149 g_assert_cmpint(((char *)&data.buf[4]) - ((char *)&data.canary2), ==, 150 0); 151 152 sc_string_append(data.buf, sizeof data.buf, ""); 153 154 // Check that we didn't corrupt either canary. 155 g_assert_cmpint(data.canary1, ==, ~0); 156 g_assert_cmpint(data.canary2, ==, ~0); 157 158 // Check that we got the result that was expected. 159 g_assert_cmpstr(data.buf, ==, "foo"); 160 } 161 162 // Check that the overflow detection works. 163 static void test_sc_string_append__overflow(void) 164 { 165 if (g_test_subprocess()) { 166 char buf[4] = { 0 }; 167 168 // Try to append a string that's one character too long. 169 sc_string_append(buf, sizeof buf, "1234"); 170 171 g_test_message("expected sc_string_append not to return"); 172 g_test_fail(); 173 return; 174 } 175 g_test_trap_subprocess(NULL, 0, 0); 176 g_test_trap_assert_failed(); 177 g_test_trap_assert_stderr 178 ("cannot append string: str is too long or unterminated\n"); 179 } 180 181 // Check that the uninitialized buffer detection works. 182 static void test_sc_string_append__uninitialized_buf(void) 183 { 184 if (g_test_subprocess()) { 185 char buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; 186 187 // Try to append a string to a buffer which is not a valic C-string. 188 sc_string_append(buf, sizeof buf, ""); 189 190 g_test_message("expected sc_string_append not to return"); 191 g_test_fail(); 192 return; 193 } 194 g_test_trap_subprocess(NULL, 0, 0); 195 g_test_trap_assert_failed(); 196 g_test_trap_assert_stderr 197 ("cannot append string: dst is unterminated\n"); 198 } 199 200 // Check that `buf' cannot be NULL. 201 static void test_sc_string_append__NULL_buf(void) 202 { 203 if (g_test_subprocess()) { 204 char buf[4]; 205 206 sc_string_append(NULL, sizeof buf, "foo"); 207 208 g_test_message("expected sc_string_append not to return"); 209 g_test_fail(); 210 return; 211 } 212 g_test_trap_subprocess(NULL, 0, 0); 213 g_test_trap_assert_failed(); 214 g_test_trap_assert_stderr("cannot append string: buffer is NULL\n"); 215 } 216 217 // Check that `src' cannot be NULL. 218 static void test_sc_string_append__NULL_str(void) 219 { 220 if (g_test_subprocess()) { 221 char buf[4]; 222 223 sc_string_append(buf, sizeof buf, NULL); 224 225 g_test_message("expected sc_string_append not to return"); 226 g_test_fail(); 227 return; 228 } 229 g_test_trap_subprocess(NULL, 0, 0); 230 g_test_trap_assert_failed(); 231 g_test_trap_assert_stderr("cannot append string: string is NULL\n"); 232 } 233 234 static void test_sc_string_init__normal(void) 235 { 236 char buf[1] = { 0xFF }; 237 238 sc_string_init(buf, sizeof buf); 239 g_assert_cmpint(buf[0], ==, 0); 240 } 241 242 static void test_sc_string_init__empty_buf(void) 243 { 244 if (g_test_subprocess()) { 245 char buf[1] = { 0xFF }; 246 247 sc_string_init(buf, 0); 248 249 g_test_message("expected sc_string_init not to return"); 250 g_test_fail(); 251 return; 252 } 253 g_test_trap_subprocess(NULL, 0, 0); 254 g_test_trap_assert_failed(); 255 g_test_trap_assert_stderr 256 ("cannot initialize string, buffer is too small\n"); 257 } 258 259 static void test_sc_string_init__NULL_buf(void) 260 { 261 if (g_test_subprocess()) { 262 sc_string_init(NULL, 1); 263 264 g_test_message("expected sc_string_init not to return"); 265 g_test_fail(); 266 return; 267 } 268 g_test_trap_subprocess(NULL, 0, 0); 269 g_test_trap_assert_failed(); 270 g_test_trap_assert_stderr("cannot initialize string, buffer is NULL\n"); 271 } 272 273 static void test_sc_string_append_char__uninitialized_buf(void) 274 { 275 if (g_test_subprocess()) { 276 char buf[2] = { 0xFF, 0xFF }; 277 sc_string_append_char(buf, sizeof buf, 'a'); 278 279 g_test_message("expected sc_string_append_char not to return"); 280 g_test_fail(); 281 return; 282 } 283 g_test_trap_subprocess(NULL, 0, 0); 284 g_test_trap_assert_failed(); 285 g_test_trap_assert_stderr 286 ("cannot append character: dst is unterminated\n"); 287 } 288 289 static void test_sc_string_append_char__NULL_buf(void) 290 { 291 if (g_test_subprocess()) { 292 sc_string_append_char(NULL, 2, 'a'); 293 294 g_test_message("expected sc_string_append_char not to return"); 295 g_test_fail(); 296 return; 297 } 298 g_test_trap_subprocess(NULL, 0, 0); 299 g_test_trap_assert_failed(); 300 g_test_trap_assert_stderr("cannot append character: buffer is NULL\n"); 301 } 302 303 static void test_sc_string_append_char__overflow(void) 304 { 305 if (g_test_subprocess()) { 306 char buf[1] = { 0 }; 307 sc_string_append_char(buf, sizeof buf, 'a'); 308 309 g_test_message("expected sc_string_append_char not to return"); 310 g_test_fail(); 311 return; 312 } 313 g_test_trap_subprocess(NULL, 0, 0); 314 g_test_trap_assert_failed(); 315 g_test_trap_assert_stderr 316 ("cannot append character: not enough space\n"); 317 } 318 319 static void test_sc_string_append_char__invalid_zero(void) 320 { 321 if (g_test_subprocess()) { 322 char buf[2] = { 0 }; 323 sc_string_append_char(buf, sizeof buf, '\0'); 324 325 g_test_message("expected sc_string_append_char not to return"); 326 g_test_fail(); 327 return; 328 } 329 g_test_trap_subprocess(NULL, 0, 0); 330 g_test_trap_assert_failed(); 331 g_test_trap_assert_stderr 332 ("cannot append character: cannot append string terminator\n"); 333 } 334 335 static void test_sc_string_append_char__normal(void) 336 { 337 char buf[16]; 338 size_t len; 339 sc_string_init(buf, sizeof buf); 340 341 len = sc_string_append_char(buf, sizeof buf, 'h'); 342 g_assert_cmpstr(buf, ==, "h"); 343 g_assert_cmpint(len, ==, 1); 344 len = sc_string_append_char(buf, sizeof buf, 'e'); 345 g_assert_cmpstr(buf, ==, "he"); 346 g_assert_cmpint(len, ==, 2); 347 len = sc_string_append_char(buf, sizeof buf, 'l'); 348 g_assert_cmpstr(buf, ==, "hel"); 349 g_assert_cmpint(len, ==, 3); 350 len = sc_string_append_char(buf, sizeof buf, 'l'); 351 g_assert_cmpstr(buf, ==, "hell"); 352 g_assert_cmpint(len, ==, 4); 353 len = sc_string_append_char(buf, sizeof buf, 'o'); 354 g_assert_cmpstr(buf, ==, "hello"); 355 g_assert_cmpint(len, ==, 5); 356 } 357 358 static void test_sc_string_append_char_pair__uninitialized_buf(void) 359 { 360 if (g_test_subprocess()) { 361 char buf[3] = { 0xFF, 0xFF, 0xFF }; 362 sc_string_append_char_pair(buf, sizeof buf, 'a', 'b'); 363 364 g_test_message 365 ("expected sc_string_append_char_pair not to return"); 366 g_test_fail(); 367 return; 368 } 369 g_test_trap_subprocess(NULL, 0, 0); 370 g_test_trap_assert_failed(); 371 g_test_trap_assert_stderr 372 ("cannot append character pair: dst is unterminated\n"); 373 } 374 375 static void test_sc_string_append_char_pair__NULL_buf(void) 376 { 377 if (g_test_subprocess()) { 378 sc_string_append_char_pair(NULL, 3, 'a', 'b'); 379 380 g_test_message 381 ("expected sc_string_append_char_pair not to return"); 382 g_test_fail(); 383 return; 384 } 385 g_test_trap_subprocess(NULL, 0, 0); 386 g_test_trap_assert_failed(); 387 g_test_trap_assert_stderr 388 ("cannot append character pair: buffer is NULL\n"); 389 } 390 391 static void test_sc_string_append_char_pair__overflow(void) 392 { 393 if (g_test_subprocess()) { 394 char buf[2] = { 0 }; 395 sc_string_append_char_pair(buf, sizeof buf, 'a', 'b'); 396 397 g_test_message 398 ("expected sc_string_append_char_pair not to return"); 399 g_test_fail(); 400 return; 401 } 402 g_test_trap_subprocess(NULL, 0, 0); 403 g_test_trap_assert_failed(); 404 g_test_trap_assert_stderr 405 ("cannot append character pair: not enough space\n"); 406 } 407 408 static void test_sc_string_append_char_pair__invalid_zero_c1(void) 409 { 410 if (g_test_subprocess()) { 411 char buf[3] = { 0 }; 412 sc_string_append_char_pair(buf, sizeof buf, '\0', 'a'); 413 414 g_test_message 415 ("expected sc_string_append_char_pair not to return"); 416 g_test_fail(); 417 return; 418 } 419 g_test_trap_subprocess(NULL, 0, 0); 420 g_test_trap_assert_failed(); 421 g_test_trap_assert_stderr 422 ("cannot append character pair: cannot append string terminator\n"); 423 } 424 425 static void test_sc_string_append_char_pair__invalid_zero_c2(void) 426 { 427 if (g_test_subprocess()) { 428 char buf[3] = { 0 }; 429 sc_string_append_char_pair(buf, sizeof buf, 'a', '\0'); 430 431 g_test_message 432 ("expected sc_string_append_char_pair not to return"); 433 g_test_fail(); 434 return; 435 } 436 g_test_trap_subprocess(NULL, 0, 0); 437 g_test_trap_assert_failed(); 438 g_test_trap_assert_stderr 439 ("cannot append character pair: cannot append string terminator\n"); 440 } 441 442 static void test_sc_string_append_char_pair__normal(void) 443 { 444 char buf[16]; 445 size_t len; 446 sc_string_init(buf, sizeof buf); 447 448 len = sc_string_append_char_pair(buf, sizeof buf, 'h', 'e'); 449 g_assert_cmpstr(buf, ==, "he"); 450 g_assert_cmpint(len, ==, 2); 451 len = sc_string_append_char_pair(buf, sizeof buf, 'l', 'l'); 452 g_assert_cmpstr(buf, ==, "hell"); 453 g_assert_cmpint(len, ==, 4); 454 len = sc_string_append_char_pair(buf, sizeof buf, 'o', '!'); 455 g_assert_cmpstr(buf, ==, "hello!"); 456 g_assert_cmpint(len, ==, 6); 457 } 458 459 static void test_sc_string_quote_NULL_str(void) 460 { 461 if (g_test_subprocess()) { 462 char buf[16] = { 0 }; 463 sc_string_quote(buf, sizeof buf, NULL); 464 465 g_test_message("expected sc_string_quote not to return"); 466 g_test_fail(); 467 return; 468 } 469 g_test_trap_subprocess(NULL, 0, 0); 470 g_test_trap_assert_failed(); 471 g_test_trap_assert_stderr("cannot quote string: string is NULL\n"); 472 } 473 474 static void test_quoting_of(bool tested[], int c, const char *expected) 475 { 476 char buf[16]; 477 478 g_assert_cmpint(c, >=, 0); 479 g_assert_cmpint(c, <=, 255); 480 481 // Create an input string with one character. 482 char input[2] = { (unsigned char)c, 0 }; 483 sc_string_quote(buf, sizeof buf, input); 484 485 // Ensure it was quoted as we expected. 486 g_assert_cmpstr(buf, ==, expected); 487 488 tested[c] = true; 489 } 490 491 static void test_sc_string_quote(void) 492 { 493 #define DQ "\"" 494 char buf[16]; 495 bool is_tested[256] = { false }; 496 497 // Exhaustive test for quoting of every 8bit input. This is very verbose 498 // but the goal is to have a very obvious and correct test that ensures no 499 // edge case is lost. 500 // 501 // block 1: 0x00 - 0x0f 502 test_quoting_of(is_tested, 0x00, DQ "" DQ); 503 test_quoting_of(is_tested, 0x01, DQ "\\x01" DQ); 504 test_quoting_of(is_tested, 0x02, DQ "\\x02" DQ); 505 test_quoting_of(is_tested, 0x03, DQ "\\x03" DQ); 506 test_quoting_of(is_tested, 0x04, DQ "\\x04" DQ); 507 test_quoting_of(is_tested, 0x05, DQ "\\x05" DQ); 508 test_quoting_of(is_tested, 0x06, DQ "\\x06" DQ); 509 test_quoting_of(is_tested, 0x07, DQ "\\x07" DQ); 510 test_quoting_of(is_tested, 0x08, DQ "\\x08" DQ); 511 test_quoting_of(is_tested, 0x09, DQ "\\t" DQ); 512 test_quoting_of(is_tested, 0x0a, DQ "\\n" DQ); 513 test_quoting_of(is_tested, 0x0b, DQ "\\v" DQ); 514 test_quoting_of(is_tested, 0x0c, DQ "\\x0c" DQ); 515 test_quoting_of(is_tested, 0x0d, DQ "\\r" DQ); 516 test_quoting_of(is_tested, 0x0e, DQ "\\x0e" DQ); 517 test_quoting_of(is_tested, 0x0f, DQ "\\x0f" DQ); 518 // block 2: 0x10 - 0x1f 519 test_quoting_of(is_tested, 0x10, DQ "\\x10" DQ); 520 test_quoting_of(is_tested, 0x11, DQ "\\x11" DQ); 521 test_quoting_of(is_tested, 0x12, DQ "\\x12" DQ); 522 test_quoting_of(is_tested, 0x13, DQ "\\x13" DQ); 523 test_quoting_of(is_tested, 0x14, DQ "\\x14" DQ); 524 test_quoting_of(is_tested, 0x15, DQ "\\x15" DQ); 525 test_quoting_of(is_tested, 0x16, DQ "\\x16" DQ); 526 test_quoting_of(is_tested, 0x17, DQ "\\x17" DQ); 527 test_quoting_of(is_tested, 0x18, DQ "\\x18" DQ); 528 test_quoting_of(is_tested, 0x19, DQ "\\x19" DQ); 529 test_quoting_of(is_tested, 0x1a, DQ "\\x1a" DQ); 530 test_quoting_of(is_tested, 0x1b, DQ "\\x1b" DQ); 531 test_quoting_of(is_tested, 0x1c, DQ "\\x1c" DQ); 532 test_quoting_of(is_tested, 0x1d, DQ "\\x1d" DQ); 533 test_quoting_of(is_tested, 0x1e, DQ "\\x1e" DQ); 534 test_quoting_of(is_tested, 0x1f, DQ "\\x1f" DQ); 535 // block 3: 0x20 - 0x2f 536 test_quoting_of(is_tested, 0x20, DQ " " DQ); 537 test_quoting_of(is_tested, 0x21, DQ "!" DQ); 538 test_quoting_of(is_tested, 0x22, DQ "\\\"" DQ); 539 test_quoting_of(is_tested, 0x23, DQ "#" DQ); 540 test_quoting_of(is_tested, 0x24, DQ "$" DQ); 541 test_quoting_of(is_tested, 0x25, DQ "%" DQ); 542 test_quoting_of(is_tested, 0x26, DQ "&" DQ); 543 test_quoting_of(is_tested, 0x27, DQ "'" DQ); 544 test_quoting_of(is_tested, 0x28, DQ "(" DQ); 545 test_quoting_of(is_tested, 0x29, DQ ")" DQ); 546 test_quoting_of(is_tested, 0x2a, DQ "*" DQ); 547 test_quoting_of(is_tested, 0x2b, DQ "+" DQ); 548 test_quoting_of(is_tested, 0x2c, DQ "," DQ); 549 test_quoting_of(is_tested, 0x2d, DQ "-" DQ); 550 test_quoting_of(is_tested, 0x2e, DQ "." DQ); 551 test_quoting_of(is_tested, 0x2f, DQ "/" DQ); 552 // block 4: 0x30 - 0x3f 553 test_quoting_of(is_tested, 0x30, DQ "0" DQ); 554 test_quoting_of(is_tested, 0x31, DQ "1" DQ); 555 test_quoting_of(is_tested, 0x32, DQ "2" DQ); 556 test_quoting_of(is_tested, 0x33, DQ "3" DQ); 557 test_quoting_of(is_tested, 0x34, DQ "4" DQ); 558 test_quoting_of(is_tested, 0x35, DQ "5" DQ); 559 test_quoting_of(is_tested, 0x36, DQ "6" DQ); 560 test_quoting_of(is_tested, 0x37, DQ "7" DQ); 561 test_quoting_of(is_tested, 0x38, DQ "8" DQ); 562 test_quoting_of(is_tested, 0x39, DQ "9" DQ); 563 test_quoting_of(is_tested, 0x3a, DQ ":" DQ); 564 test_quoting_of(is_tested, 0x3b, DQ ";" DQ); 565 test_quoting_of(is_tested, 0x3c, DQ "<" DQ); 566 test_quoting_of(is_tested, 0x3d, DQ "=" DQ); 567 test_quoting_of(is_tested, 0x3e, DQ ">" DQ); 568 test_quoting_of(is_tested, 0x3f, DQ "?" DQ); 569 // block 5: 0x40 - 0x4f 570 test_quoting_of(is_tested, 0x40, DQ "@" DQ); 571 test_quoting_of(is_tested, 0x41, DQ "A" DQ); 572 test_quoting_of(is_tested, 0x42, DQ "B" DQ); 573 test_quoting_of(is_tested, 0x43, DQ "C" DQ); 574 test_quoting_of(is_tested, 0x44, DQ "D" DQ); 575 test_quoting_of(is_tested, 0x45, DQ "E" DQ); 576 test_quoting_of(is_tested, 0x46, DQ "F" DQ); 577 test_quoting_of(is_tested, 0x47, DQ "G" DQ); 578 test_quoting_of(is_tested, 0x48, DQ "H" DQ); 579 test_quoting_of(is_tested, 0x49, DQ "I" DQ); 580 test_quoting_of(is_tested, 0x4a, DQ "J" DQ); 581 test_quoting_of(is_tested, 0x4b, DQ "K" DQ); 582 test_quoting_of(is_tested, 0x4c, DQ "L" DQ); 583 test_quoting_of(is_tested, 0x4d, DQ "M" DQ); 584 test_quoting_of(is_tested, 0x4e, DQ "N" DQ); 585 test_quoting_of(is_tested, 0x4f, DQ "O" DQ); 586 // block 6: 0x50 - 0x5f 587 test_quoting_of(is_tested, 0x50, DQ "P" DQ); 588 test_quoting_of(is_tested, 0x51, DQ "Q" DQ); 589 test_quoting_of(is_tested, 0x52, DQ "R" DQ); 590 test_quoting_of(is_tested, 0x53, DQ "S" DQ); 591 test_quoting_of(is_tested, 0x54, DQ "T" DQ); 592 test_quoting_of(is_tested, 0x55, DQ "U" DQ); 593 test_quoting_of(is_tested, 0x56, DQ "V" DQ); 594 test_quoting_of(is_tested, 0x57, DQ "W" DQ); 595 test_quoting_of(is_tested, 0x58, DQ "X" DQ); 596 test_quoting_of(is_tested, 0x59, DQ "Y" DQ); 597 test_quoting_of(is_tested, 0x5a, DQ "Z" DQ); 598 test_quoting_of(is_tested, 0x5b, DQ "[" DQ); 599 test_quoting_of(is_tested, 0x5c, DQ "\\\\" DQ); 600 test_quoting_of(is_tested, 0x5d, DQ "]" DQ); 601 test_quoting_of(is_tested, 0x5e, DQ "^" DQ); 602 test_quoting_of(is_tested, 0x5f, DQ "_" DQ); 603 // block 7: 0x60 - 0x6f 604 test_quoting_of(is_tested, 0x60, DQ "`" DQ); 605 test_quoting_of(is_tested, 0x61, DQ "a" DQ); 606 test_quoting_of(is_tested, 0x62, DQ "b" DQ); 607 test_quoting_of(is_tested, 0x63, DQ "c" DQ); 608 test_quoting_of(is_tested, 0x64, DQ "d" DQ); 609 test_quoting_of(is_tested, 0x65, DQ "e" DQ); 610 test_quoting_of(is_tested, 0x66, DQ "f" DQ); 611 test_quoting_of(is_tested, 0x67, DQ "g" DQ); 612 test_quoting_of(is_tested, 0x68, DQ "h" DQ); 613 test_quoting_of(is_tested, 0x69, DQ "i" DQ); 614 test_quoting_of(is_tested, 0x6a, DQ "j" DQ); 615 test_quoting_of(is_tested, 0x6b, DQ "k" DQ); 616 test_quoting_of(is_tested, 0x6c, DQ "l" DQ); 617 test_quoting_of(is_tested, 0x6d, DQ "m" DQ); 618 test_quoting_of(is_tested, 0x6e, DQ "n" DQ); 619 test_quoting_of(is_tested, 0x6f, DQ "o" DQ); 620 // block 8: 0x70 - 0x7f 621 test_quoting_of(is_tested, 0x70, DQ "p" DQ); 622 test_quoting_of(is_tested, 0x71, DQ "q" DQ); 623 test_quoting_of(is_tested, 0x72, DQ "r" DQ); 624 test_quoting_of(is_tested, 0x73, DQ "s" DQ); 625 test_quoting_of(is_tested, 0x74, DQ "t" DQ); 626 test_quoting_of(is_tested, 0x75, DQ "u" DQ); 627 test_quoting_of(is_tested, 0x76, DQ "v" DQ); 628 test_quoting_of(is_tested, 0x77, DQ "w" DQ); 629 test_quoting_of(is_tested, 0x78, DQ "x" DQ); 630 test_quoting_of(is_tested, 0x79, DQ "y" DQ); 631 test_quoting_of(is_tested, 0x7a, DQ "z" DQ); 632 test_quoting_of(is_tested, 0x7b, DQ "{" DQ); 633 test_quoting_of(is_tested, 0x7c, DQ "|" DQ); 634 test_quoting_of(is_tested, 0x7d, DQ "}" DQ); 635 test_quoting_of(is_tested, 0x7e, DQ "~" DQ); 636 test_quoting_of(is_tested, 0x7f, DQ "\\x7f" DQ); 637 // block 9 (8-bit): 0x80 - 0x8f 638 test_quoting_of(is_tested, 0x80, DQ "\\x80" DQ); 639 test_quoting_of(is_tested, 0x81, DQ "\\x81" DQ); 640 test_quoting_of(is_tested, 0x82, DQ "\\x82" DQ); 641 test_quoting_of(is_tested, 0x83, DQ "\\x83" DQ); 642 test_quoting_of(is_tested, 0x84, DQ "\\x84" DQ); 643 test_quoting_of(is_tested, 0x85, DQ "\\x85" DQ); 644 test_quoting_of(is_tested, 0x86, DQ "\\x86" DQ); 645 test_quoting_of(is_tested, 0x87, DQ "\\x87" DQ); 646 test_quoting_of(is_tested, 0x88, DQ "\\x88" DQ); 647 test_quoting_of(is_tested, 0x89, DQ "\\x89" DQ); 648 test_quoting_of(is_tested, 0x8a, DQ "\\x8a" DQ); 649 test_quoting_of(is_tested, 0x8b, DQ "\\x8b" DQ); 650 test_quoting_of(is_tested, 0x8c, DQ "\\x8c" DQ); 651 test_quoting_of(is_tested, 0x8d, DQ "\\x8d" DQ); 652 test_quoting_of(is_tested, 0x8e, DQ "\\x8e" DQ); 653 test_quoting_of(is_tested, 0x8f, DQ "\\x8f" DQ); 654 // block 10 (8-bit): 0x90 - 0x9f 655 test_quoting_of(is_tested, 0x90, DQ "\\x90" DQ); 656 test_quoting_of(is_tested, 0x91, DQ "\\x91" DQ); 657 test_quoting_of(is_tested, 0x92, DQ "\\x92" DQ); 658 test_quoting_of(is_tested, 0x93, DQ "\\x93" DQ); 659 test_quoting_of(is_tested, 0x94, DQ "\\x94" DQ); 660 test_quoting_of(is_tested, 0x95, DQ "\\x95" DQ); 661 test_quoting_of(is_tested, 0x96, DQ "\\x96" DQ); 662 test_quoting_of(is_tested, 0x97, DQ "\\x97" DQ); 663 test_quoting_of(is_tested, 0x98, DQ "\\x98" DQ); 664 test_quoting_of(is_tested, 0x99, DQ "\\x99" DQ); 665 test_quoting_of(is_tested, 0x9a, DQ "\\x9a" DQ); 666 test_quoting_of(is_tested, 0x9b, DQ "\\x9b" DQ); 667 test_quoting_of(is_tested, 0x9c, DQ "\\x9c" DQ); 668 test_quoting_of(is_tested, 0x9d, DQ "\\x9d" DQ); 669 test_quoting_of(is_tested, 0x9e, DQ "\\x9e" DQ); 670 test_quoting_of(is_tested, 0x9f, DQ "\\x9f" DQ); 671 // block 11 (8-bit): 0xa0 - 0xaf 672 test_quoting_of(is_tested, 0xa0, DQ "\\xa0" DQ); 673 test_quoting_of(is_tested, 0xa1, DQ "\\xa1" DQ); 674 test_quoting_of(is_tested, 0xa2, DQ "\\xa2" DQ); 675 test_quoting_of(is_tested, 0xa3, DQ "\\xa3" DQ); 676 test_quoting_of(is_tested, 0xa4, DQ "\\xa4" DQ); 677 test_quoting_of(is_tested, 0xa5, DQ "\\xa5" DQ); 678 test_quoting_of(is_tested, 0xa6, DQ "\\xa6" DQ); 679 test_quoting_of(is_tested, 0xa7, DQ "\\xa7" DQ); 680 test_quoting_of(is_tested, 0xa8, DQ "\\xa8" DQ); 681 test_quoting_of(is_tested, 0xa9, DQ "\\xa9" DQ); 682 test_quoting_of(is_tested, 0xaa, DQ "\\xaa" DQ); 683 test_quoting_of(is_tested, 0xab, DQ "\\xab" DQ); 684 test_quoting_of(is_tested, 0xac, DQ "\\xac" DQ); 685 test_quoting_of(is_tested, 0xad, DQ "\\xad" DQ); 686 test_quoting_of(is_tested, 0xae, DQ "\\xae" DQ); 687 test_quoting_of(is_tested, 0xaf, DQ "\\xaf" DQ); 688 // block 12 (8-bit): 0xb0 - 0xbf 689 test_quoting_of(is_tested, 0xb0, DQ "\\xb0" DQ); 690 test_quoting_of(is_tested, 0xb1, DQ "\\xb1" DQ); 691 test_quoting_of(is_tested, 0xb2, DQ "\\xb2" DQ); 692 test_quoting_of(is_tested, 0xb3, DQ "\\xb3" DQ); 693 test_quoting_of(is_tested, 0xb4, DQ "\\xb4" DQ); 694 test_quoting_of(is_tested, 0xb5, DQ "\\xb5" DQ); 695 test_quoting_of(is_tested, 0xb6, DQ "\\xb6" DQ); 696 test_quoting_of(is_tested, 0xb7, DQ "\\xb7" DQ); 697 test_quoting_of(is_tested, 0xb8, DQ "\\xb8" DQ); 698 test_quoting_of(is_tested, 0xb9, DQ "\\xb9" DQ); 699 test_quoting_of(is_tested, 0xba, DQ "\\xba" DQ); 700 test_quoting_of(is_tested, 0xbb, DQ "\\xbb" DQ); 701 test_quoting_of(is_tested, 0xbc, DQ "\\xbc" DQ); 702 test_quoting_of(is_tested, 0xbd, DQ "\\xbd" DQ); 703 test_quoting_of(is_tested, 0xbe, DQ "\\xbe" DQ); 704 test_quoting_of(is_tested, 0xbf, DQ "\\xbf" DQ); 705 // block 13 (8-bit): 0xc0 - 0xcf 706 test_quoting_of(is_tested, 0xc0, DQ "\\xc0" DQ); 707 test_quoting_of(is_tested, 0xc1, DQ "\\xc1" DQ); 708 test_quoting_of(is_tested, 0xc2, DQ "\\xc2" DQ); 709 test_quoting_of(is_tested, 0xc3, DQ "\\xc3" DQ); 710 test_quoting_of(is_tested, 0xc4, DQ "\\xc4" DQ); 711 test_quoting_of(is_tested, 0xc5, DQ "\\xc5" DQ); 712 test_quoting_of(is_tested, 0xc6, DQ "\\xc6" DQ); 713 test_quoting_of(is_tested, 0xc7, DQ "\\xc7" DQ); 714 test_quoting_of(is_tested, 0xc8, DQ "\\xc8" DQ); 715 test_quoting_of(is_tested, 0xc9, DQ "\\xc9" DQ); 716 test_quoting_of(is_tested, 0xca, DQ "\\xca" DQ); 717 test_quoting_of(is_tested, 0xcb, DQ "\\xcb" DQ); 718 test_quoting_of(is_tested, 0xcc, DQ "\\xcc" DQ); 719 test_quoting_of(is_tested, 0xcd, DQ "\\xcd" DQ); 720 test_quoting_of(is_tested, 0xce, DQ "\\xce" DQ); 721 test_quoting_of(is_tested, 0xcf, DQ "\\xcf" DQ); 722 // block 14 (8-bit): 0xd0 - 0xdf 723 test_quoting_of(is_tested, 0xd0, DQ "\\xd0" DQ); 724 test_quoting_of(is_tested, 0xd1, DQ "\\xd1" DQ); 725 test_quoting_of(is_tested, 0xd2, DQ "\\xd2" DQ); 726 test_quoting_of(is_tested, 0xd3, DQ "\\xd3" DQ); 727 test_quoting_of(is_tested, 0xd4, DQ "\\xd4" DQ); 728 test_quoting_of(is_tested, 0xd5, DQ "\\xd5" DQ); 729 test_quoting_of(is_tested, 0xd6, DQ "\\xd6" DQ); 730 test_quoting_of(is_tested, 0xd7, DQ "\\xd7" DQ); 731 test_quoting_of(is_tested, 0xd8, DQ "\\xd8" DQ); 732 test_quoting_of(is_tested, 0xd9, DQ "\\xd9" DQ); 733 test_quoting_of(is_tested, 0xda, DQ "\\xda" DQ); 734 test_quoting_of(is_tested, 0xdb, DQ "\\xdb" DQ); 735 test_quoting_of(is_tested, 0xdc, DQ "\\xdc" DQ); 736 test_quoting_of(is_tested, 0xdd, DQ "\\xdd" DQ); 737 test_quoting_of(is_tested, 0xde, DQ "\\xde" DQ); 738 test_quoting_of(is_tested, 0xdf, DQ "\\xdf" DQ); 739 // block 15 (8-bit): 0xe0 - 0xef 740 test_quoting_of(is_tested, 0xe0, DQ "\\xe0" DQ); 741 test_quoting_of(is_tested, 0xe1, DQ "\\xe1" DQ); 742 test_quoting_of(is_tested, 0xe2, DQ "\\xe2" DQ); 743 test_quoting_of(is_tested, 0xe3, DQ "\\xe3" DQ); 744 test_quoting_of(is_tested, 0xe4, DQ "\\xe4" DQ); 745 test_quoting_of(is_tested, 0xe5, DQ "\\xe5" DQ); 746 test_quoting_of(is_tested, 0xe6, DQ "\\xe6" DQ); 747 test_quoting_of(is_tested, 0xe7, DQ "\\xe7" DQ); 748 test_quoting_of(is_tested, 0xe8, DQ "\\xe8" DQ); 749 test_quoting_of(is_tested, 0xe9, DQ "\\xe9" DQ); 750 test_quoting_of(is_tested, 0xea, DQ "\\xea" DQ); 751 test_quoting_of(is_tested, 0xeb, DQ "\\xeb" DQ); 752 test_quoting_of(is_tested, 0xec, DQ "\\xec" DQ); 753 test_quoting_of(is_tested, 0xed, DQ "\\xed" DQ); 754 test_quoting_of(is_tested, 0xee, DQ "\\xee" DQ); 755 test_quoting_of(is_tested, 0xef, DQ "\\xef" DQ); 756 // block 16 (8-bit): 0xf0 - 0xff 757 test_quoting_of(is_tested, 0xf0, DQ "\\xf0" DQ); 758 test_quoting_of(is_tested, 0xf1, DQ "\\xf1" DQ); 759 test_quoting_of(is_tested, 0xf2, DQ "\\xf2" DQ); 760 test_quoting_of(is_tested, 0xf3, DQ "\\xf3" DQ); 761 test_quoting_of(is_tested, 0xf4, DQ "\\xf4" DQ); 762 test_quoting_of(is_tested, 0xf5, DQ "\\xf5" DQ); 763 test_quoting_of(is_tested, 0xf6, DQ "\\xf6" DQ); 764 test_quoting_of(is_tested, 0xf7, DQ "\\xf7" DQ); 765 test_quoting_of(is_tested, 0xf8, DQ "\\xf8" DQ); 766 test_quoting_of(is_tested, 0xf9, DQ "\\xf9" DQ); 767 test_quoting_of(is_tested, 0xfa, DQ "\\xfa" DQ); 768 test_quoting_of(is_tested, 0xfb, DQ "\\xfb" DQ); 769 test_quoting_of(is_tested, 0xfc, DQ "\\xfc" DQ); 770 test_quoting_of(is_tested, 0xfd, DQ "\\xfd" DQ); 771 test_quoting_of(is_tested, 0xfe, DQ "\\xfe" DQ); 772 test_quoting_of(is_tested, 0xff, DQ "\\xff" DQ); 773 774 // Ensure the search was exhaustive. 775 for (int i = 0; i <= 0xff; ++i) { 776 g_assert_true(is_tested[i]); 777 } 778 779 // Few extra tests (repeated) for specific things. 780 781 // Smoke test 782 sc_string_quote(buf, sizeof buf, "hello 123"); 783 g_assert_cmpstr(buf, ==, DQ "hello 123" DQ); 784 785 // Whitespace 786 sc_string_quote(buf, sizeof buf, "\n"); 787 g_assert_cmpstr(buf, ==, DQ "\\n" DQ); 788 sc_string_quote(buf, sizeof buf, "\r"); 789 g_assert_cmpstr(buf, ==, DQ "\\r" DQ); 790 sc_string_quote(buf, sizeof buf, "\t"); 791 g_assert_cmpstr(buf, ==, DQ "\\t" DQ); 792 sc_string_quote(buf, sizeof buf, "\v"); 793 g_assert_cmpstr(buf, ==, DQ "\\v" DQ); 794 795 // Escape character itself 796 sc_string_quote(buf, sizeof buf, "\\"); 797 g_assert_cmpstr(buf, ==, DQ "\\\\" DQ); 798 799 // Double quote character 800 sc_string_quote(buf, sizeof buf, "\""); 801 g_assert_cmpstr(buf, ==, DQ "\\\"" DQ); 802 803 #undef DQ 804 } 805 806 static void test_sc_strdup(void) 807 { 808 char *s = sc_strdup("snap install everything"); 809 g_assert_nonnull(s); 810 g_assert_cmpstr(s, ==, "snap install everything"); 811 free(s); 812 } 813 814 static void __attribute__((constructor)) init(void) 815 { 816 g_test_add_func("/string-utils/sc_streq", test_sc_streq); 817 g_test_add_func("/string-utils/sc_endswith", test_sc_endswith); 818 g_test_add_func("/string-utils/sc_startswith", test_sc_startswith); 819 g_test_add_func("/string-utils/sc_must_snprintf", 820 test_sc_must_snprintf); 821 g_test_add_func("/string-utils/sc_must_snprintf/fail", 822 test_sc_must_snprintf__fail); 823 g_test_add_func("/string-utils/sc_string_append/normal", 824 test_sc_string_append); 825 g_test_add_func("/string-utils/sc_string_append/empty_to_full", 826 test_sc_string_append__empty_to_full); 827 g_test_add_func("/string-utils/sc_string_append/overflow", 828 test_sc_string_append__overflow); 829 g_test_add_func("/string-utils/sc_string_append/uninitialized_buf", 830 test_sc_string_append__uninitialized_buf); 831 g_test_add_func("/string-utils/sc_string_append/NULL_buf", 832 test_sc_string_append__NULL_buf); 833 g_test_add_func("/string-utils/sc_string_append/NULL_str", 834 test_sc_string_append__NULL_str); 835 g_test_add_func("/string-utils/sc_string_init/normal", 836 test_sc_string_init__normal); 837 g_test_add_func("/string-utils/sc_string_init/empty_buf", 838 test_sc_string_init__empty_buf); 839 g_test_add_func("/string-utils/sc_string_init/NULL_buf", 840 test_sc_string_init__NULL_buf); 841 g_test_add_func 842 ("/string-utils/sc_string_append_char__uninitialized_buf", 843 test_sc_string_append_char__uninitialized_buf); 844 g_test_add_func("/string-utils/sc_string_append_char__NULL_buf", 845 test_sc_string_append_char__NULL_buf); 846 g_test_add_func("/string-utils/sc_string_append_char__overflow", 847 test_sc_string_append_char__overflow); 848 g_test_add_func("/string-utils/sc_string_append_char__invalid_zero", 849 test_sc_string_append_char__invalid_zero); 850 g_test_add_func("/string-utils/sc_string_append_char__normal", 851 test_sc_string_append_char__normal); 852 g_test_add_func 853 ("/string-utils/sc_string_append_char_pair__NULL_buf", 854 test_sc_string_append_char_pair__NULL_buf); 855 g_test_add_func("/string-utils/sc_string_append_char_pair__overflow", 856 test_sc_string_append_char_pair__overflow); 857 g_test_add_func 858 ("/string-utils/sc_string_append_char_pair__invalid_zero_c1", 859 test_sc_string_append_char_pair__invalid_zero_c1); 860 g_test_add_func 861 ("/string-utils/sc_string_append_char_pair__invalid_zero_c2", 862 test_sc_string_append_char_pair__invalid_zero_c2); 863 g_test_add_func("/string-utils/sc_string_append_char_pair__normal", 864 test_sc_string_append_char_pair__normal); 865 g_test_add_func("/string-utils/sc_string_quote__NULL_buf", 866 test_sc_string_quote_NULL_str); 867 g_test_add_func 868 ("/string-utils/sc_string_append_char_pair__uninitialized_buf", 869 test_sc_string_append_char_pair__uninitialized_buf); 870 g_test_add_func("/string-utils/sc_string_quote", test_sc_string_quote); 871 g_test_add_func("/string-utils/sc_strdup", test_sc_strdup); 872 }