1 /*- 2 * Copyright (c) 2012 Dag-Erling Smørgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $Id: t_openpam_readword.c 584 2012-04-07 22:47:16Z des $ 31 */ 32 33 #ifdef HAVE_CONFIG_H 34 # include "config.h" 35 #endif 36 37 #include <err.h> 38 #include <errno.h> 39 #include <fcntl.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 #include <security/pam_appl.h> 46 #include <security/openpam.h> 47 48 #include "t.h" 49 50 static char filename[1024]; 51 static FILE *f; 52 53 /* 54 * Open the temp file and immediately unlink it so it doesn't leak in case 55 * of premature exit. 56 */ 57 static void 58 orw_open(void) 59 { 60 int fd; 61 62 if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) 63 err(1, "%s(): %s", __func__, filename); 64 if ((f = fdopen(fd, "r+")) == NULL) 65 err(1, "%s(): %s", __func__, filename); 66 if (unlink(filename) < 0) 67 err(1, "%s(): %s", __func__, filename); 68 } 69 70 /* 71 * Write text to the temp file. 72 */ 73 static void 74 orw_output(const char *fmt, ...) 75 { 76 va_list ap; 77 78 va_start(ap, fmt); 79 vfprintf(f, fmt, ap); 80 va_end(ap); 81 if (ferror(f)) 82 err(1, "%s", filename); 83 } 84 85 /* 86 * Rewind the temp file. 87 */ 88 static void 89 orw_rewind(void) 90 { 91 92 errno = 0; 93 rewind(f); 94 if (errno != 0) 95 err(1, "%s(): %s", __func__, filename); 96 } 97 98 /* 99 * Read a word from the temp file and verify that the result matches our 100 * expectations: whether a word was read at all, how many lines were read 101 * (in case of quoted or escaped newlines), whether we reached the end of 102 * the file and whether we reached the end of the line. 103 */ 104 static int 105 orw_expect(const char *expected, int lines, int eof, int eol) 106 { 107 int ch, lineno = 0; 108 char *got; 109 size_t len; 110 111 got = openpam_readword(f, &lineno, &len); 112 if (ferror(f)) 113 err(1, "%s(): %s", __func__, filename); 114 if (expected != NULL && got == NULL) { 115 t_verbose("expected <<%s>>, got nothing\n", expected); 116 return (0); 117 } 118 if (expected == NULL && got != NULL) { 119 t_verbose("expected nothing, got <<%s>>\n", got); 120 return (0); 121 } 122 if (expected != NULL && got != NULL && strcmp(expected, got) != 0) { 123 t_verbose("expected <<%s>>, got <<%s>>\n", expected, got); 124 return (0); 125 } 126 if (lineno != lines) { 127 t_verbose("expected to advance %d lines, advanced %d lines\n", 128 lines, lineno); 129 return (0); 130 } 131 if (eof && !feof(f)) { 132 t_verbose("expected EOF, but didn't get it\n"); 133 return (0); 134 } 135 if (!eof && feof(f)) { 136 t_verbose("didn't expect EOF, but got it anyway\n"); 137 return (0); 138 } 139 ch = fgetc(f); 140 if (ferror(f)) 141 err(1, "%s(): %s", __func__, filename); 142 if (eol && ch != '\n') { 143 t_verbose("expected EOL, but didn't get it\n"); 144 return (0); 145 } 146 if (!eol && ch == '\n') { 147 t_verbose("didn't expect EOL, but got it anyway\n"); 148 return (0); 149 } 150 if (ch != EOF) 151 ungetc(ch, f); 152 return (1); 153 } 154 155 /* 156 * Close the temp file. 157 */ 158 void 159 orw_close(void) 160 { 161 162 if (fclose(f) != 0) 163 err(1, "%s(): %s", __func__, filename); 164 f = NULL; 165 } 166 167 168 /*************************************************************************** 169 * Lines without words 170 */ 171 172 T_FUNC(empty_input, "empty input") 173 { 174 int ret; 175 176 orw_open(); 177 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 178 orw_close(); 179 return (ret); 180 } 181 182 T_FUNC(empty_line, "empty line") 183 { 184 int ret; 185 186 orw_open(); 187 orw_output("\n"); 188 orw_rewind(); 189 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 190 orw_close(); 191 return (ret); 192 } 193 194 T_FUNC(unterminated_line, "unterminated line") 195 { 196 int ret; 197 198 orw_open(); 199 orw_output(" "); 200 orw_rewind(); 201 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 202 orw_close(); 203 return (ret); 204 } 205 206 T_FUNC(single_whitespace, "single whitespace") 207 { 208 int ret; 209 210 orw_open(); 211 orw_output(" \n"); 212 orw_rewind(); 213 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 214 orw_close(); 215 return (ret); 216 } 217 218 T_FUNC(multiple_whitespace, "multiple whitespace") 219 { 220 int ret; 221 222 orw_open(); 223 orw_output(" \t\r\n"); 224 orw_rewind(); 225 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 226 orw_close(); 227 return (ret); 228 } 229 230 T_FUNC(comment, "comment") 231 { 232 int ret; 233 234 orw_open(); 235 orw_output("# comment\n"); 236 orw_rewind(); 237 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 238 orw_close(); 239 return (ret); 240 } 241 242 T_FUNC(whitespace_before_comment, "whitespace before comment") 243 { 244 int ret; 245 246 orw_open(); 247 orw_output(" # comment\n"); 248 orw_rewind(); 249 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 250 orw_close(); 251 return (ret); 252 } 253 254 255 /*************************************************************************** 256 * Simple cases - no quotes or escapes 257 */ 258 259 T_FUNC(single_word, "single word") 260 { 261 const char *word = "hello"; 262 int ret; 263 264 orw_open(); 265 orw_output("%s\n", word); 266 orw_rewind(); 267 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 268 orw_close(); 269 return (ret); 270 } 271 272 T_FUNC(single_whitespace_before_word, "single whitespace before word") 273 { 274 const char *word = "hello"; 275 int ret; 276 277 orw_open(); 278 orw_output(" %s\n", word); 279 orw_rewind(); 280 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 281 orw_close(); 282 return (ret); 283 } 284 285 T_FUNC(double_whitespace_before_word, "double whitespace before word") 286 { 287 const char *word = "hello"; 288 int ret; 289 290 orw_open(); 291 orw_output(" %s\n", word); 292 orw_rewind(); 293 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 294 orw_close(); 295 return (ret); 296 } 297 298 T_FUNC(single_whitespace_after_word, "single whitespace after word") 299 { 300 const char *word = "hello"; 301 int ret; 302 303 orw_open(); 304 orw_output("%s \n", word); 305 orw_rewind(); 306 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); 307 orw_close(); 308 return (ret); 309 } 310 311 T_FUNC(double_whitespace_after_word, "double whitespace after word") 312 { 313 const char *word = "hello"; 314 int ret; 315 316 orw_open(); 317 orw_output("%s \n", word); 318 orw_rewind(); 319 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); 320 orw_close(); 321 return (ret); 322 } 323 324 T_FUNC(comment_after_word, "comment after word") 325 { 326 const char *word = "hello"; 327 int ret; 328 329 orw_open(); 330 orw_output("%s # comment\n", word); 331 orw_rewind(); 332 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 333 orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 334 orw_close(); 335 return (ret); 336 } 337 338 T_FUNC(word_containing_hash, "word containing hash") 339 { 340 const char *word = "hello#world"; 341 int ret; 342 343 orw_open(); 344 orw_output("%s\n", word); 345 orw_rewind(); 346 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 347 orw_close(); 348 return (ret); 349 } 350 351 T_FUNC(two_words, "two words") 352 { 353 const char *word[] = { "hello", "world" }; 354 int ret; 355 356 orw_open(); 357 orw_output("%s %s\n", word[0], word[1]); 358 orw_rewind(); 359 ret = orw_expect(word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 360 orw_expect(word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 361 orw_close(); 362 return (ret); 363 } 364 365 366 /*************************************************************************** 367 * Escapes 368 */ 369 370 T_FUNC(naked_escape, "naked escape") 371 { 372 int ret; 373 374 orw_open(); 375 orw_output("\\"); 376 orw_rewind(); 377 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 378 orw_close(); 379 return (ret); 380 } 381 382 T_FUNC(escaped_escape, "escaped escape") 383 { 384 int ret; 385 386 orw_open(); 387 orw_output("\\\\\n"); 388 orw_rewind(); 389 ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 390 orw_close(); 391 return (ret); 392 } 393 394 T_FUNC(escaped_whitespace, "escaped whitespace") 395 { 396 int ret; 397 398 orw_open(); 399 orw_output("\\ \\\t \\\r \\\n\n"); 400 orw_rewind(); 401 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 402 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 403 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 404 /* this last one is a line continuation */ 405 orw_expect(NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 406 orw_close(); 407 return (ret); 408 } 409 410 T_FUNC(escaped_newline_before_word, "escaped newline before word") 411 { 412 int ret; 413 414 orw_open(); 415 orw_output("\\\nhello world\n"); 416 orw_rewind(); 417 ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); 418 orw_close(); 419 return (ret); 420 } 421 422 T_FUNC(escaped_newline_within_word, "escaped newline within word") 423 { 424 int ret; 425 426 orw_open(); 427 orw_output("hello\\\nworld\n"); 428 orw_rewind(); 429 ret = orw_expect("helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 430 orw_close(); 431 return (ret); 432 } 433 434 T_FUNC(escaped_newline_after_word, "escaped newline after word") 435 { 436 int ret; 437 438 orw_open(); 439 orw_output("hello\\\n world\n"); 440 orw_rewind(); 441 ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); 442 orw_close(); 443 return (ret); 444 } 445 446 T_FUNC(escaped_letter, "escaped letter") 447 { 448 int ret; 449 450 orw_open(); 451 orw_output("\\z\n"); 452 orw_rewind(); 453 ret = orw_expect("z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 454 orw_close(); 455 return (ret); 456 } 457 458 459 /*************************************************************************** 460 * Quotes 461 */ 462 463 T_FUNC(naked_single_quote, "naked single quote") 464 { 465 int ret; 466 467 orw_open(); 468 orw_output("'"); 469 orw_rewind(); 470 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 471 orw_close(); 472 return (ret); 473 } 474 475 T_FUNC(naked_double_quote, "naked double quote") 476 { 477 int ret; 478 479 orw_open(); 480 orw_output("\""); 481 orw_rewind(); 482 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 483 orw_close(); 484 return (ret); 485 } 486 487 T_FUNC(empty_single_quotes, "empty single quotes") 488 { 489 int ret; 490 491 orw_open(); 492 orw_output("''\n"); 493 orw_rewind(); 494 ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 495 orw_close(); 496 return (ret); 497 } 498 499 T_FUNC(empty_double_quotes, "empty double quotes") 500 { 501 int ret; 502 503 orw_open(); 504 orw_output("\"\"\n"); 505 orw_rewind(); 506 ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 507 orw_close(); 508 return (ret); 509 } 510 511 T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes") 512 { 513 int ret; 514 515 orw_open(); 516 orw_output("\"' '\"\n"); 517 orw_rewind(); 518 ret = orw_expect("' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 519 orw_close(); 520 return (ret); 521 } 522 523 T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes") 524 { 525 int ret; 526 527 orw_open(); 528 orw_output("'\" \"'\n"); 529 orw_rewind(); 530 ret = orw_expect("\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 531 orw_close(); 532 return (ret); 533 } 534 535 T_FUNC(single_quoted_whitespace, "single-quoted whitespace") 536 { 537 int ret; 538 539 orw_open(); 540 orw_output("' ' '\t' '\r' '\n'\n"); 541 orw_rewind(); 542 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 543 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 544 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 545 orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 546 orw_close(); 547 return (ret); 548 } 549 550 T_FUNC(double_quoted_whitespace, "double-quoted whitespace") 551 { 552 int ret; 553 554 orw_open(); 555 orw_output("\" \" \"\t\" \"\r\" \"\n\"\n"); 556 orw_rewind(); 557 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 558 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 559 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 560 orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 561 orw_close(); 562 return (ret); 563 } 564 565 T_FUNC(single_quoted_words, "single-quoted words") 566 { 567 int ret; 568 569 orw_open(); 570 orw_output("'hello world'\n"); 571 orw_rewind(); 572 ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 573 orw_close(); 574 return (ret); 575 } 576 577 T_FUNC(double_quoted_words, "double-quoted words") 578 { 579 int ret; 580 581 orw_open(); 582 orw_output("\"hello world\"\n"); 583 orw_rewind(); 584 ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 585 orw_close(); 586 return (ret); 587 } 588 589 590 /*************************************************************************** 591 * Combinations of escape and quotes 592 */ 593 594 T_FUNC(escaped_single_quote, 595 "escaped single quote") 596 { 597 int ret; 598 599 orw_open(); 600 orw_output("\\'\n"); 601 orw_rewind(); 602 ret = orw_expect("'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 603 orw_close(); 604 return (ret); 605 } 606 607 T_FUNC(escaped_double_quote, 608 "escaped double quote") 609 { 610 int ret; 611 612 orw_open(); 613 orw_output("\\\"\n"); 614 orw_rewind(); 615 ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 616 orw_close(); 617 return (ret); 618 } 619 620 T_FUNC(escaped_whitespace_within_single_quotes, 621 "escaped whitespace within single quotes") 622 { 623 int ret; 624 625 orw_open(); 626 orw_output("'\\ ' '\\\t' '\\\r' '\\\n'\n"); 627 orw_rewind(); 628 ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 629 orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 630 orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 631 orw_expect("\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 632 orw_close(); 633 return (ret); 634 } 635 636 T_FUNC(escaped_whitespace_within_double_quotes, 637 "escaped whitespace within double quotes") 638 { 639 int ret; 640 641 orw_open(); 642 orw_output("\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n"); 643 orw_rewind(); 644 ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 645 orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 646 orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 647 /* this last one is a line continuation */ 648 orw_expect("", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 649 orw_close(); 650 return (ret); 651 } 652 653 T_FUNC(escaped_letter_within_single_quotes, 654 "escaped letter within single quotes") 655 { 656 int ret; 657 658 orw_open(); 659 orw_output("'\\z'\n"); 660 orw_rewind(); 661 ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 662 orw_close(); 663 return (ret); 664 } 665 666 T_FUNC(escaped_letter_within_double_quotes, 667 "escaped letter within double quotes") 668 { 669 int ret; 670 671 orw_open(); 672 orw_output("\"\\z\"\n"); 673 orw_rewind(); 674 ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 675 orw_close(); 676 return (ret); 677 } 678 679 T_FUNC(escaped_escape_within_single_quotes, 680 "escaped escape within single quotes") 681 { 682 int ret; 683 684 orw_open(); 685 orw_output("'\\\\'\n"); 686 orw_rewind(); 687 ret = orw_expect("\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 688 orw_close(); 689 return (ret); 690 } 691 692 T_FUNC(escaped_escape_within_double_quotes, 693 "escaped escape within double quotes") 694 { 695 int ret; 696 697 orw_open(); 698 orw_output("\"\\\\\"\n"); 699 orw_rewind(); 700 ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 701 orw_close(); 702 return (ret); 703 } 704 705 T_FUNC(escaped_single_quote_within_single_quotes, 706 "escaped single quote within single quotes") 707 { 708 int ret; 709 710 orw_open(); 711 orw_output("'\\''\n"); 712 orw_rewind(); 713 ret = orw_expect(NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/); 714 orw_close(); 715 return (ret); 716 } 717 718 T_FUNC(escaped_double_quote_within_single_quotes, 719 "escaped double quote within single quotes") 720 { 721 int ret; 722 723 orw_open(); 724 orw_output("'\\\"'\n"); 725 orw_rewind(); 726 ret = orw_expect("\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 727 orw_close(); 728 return (ret); 729 } 730 731 T_FUNC(escaped_single_quote_within_double_quotes, 732 "escaped single quote within double quotes") 733 { 734 int ret; 735 736 orw_open(); 737 orw_output("\"\\'\"\n"); 738 orw_rewind(); 739 ret = orw_expect("\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 740 orw_close(); 741 return (ret); 742 } 743 744 T_FUNC(escaped_double_quote_within_double_quotes, 745 "escaped double quote within double quotes") 746 { 747 int ret; 748 749 orw_open(); 750 orw_output("\"\\\"\"\n"); 751 orw_rewind(); 752 ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 753 orw_close(); 754 return (ret); 755 } 756 757 758 /*************************************************************************** 759 * Boilerplate 760 */ 761 762 const struct t_test *t_plan[] = { 763 T(empty_input), 764 T(empty_line), 765 T(single_whitespace), 766 T(multiple_whitespace), 767 T(comment), 768 T(whitespace_before_comment), 769 770 T(single_word), 771 T(single_whitespace_before_word), 772 T(double_whitespace_before_word), 773 T(single_whitespace_after_word), 774 T(double_whitespace_after_word), 775 T(comment_after_word), 776 T(word_containing_hash), 777 T(two_words), 778 779 T(naked_escape), 780 T(escaped_escape), 781 T(escaped_whitespace), 782 T(escaped_newline_before_word), 783 T(escaped_newline_within_word), 784 T(escaped_newline_after_word), 785 T(escaped_letter), 786 787 T(naked_single_quote), 788 T(naked_double_quote), 789 T(empty_single_quotes), 790 T(empty_double_quotes), 791 T(single_quotes_within_double_quotes), 792 T(double_quotes_within_single_quotes), 793 T(single_quoted_whitespace), 794 T(double_quoted_whitespace), 795 T(single_quoted_words), 796 T(double_quoted_words), 797 798 T(escaped_single_quote), 799 T(escaped_double_quote), 800 T(escaped_whitespace_within_single_quotes), 801 T(escaped_whitespace_within_double_quotes), 802 T(escaped_letter_within_single_quotes), 803 T(escaped_letter_within_double_quotes), 804 T(escaped_escape_within_single_quotes), 805 T(escaped_escape_within_double_quotes), 806 T(escaped_single_quote_within_single_quotes), 807 T(escaped_double_quote_within_single_quotes), 808 T(escaped_single_quote_within_double_quotes), 809 T(escaped_double_quote_within_double_quotes), 810 811 NULL 812 }; 813 814 const struct t_test ** 815 t_prepare(int argc, char *argv[]) 816 { 817 818 (void)argc; 819 (void)argv; 820 snprintf(filename, sizeof filename, "%s.%d.tmp", t_progname, getpid()); 821 if (filename == NULL) 822 err(1, "asprintf()"); 823 return (t_plan); 824 } 825 826 void 827 t_cleanup(void) 828 { 829 } 830