]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/tests/testRFC1738.cc
Cleanup: un-wrap C++ header includes
[thirdparty/squid.git] / lib / tests / testRFC1738.cc
1 #define SQUID_UNIT_TEST 1
2 #include "squid.h"
3
4 #include <cassert>
5
6 #include "testRFC1738.h"
7
8 /* Being a C library code it is best bodily included and tested with C++ type-safe techniques. */
9 #include "lib/rfc1738.c"
10
11 CPPUNIT_TEST_SUITE_REGISTRATION( testRFC1738 );
12
13 /* Regular Format de-coding tests */
14 void testRFC1738::testUrlDecode()
15 {
16 char *unescaped_str;
17
18 /* regular URL-path */
19 unescaped_str = xstrdup("%2Fdata%2Fsource%2Fpath");
20 rfc1738_unescape(unescaped_str);
21 CPPUNIT_ASSERT(memcmp(unescaped_str, "/data/source/path",18)==0);
22 xfree(unescaped_str);
23
24 /* path in full URL */
25 unescaped_str = xstrdup("http://foo.invalid%2Fdata%2Fsource%2Fpath");
26 rfc1738_unescape(unescaped_str);
27 CPPUNIT_ASSERT(memcmp(unescaped_str, "http://foo.invalid/data/source/path",36)==0);
28 xfree(unescaped_str);
29
30 // TODO query string...
31
32 /* Newline %0A encoded */
33 unescaped_str = xstrdup("w%0Ard");
34 rfc1738_unescape(unescaped_str);
35 CPPUNIT_ASSERT(memcmp(unescaped_str, "w\nrd",5)==0);
36 xfree(unescaped_str);
37
38 /* Handle Un-encoded % */
39 unescaped_str = xstrdup("w%rd");
40 rfc1738_unescape(unescaped_str);
41 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%rd",5)==0);
42 xfree(unescaped_str);
43
44 /* Handle encoded % */
45 unescaped_str = xstrdup("w%%rd");
46 rfc1738_unescape(unescaped_str);
47 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%rd",5)==0);
48 xfree(unescaped_str);
49
50 /* Handle mixed-encoded % */
51 unescaped_str = xstrdup("w%%%rd");
52 rfc1738_unescape(unescaped_str);
53 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%%rd",6)==0);
54 xfree(unescaped_str);
55
56 /* A corrupt string */
57 unescaped_str = xstrdup("Bad String %1");
58 rfc1738_unescape(unescaped_str);
59 CPPUNIT_ASSERT(memcmp(unescaped_str, "Bad String %1",14)==0);
60 xfree(unescaped_str);
61
62 /* A partly corrupt string */
63 unescaped_str = xstrdup("Bad String %1A%3");
64 rfc1738_unescape(unescaped_str);
65 CPPUNIT_ASSERT(memcmp(unescaped_str, "Bad String \032%3",15)==0);
66 xfree(unescaped_str);
67
68 /* A non corrupt string */
69 unescaped_str = xstrdup("Good String %1A");
70 rfc1738_unescape(unescaped_str);
71 CPPUNIT_ASSERT(memcmp(unescaped_str, "Good String \032",14)==0);
72 xfree(unescaped_str);
73 }
74
75 /**
76 * Public API is formed of a triplet of encode functions mapping to the rfc1738_do_encode() engine.
77 *
78 * Flags:
79 * rfc1738_escape == 0
80 * rfc1738_escape_unescaped == -1
81 * rfc1738_escape_part == 1
82 */
83 void testRFC1738::testUrlEncode()
84 {
85 char *result;
86
87 /* TEST: Escaping only unsafe characters */
88
89 /* regular URL (no encoding needed) */
90 result = rfc1738_do_escape("http://foo.invalid/data/source/path", RFC1738_ESCAPE_UNSAFE);
91 CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data/source/path",36)==0);
92
93 /* long string of unsafe # characters */
94 result = rfc1738_do_escape("################ ################ ################ ################ ################ ################ ################ ################", RFC1738_ESCAPE_UNSAFE);
95 CPPUNIT_ASSERT(memcmp(result, "%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23",406)==0);
96
97 /* TEST: escaping only reserved characters */
98
99 /* regular URL (full encoding requested) */
100 result = rfc1738_do_escape("http://foo.invalid/data/source/path", RFC1738_ESCAPE_RESERVED);
101 CPPUNIT_ASSERT(memcmp(result, "http%3A%2F%2Ffoo.invalid%2Fdata%2Fsource%2Fpath",48)==0);
102
103 /* regular path (encoding wanted for ALL special chars) */
104 result = rfc1738_do_escape("/data/source/path", RFC1738_ESCAPE_RESERVED);
105 CPPUNIT_ASSERT(memcmp(result, "%2Fdata%2Fsource%2Fpath",24)==0);
106
107 /* TEST: safety-escaping a string already partially escaped */
108
109 /* escaping of dangerous characters in a partially escaped string */
110 result = rfc1738_do_escape("http://foo.invalid/data%2Fsource[]", RFC1738_ESCAPE_UNESCAPED);
111 CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data%2Fsource%5B%5D",39)==0);
112
113 /* escaping of hexadecimal 0xFF characters in a partially escaped string */
114 result = rfc1738_do_escape("http://foo.invalid/data%2Fsource\xFF\xFF", RFC1738_ESCAPE_UNESCAPED);
115 CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data%2Fsource%FF%FF",39)==0);
116
117 }
118
119 /** SECURITY BUG TESTS: avoid null truncation attacks by skipping %00 bytes */
120 void testRFC1738::PercentZeroNullDecoding()
121 {
122 char *unescaped_str;
123
124 /* Attack with %00 encoded NULL */
125 unescaped_str = xstrdup("w%00rd");
126 rfc1738_unescape(unescaped_str);
127 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%00rd",7)==0);
128 xfree(unescaped_str);
129
130 /* Attack with %0 encoded NULL */
131 unescaped_str = xstrdup("w%0rd");
132 rfc1738_unescape(unescaped_str);
133 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%0rd",6)==0);
134 xfree(unescaped_str);
135
136 /* Handle '0' bytes embeded in encoded % */
137 unescaped_str = xstrdup("w%%00%rd");
138 rfc1738_unescape(unescaped_str);
139 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%00%rd",8)==0);
140 xfree(unescaped_str);
141
142 /* Handle NULL bytes with encoded % */
143 unescaped_str = xstrdup("w%%%00%rd");
144 rfc1738_unescape(unescaped_str);
145 CPPUNIT_ASSERT(memcmp(unescaped_str, "w%%00%rd",9)==0);
146 xfree(unescaped_str);
147 }