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