t_openpam_readword.c revision 1.1.1.2 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 Smrgrav
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 /***************************************************************************
109 * Lines without words
110 */
111
112 T_FUNC(empty_input, "empty input")
113 {
114 struct t_file *tf;
115 int ret;
116
117 tf = t_fopen(NULL);
118 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
119 t_fclose(tf);
120 return (ret);
121 }
122
123 T_FUNC(empty_line, "empty line")
124 {
125 struct t_file *tf;
126 int ret;
127
128 tf = t_fopen(NULL);
129 t_fprintf(tf, "\n");
130 t_frewind(tf);
131 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
132 t_fclose(tf);
133 return (ret);
134 }
135
136 T_FUNC(unterminated_line, "unterminated line")
137 {
138 struct t_file *tf;
139 int ret;
140
141 tf = t_fopen(NULL);
142 t_fprintf(tf, " ");
143 t_frewind(tf);
144 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
145 t_fclose(tf);
146 return (ret);
147 }
148
149 T_FUNC(single_whitespace, "single whitespace")
150 {
151 struct t_file *tf;
152 int ret;
153
154 tf = t_fopen(NULL);
155 t_fprintf(tf, " \n");
156 t_frewind(tf);
157 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
158 t_fclose(tf);
159 return (ret);
160 }
161
162 T_FUNC(multiple_whitespace, "multiple whitespace")
163 {
164 struct t_file *tf;
165 int ret;
166
167 tf = t_fopen(NULL);
168 t_fprintf(tf, " \t\r\n");
169 t_frewind(tf);
170 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
171 t_fclose(tf);
172 return (ret);
173 }
174
175 T_FUNC(comment, "comment")
176 {
177 struct t_file *tf;
178 int ret;
179
180 tf = t_fopen(NULL);
181 t_fprintf(tf, "# comment\n");
182 t_frewind(tf);
183 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
184 t_fclose(tf);
185 return (ret);
186 }
187
188 T_FUNC(whitespace_before_comment, "whitespace before comment")
189 {
190 struct t_file *tf;
191 int ret;
192
193 tf = t_fopen(NULL);
194 t_fprintf(tf, " # comment\n");
195 t_frewind(tf);
196 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
197 t_fclose(tf);
198 return (ret);
199 }
200
201
202 /***************************************************************************
204 * Simple cases - no quotes or escapes
205 */
206
207 T_FUNC(single_word, "single word")
208 {
209 const char *word = "hello";
210 struct t_file *tf;
211 int ret;
212
213 tf = t_fopen(NULL);
214 t_fprintf(tf, "%s\n", word);
215 t_frewind(tf);
216 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
217 t_fclose(tf);
218 return (ret);
219 }
220
221 T_FUNC(single_whitespace_before_word, "single whitespace before word")
222 {
223 const char *word = "hello";
224 struct t_file *tf;
225 int ret;
226
227 tf = t_fopen(NULL);
228 t_fprintf(tf, " %s\n", word);
229 t_frewind(tf);
230 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
231 t_fclose(tf);
232 return (ret);
233 }
234
235 T_FUNC(double_whitespace_before_word, "double whitespace before word")
236 {
237 const char *word = "hello";
238 struct t_file *tf;
239 int ret;
240
241 tf = t_fopen(NULL);
242 t_fprintf(tf, " %s\n", word);
243 t_frewind(tf);
244 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
245 t_fclose(tf);
246 return (ret);
247 }
248
249 T_FUNC(single_whitespace_after_word, "single whitespace after word")
250 {
251 const char *word = "hello";
252 struct t_file *tf;
253 int ret;
254
255 tf = t_fopen(NULL);
256 t_fprintf(tf, "%s \n", word);
257 t_frewind(tf);
258 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
259 t_fclose(tf);
260 return (ret);
261 }
262
263 T_FUNC(double_whitespace_after_word, "double whitespace after word")
264 {
265 const char *word = "hello";
266 struct t_file *tf;
267 int ret;
268
269 tf = t_fopen(NULL);
270 t_fprintf(tf, "%s \n", word);
271 t_frewind(tf);
272 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
273 t_fclose(tf);
274 return (ret);
275 }
276
277 T_FUNC(comment_after_word, "comment after word")
278 {
279 const char *word = "hello";
280 struct t_file *tf;
281 int ret;
282
283 tf = t_fopen(NULL);
284 t_fprintf(tf, "%s # comment\n", word);
285 t_frewind(tf);
286 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
287 orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
288 t_fclose(tf);
289 return (ret);
290 }
291
292 T_FUNC(word_containing_hash, "word containing hash")
293 {
294 const char *word = "hello#world";
295 struct t_file *tf;
296 int ret;
297
298 tf = t_fopen(NULL);
299 t_fprintf(tf, "%s\n", word);
300 t_frewind(tf);
301 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
302 t_fclose(tf);
303 return (ret);
304 }
305
306 T_FUNC(two_words, "two words")
307 {
308 const char *word[] = { "hello", "world" };
309 struct t_file *tf;
310 int ret;
311
312 tf = t_fopen(NULL);
313 t_fprintf(tf, "%s %s\n", word[0], word[1]);
314 t_frewind(tf);
315 ret = orw_expect(tf, word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
316 orw_expect(tf, word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
317 t_fclose(tf);
318 return (ret);
319 }
320
321
322 /***************************************************************************
324 * Escapes
325 */
326
327 T_FUNC(naked_escape, "naked escape")
328 {
329 struct t_file *tf;
330 int ret;
331
332 tf = t_fopen(NULL);
333 t_fprintf(tf, "\\");
334 t_frewind(tf);
335 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
336 t_fclose(tf);
337 return (ret);
338 }
339
340 T_FUNC(escaped_escape, "escaped escape")
341 {
342 struct t_file *tf;
343 int ret;
344
345 tf = t_fopen(NULL);
346 t_fprintf(tf, "\\\\\n");
347 t_frewind(tf);
348 ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
349 t_fclose(tf);
350 return (ret);
351 }
352
353 T_FUNC(escaped_whitespace, "escaped whitespace")
354 {
355 struct t_file *tf;
356 int ret;
357
358 tf = t_fopen(NULL);
359 t_fprintf(tf, "\\ \\\t \\\r \\\n\n");
360 t_frewind(tf);
361 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
362 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
363 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
364 /* this last one is a line continuation */
365 orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
366 t_fclose(tf);
367 return (ret);
368 }
369
370 T_FUNC(escaped_newline_before_word, "escaped newline before word")
371 {
372 struct t_file *tf;
373 int ret;
374
375 tf = t_fopen(NULL);
376 t_fprintf(tf, "\\\nhello world\n");
377 t_frewind(tf);
378 ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
379 t_fclose(tf);
380 return (ret);
381 }
382
383 T_FUNC(escaped_newline_within_word, "escaped newline within word")
384 {
385 struct t_file *tf;
386 int ret;
387
388 tf = t_fopen(NULL);
389 t_fprintf(tf, "hello\\\nworld\n");
390 t_frewind(tf);
391 ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
392 t_fclose(tf);
393 return (ret);
394 }
395
396 T_FUNC(escaped_newline_after_word, "escaped newline after word")
397 {
398 struct t_file *tf;
399 int ret;
400
401 tf = t_fopen(NULL);
402 t_fprintf(tf, "hello\\\n world\n");
403 t_frewind(tf);
404 ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
405 t_fclose(tf);
406 return (ret);
407 }
408
409 T_FUNC(escaped_letter, "escaped letter")
410 {
411 struct t_file *tf;
412 int ret;
413
414 tf = t_fopen(NULL);
415 t_fprintf(tf, "\\z\n");
416 t_frewind(tf);
417 ret = orw_expect(tf, "z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
418 t_fclose(tf);
419 return (ret);
420 }
421
422
423 /***************************************************************************
425 * Quotes
426 */
427
428 T_FUNC(naked_single_quote, "naked single quote")
429 {
430 struct t_file *tf;
431 int ret;
432
433 tf = t_fopen(NULL);
434 t_fprintf(tf, "'");
435 t_frewind(tf);
436 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
437 t_fclose(tf);
438 return (ret);
439 }
440
441 T_FUNC(naked_double_quote, "naked double quote")
442 {
443 struct t_file *tf;
444 int ret;
445
446 tf = t_fopen(NULL);
447 t_fprintf(tf, "\"");
448 t_frewind(tf);
449 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
450 t_fclose(tf);
451 return (ret);
452 }
453
454 T_FUNC(empty_single_quotes, "empty single quotes")
455 {
456 struct t_file *tf;
457 int ret;
458
459 tf = t_fopen(NULL);
460 t_fprintf(tf, "''\n");
461 t_frewind(tf);
462 ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
463 t_fclose(tf);
464 return (ret);
465 }
466
467 T_FUNC(empty_double_quotes, "empty double quotes")
468 {
469 struct t_file *tf;
470 int ret;
471
472 tf = t_fopen(NULL);
473 t_fprintf(tf, "\"\"\n");
474 t_frewind(tf);
475 ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
476 t_fclose(tf);
477 return (ret);
478 }
479
480 T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes")
481 {
482 struct t_file *tf;
483 int ret;
484
485 tf = t_fopen(NULL);
486 t_fprintf(tf, "\"' '\"\n");
487 t_frewind(tf);
488 ret = orw_expect(tf, "' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
489 t_fclose(tf);
490 return (ret);
491 }
492
493 T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes")
494 {
495 struct t_file *tf;
496 int ret;
497
498 tf = t_fopen(NULL);
499 t_fprintf(tf, "'\" \"'\n");
500 t_frewind(tf);
501 ret = orw_expect(tf, "\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
502 t_fclose(tf);
503 return (ret);
504 }
505
506 T_FUNC(single_quoted_whitespace, "single-quoted whitespace")
507 {
508 struct t_file *tf;
509 int ret;
510
511 tf = t_fopen(NULL);
512 t_fprintf(tf, "' ' '\t' '\r' '\n'\n");
513 t_frewind(tf);
514 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
515 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
516 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
517 orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
518 t_fclose(tf);
519 return (ret);
520 }
521
522 T_FUNC(double_quoted_whitespace, "double-quoted whitespace")
523 {
524 struct t_file *tf;
525 int ret;
526
527 tf = t_fopen(NULL);
528 t_fprintf(tf, "\" \" \"\t\" \"\r\" \"\n\"\n");
529 t_frewind(tf);
530 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
531 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
532 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
533 orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
534 t_fclose(tf);
535 return (ret);
536 }
537
538 T_FUNC(single_quoted_words, "single-quoted words")
539 {
540 struct t_file *tf;
541 int ret;
542
543 tf = t_fopen(NULL);
544 t_fprintf(tf, "'hello world'\n");
545 t_frewind(tf);
546 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
547 t_fclose(tf);
548 return (ret);
549 }
550
551 T_FUNC(double_quoted_words, "double-quoted words")
552 {
553 struct t_file *tf;
554 int ret;
555
556 tf = t_fopen(NULL);
557 t_fprintf(tf, "\"hello world\"\n");
558 t_frewind(tf);
559 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
560 t_fclose(tf);
561 return (ret);
562 }
563
564
565 /***************************************************************************
567 * Combinations of quoted and unquoted text
568 */
569
570 T_FUNC(single_quote_before_word, "single quote before word")
571 {
572 struct t_file *tf;
573 int ret;
574
575 tf = t_fopen(NULL);
576 t_fprintf(tf, "'hello 'world\n");
577 t_frewind(tf);
578 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
579 t_fclose(tf);
580 return (ret);
581 }
582
583 T_FUNC(double_quote_before_word, "double quote before word")
584 {
585 struct t_file *tf;
586 int ret;
587
588 tf = t_fopen(NULL);
589 t_fprintf(tf, "\"hello \"world\n");
590 t_frewind(tf);
591 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
592 t_fclose(tf);
593 return (ret);
594 }
595
596 T_FUNC(single_quote_within_word, "single quote within word")
597 {
598 struct t_file *tf;
599 int ret;
600
601 tf = t_fopen(NULL);
602 t_fprintf(tf, "hello' 'world\n");
603 t_frewind(tf);
604 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
605 t_fclose(tf);
606 return (ret);
607 }
608
609 T_FUNC(double_quote_within_word, "double quote within word")
610 {
611 struct t_file *tf;
612 int ret;
613
614 tf = t_fopen(NULL);
615 t_fprintf(tf, "hello\" \"world\n");
616 t_frewind(tf);
617 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
618 t_fclose(tf);
619 return (ret);
620 }
621
622 T_FUNC(single_quote_after_word, "single quote after word")
623 {
624 struct t_file *tf;
625 int ret;
626
627 tf = t_fopen(NULL);
628 t_fprintf(tf, "hello' world'\n");
629 t_frewind(tf);
630 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
631 t_fclose(tf);
632 return (ret);
633 }
634
635 T_FUNC(double_quote_after_word, "double quote after word")
636 {
637 struct t_file *tf;
638 int ret;
639
640 tf = t_fopen(NULL);
641 t_fprintf(tf, "hello\" world\"\n");
642 t_frewind(tf);
643 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
644 t_fclose(tf);
645 return (ret);
646 }
647
648
649 /***************************************************************************
651 * Combinations of escape and quotes
652 */
653
654 T_FUNC(escaped_single_quote,
655 "escaped single quote")
656 {
657 struct t_file *tf;
658 int ret;
659
660 tf = t_fopen(NULL);
661 t_fprintf(tf, "\\'\n");
662 t_frewind(tf);
663 ret = orw_expect(tf, "'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
664 t_fclose(tf);
665 return (ret);
666 }
667
668 T_FUNC(escaped_double_quote,
669 "escaped double quote")
670 {
671 struct t_file *tf;
672 int ret;
673
674 tf = t_fopen(NULL);
675 t_fprintf(tf, "\\\"\n");
676 t_frewind(tf);
677 ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
678 t_fclose(tf);
679 return (ret);
680 }
681
682 T_FUNC(escaped_whitespace_within_single_quotes,
683 "escaped whitespace within single quotes")
684 {
685 struct t_file *tf;
686 int ret;
687
688 tf = t_fopen(NULL);
689 t_fprintf(tf, "'\\ ' '\\\t' '\\\r' '\\\n'\n");
690 t_frewind(tf);
691 ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
692 orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
693 orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
694 orw_expect(tf, "\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
695 t_fclose(tf);
696 return (ret);
697 }
698
699 T_FUNC(escaped_whitespace_within_double_quotes,
700 "escaped whitespace within double quotes")
701 {
702 struct t_file *tf;
703 int ret;
704
705 tf = t_fopen(NULL);
706 t_fprintf(tf, "\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n");
707 t_frewind(tf);
708 ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
709 orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
710 orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
711 /* this last one is a line continuation */
712 orw_expect(tf, "", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
713 t_fclose(tf);
714 return (ret);
715 }
716
717 T_FUNC(escaped_letter_within_single_quotes,
718 "escaped letter within single quotes")
719 {
720 struct t_file *tf;
721 int ret;
722
723 tf = t_fopen(NULL);
724 t_fprintf(tf, "'\\z'\n");
725 t_frewind(tf);
726 ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
727 t_fclose(tf);
728 return (ret);
729 }
730
731 T_FUNC(escaped_letter_within_double_quotes,
732 "escaped letter within double quotes")
733 {
734 struct t_file *tf;
735 int ret;
736
737 tf = t_fopen(NULL);
738 t_fprintf(tf, "\"\\z\"\n");
739 t_frewind(tf);
740 ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
741 t_fclose(tf);
742 return (ret);
743 }
744
745 T_FUNC(escaped_escape_within_single_quotes,
746 "escaped escape within single quotes")
747 {
748 struct t_file *tf;
749 int ret;
750
751 tf = t_fopen(NULL);
752 t_fprintf(tf, "'\\\\'\n");
753 t_frewind(tf);
754 ret = orw_expect(tf, "\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
755 t_fclose(tf);
756 return (ret);
757 }
758
759 T_FUNC(escaped_escape_within_double_quotes,
760 "escaped escape within double quotes")
761 {
762 struct t_file *tf;
763 int ret;
764
765 tf = t_fopen(NULL);
766 t_fprintf(tf, "\"\\\\\"\n");
767 t_frewind(tf);
768 ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
769 t_fclose(tf);
770 return (ret);
771 }
772
773 T_FUNC(escaped_single_quote_within_single_quotes,
774 "escaped single quote within single quotes")
775 {
776 struct t_file *tf;
777 int ret;
778
779 tf = t_fopen(NULL);
780 t_fprintf(tf, "'\\''\n");
781 t_frewind(tf);
782 ret = orw_expect(tf, NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/);
783 t_fclose(tf);
784 return (ret);
785 }
786
787 T_FUNC(escaped_double_quote_within_single_quotes,
788 "escaped double quote within single quotes")
789 {
790 struct t_file *tf;
791 int ret;
792
793 tf = t_fopen(NULL);
794 t_fprintf(tf, "'\\\"'\n");
795 t_frewind(tf);
796 ret = orw_expect(tf, "\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
797 t_fclose(tf);
798 return (ret);
799 }
800
801 T_FUNC(escaped_single_quote_within_double_quotes,
802 "escaped single quote within double quotes")
803 {
804 struct t_file *tf;
805 int ret;
806
807 tf = t_fopen(NULL);
808 t_fprintf(tf, "\"\\'\"\n");
809 t_frewind(tf);
810 ret = orw_expect(tf, "\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
811 t_fclose(tf);
812 return (ret);
813 }
814
815 T_FUNC(escaped_double_quote_within_double_quotes,
816 "escaped double quote within double quotes")
817 {
818 struct t_file *tf;
819 int ret;
820
821 tf = t_fopen(NULL);
822 t_fprintf(tf, "\"\\\"\"\n");
823 t_frewind(tf);
824 ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
825 t_fclose(tf);
826 return (ret);
827 }
828
829
830 /***************************************************************************
832 * Boilerplate
833 */
834
835 const struct t_test *t_plan[] = {
836 T(empty_input),
837 T(empty_line),
838 T(single_whitespace),
839 T(multiple_whitespace),
840 T(comment),
841 T(whitespace_before_comment),
842
843 T(single_word),
844 T(single_whitespace_before_word),
845 T(double_whitespace_before_word),
846 T(single_whitespace_after_word),
847 T(double_whitespace_after_word),
848 T(comment_after_word),
849 T(word_containing_hash),
850 T(two_words),
851
852 T(naked_escape),
853 T(escaped_escape),
854 T(escaped_whitespace),
855 T(escaped_newline_before_word),
856 T(escaped_newline_within_word),
857 T(escaped_newline_after_word),
858 T(escaped_letter),
859
860 T(naked_single_quote),
861 T(naked_double_quote),
862 T(empty_single_quotes),
863 T(empty_double_quotes),
864 T(single_quotes_within_double_quotes),
865 T(double_quotes_within_single_quotes),
866 T(single_quoted_whitespace),
867 T(double_quoted_whitespace),
868 T(single_quoted_words),
869 T(double_quoted_words),
870
871 T(single_quote_before_word),
872 T(double_quote_before_word),
873 T(single_quote_within_word),
874 T(double_quote_within_word),
875 T(single_quote_after_word),
876 T(double_quote_after_word),
877
878 T(escaped_single_quote),
879 T(escaped_double_quote),
880 T(escaped_whitespace_within_single_quotes),
881 T(escaped_whitespace_within_double_quotes),
882 T(escaped_letter_within_single_quotes),
883 T(escaped_letter_within_double_quotes),
884 T(escaped_escape_within_single_quotes),
885 T(escaped_escape_within_double_quotes),
886 T(escaped_single_quote_within_single_quotes),
887 T(escaped_double_quote_within_single_quotes),
888 T(escaped_single_quote_within_double_quotes),
889 T(escaped_double_quote_within_double_quotes),
890
891 NULL
892 };
893
894 const struct t_test **
895 t_prepare(int argc, char *argv[])
896 {
897
898 (void)argc;
899 (void)argv;
900 return (t_plan);
901 }
902
903 void
904 t_cleanup(void)
905 {
906 }
907