1 /* vim: set ts=8 sts=4 sw=4 tw=80 noet: */
2 /*======================================================================
3 Copyright (C) 2004,2005,2009 Walter Doekes <walter+tthsum@wjd.nu>
4 This file is part of tthsum.
5
6 tthsum is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 tthsum is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with tthsum. If not, see <http://www.gnu.org/licenses/>.
18 ======================================================================*/
19 #include "escape.h"
20
21 #include "test.h"
22 #include "texts.h"
23 #include <string.h>
24
25
help_cmp_symmetric(const char * str,const char * escaped,int should_fail)26 static int help_cmp_symmetric(const char* str, const char* escaped,
27 int should_fail) {
28 char strbuf[2048];
29 char escapedbuf[2048];
30
31 if (strlen(str) >= 512 || strlen(escaped) >= 2048)
32 FAIL3("Test values too large: \"%s\" is %u and %u bytes", escaped,
33 (unsigned)strlen(str), (unsigned)strlen(escaped));
34 strtoctrlesc(escapedbuf, str);
35 if (ctrlesctostr(strbuf, escaped) != 0)
36 FAIL2("ctrlesctostr failed on \"%s\": %s", escaped, get_error());
37 if ((strcmp(strbuf, str) != 0 || strcmp(escapedbuf, escaped) != 0)
38 == !should_fail)
39 FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "",
40 escaped);
41
42 return 0;
43 }
44
help_cmp_unescape(const char * escaped,const char * result,int should_fail)45 static int help_cmp_unescape(const char* escaped, const char* result,
46 int should_fail) {
47 char resultbuf[2048];
48
49 if (strlen(escaped) >= 2048)
50 FAIL2("Test value too large: \"%s\" is %u bytes", escaped,
51 (unsigned)strlen(escaped));
52 if (ctrlesctostr(resultbuf, escaped) != 0)
53 FAIL2("ctrlesctostr failed on \"%s\": %s", escaped, get_error());
54 if (strcmp(resultbuf, result) == !should_fail)
55 FAIL2("Values %sdiffer for \"%s\"", should_fail ? "do NOT " : "",
56 escaped);
57
58 return 0;
59 }
60
test_bidirectional_success()61 static int test_bidirectional_success() {
62 return help_cmp_symmetric("", "", 0)
63 + help_cmp_symmetric("ABC", "ABC", 0)
64 + help_cmp_symmetric("\xff ABC \x80\x81", "\xff ABC \x80\x81", 0)
65 + help_cmp_symmetric(
66 "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
67 "\\x01\\x02\\x03\\x04\\x05\\x06\\a\\b\\t\\n\\v\\f\\r\\x0e\\x0f",
68 0)
69 + help_cmp_symmetric(
70 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
71 "\x1f", "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19"
72 "\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f", 0);
73 }
74
test_bidirectional_fail()75 static int test_bidirectional_fail() {
76 return help_cmp_symmetric(" ", "", 1)
77 + help_cmp_symmetric("ABC", "ABCD", 1)
78 + help_cmp_symmetric("\n", "\\x0a", 1)
79 + help_cmp_symmetric("\r\n", "\\n\\n", 1)
80 + help_cmp_symmetric("\0", "\\x00", 1); /* \0 is not seen */
81 }
82
test_unidirectional_success()83 static int test_unidirectional_success() {
84 return help_cmp_unescape("\\x0d\\n", "\r\n", 0)
85 + help_cmp_unescape("abcdef", "abcdef", 0)
86 + help_cmp_unescape("abc\\x0a\\x0d\\t", "abc\n\r\t", 0)
87 + help_cmp_unescape("\\x00foobar", "", 0) /* leading \0 */
88 + help_cmp_unescape("\\\\x80\x81\\xff", "\\x80\x81\xff", 0);
89 }
90
test_unidirectional_fail()91 static int test_unidirectional_fail() {
92 return help_cmp_unescape("\\x0d\\n", "\\x0d\n", 1)
93 + help_cmp_unescape("abcdef", "abcdefg", 1)
94 + help_cmp_unescape("abc\\x0a\\x0d\\t", "abc\\n\\r\\t", 1)
95 + help_cmp_unescape("\\x00foobar", "foobar", 1)
96 + help_cmp_unescape("\\\\x80\x81\\xff", "\x80\x81\xff", 1);
97 }
98
test_decode_success()99 static int test_decode_success() {
100 char buf[256];
101 return ctrlesctostr(buf, "\\x11")
102 || ctrlesctostr(buf, "abc\\x00def")
103 || ctrlesctostr(buf, "\\x0a\\n\\r\\x0d")
104 || ctrlesctostr(buf, "\a\b\t\v\r\n")
105 || ctrlesctostr(buf, "\\x1A\\x1a");
106 }
107
test_decode_fail()108 static int test_decode_fail() {
109 char buf[256];
110 return !ctrlesctostr(buf, "\\x1")
111 || !ctrlesctostr(buf, "\\0")
112 || !ctrlesctostr(buf, "\\0\\1\\2")
113 || !ctrlesctostr(buf, "\\x1g")
114 || !ctrlesctostr(buf, "\\g")
115 || !ctrlesctostr(buf, "\\N")
116 || !ctrlesctostr(buf, "\\x1G");
117 }
118
119
120 TESTS(escape_test)
121 TEST(test_bidirectional_success);
122 TEST(test_bidirectional_fail);
123 TEST(test_unidirectional_success);
124 TEST(test_unidirectional_fail);
125 TEST(test_decode_success);
126 TEST(test_decode_fail);
127 ENDTESTS
128