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