testRFC1738.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "unitTestMain.h"
11 
12 #include <cassert>
13 #include <cppunit/extensions/HelperMacros.h>
14 
15 /* Being a C library code it is best bodily included and tested with C++ type-safe techniques. */
16 #include "lib/rfc1738.c"
17 
21 class TestRfc1738 : public CPPUNIT_NS::TestFixture
22 {
26 
29 
30 public:
31 protected:
32  void testUrlDecode();
33  void testUrlEncode();
34 
35  // bugs.
37 };
39 
40 /* Regular Format de-coding tests */
42 {
43  char *unescaped_str;
44 
45  /* regular URL-path */
46  unescaped_str = xstrdup("%2Fdata%2Fsource%2Fpath");
47  rfc1738_unescape(unescaped_str);
48  CPPUNIT_ASSERT(memcmp(unescaped_str, "/data/source/path",18)==0);
49  xfree(unescaped_str);
50 
51  /* path in full URL */
52  unescaped_str = xstrdup("http://foo.invalid%2Fdata%2Fsource%2Fpath");
53  rfc1738_unescape(unescaped_str);
54  CPPUNIT_ASSERT(memcmp(unescaped_str, "http://foo.invalid/data/source/path",36)==0);
55  xfree(unescaped_str);
56 
57 // TODO query string...
58 
59  /* Newline %0A encoded */
60  unescaped_str = xstrdup("w%0Ard");
61  rfc1738_unescape(unescaped_str);
62  CPPUNIT_ASSERT(memcmp(unescaped_str, "w\nrd",5)==0);
63  xfree(unescaped_str);
64 
65  /* Handle Un-encoded % */
66  unescaped_str = xstrdup("w%rd");
67  rfc1738_unescape(unescaped_str);
68  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%rd",5)==0);
69  xfree(unescaped_str);
70 
71  /* Handle encoded % */
72  unescaped_str = xstrdup("w%%rd");
73  rfc1738_unescape(unescaped_str);
74  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%rd",5)==0);
75  xfree(unescaped_str);
76 
77  /* Handle mixed-encoded % */
78  unescaped_str = xstrdup("w%%%rd");
79  rfc1738_unescape(unescaped_str);
80  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%%rd",6)==0);
81  xfree(unescaped_str);
82 
83  /* A corrupt string */
84  unescaped_str = xstrdup("Bad String %1");
85  rfc1738_unescape(unescaped_str);
86  CPPUNIT_ASSERT(memcmp(unescaped_str, "Bad String %1",14)==0);
87  xfree(unescaped_str);
88 
89  /* A partly corrupt string */
90  unescaped_str = xstrdup("Bad String %1A%3");
91  rfc1738_unescape(unescaped_str);
92  CPPUNIT_ASSERT(memcmp(unescaped_str, "Bad String \032%3",15)==0);
93  xfree(unescaped_str);
94 
95  /* A non corrupt string */
96  unescaped_str = xstrdup("Good String %1A");
97  rfc1738_unescape(unescaped_str);
98  CPPUNIT_ASSERT(memcmp(unescaped_str, "Good String \032",14)==0);
99  xfree(unescaped_str);
100 }
101 
111 {
112  char *result;
113 
114  /* TEST: Escaping only unsafe characters */
115 
116  /* regular URL (no encoding needed) */
117  result = rfc1738_do_escape("http://foo.invalid/data/source/path", RFC1738_ESCAPE_UNSAFE);
118  CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data/source/path",36)==0);
119 
120  /* long string of unsafe # characters */
121  result = rfc1738_do_escape("################ ################ ################ ################ ################ ################ ################ ################", RFC1738_ESCAPE_UNSAFE);
122  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);
123 
124  /* TEST: escaping only reserved characters */
125 
126  /* regular URL (full encoding requested) */
127  result = rfc1738_do_escape("http://foo.invalid/data/source/path", RFC1738_ESCAPE_RESERVED);
128  CPPUNIT_ASSERT(memcmp(result, "http%3A%2F%2Ffoo.invalid%2Fdata%2Fsource%2Fpath",48)==0);
129 
130  /* regular path (encoding wanted for ALL special chars) */
131  result = rfc1738_do_escape("/data/source/path", RFC1738_ESCAPE_RESERVED);
132  CPPUNIT_ASSERT(memcmp(result, "%2Fdata%2Fsource%2Fpath",24)==0);
133 
134  /* TEST: safety-escaping a string already partially escaped */
135 
136  /* escaping of dangerous characters in a partially escaped string */
137  result = rfc1738_do_escape("http://foo.invalid/data%2Fsource[]", RFC1738_ESCAPE_UNESCAPED);
138  CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data%2Fsource%5B%5D",39)==0);
139 
140  /* escaping of hexadecimal 0xFF characters in a partially escaped string */
141  result = rfc1738_do_escape("http://foo.invalid/data%2Fsource\xFF\xFF", RFC1738_ESCAPE_UNESCAPED);
142  CPPUNIT_ASSERT(memcmp(result, "http://foo.invalid/data%2Fsource%FF%FF",39)==0);
143 
144 }
145 
148 {
149  char *unescaped_str;
150 
151  /* Attack with %00 encoded NULL */
152  unescaped_str = xstrdup("w%00rd");
153  rfc1738_unescape(unescaped_str);
154  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%00rd",7)==0);
155  xfree(unescaped_str);
156 
157  /* Attack with %0 encoded NULL */
158  unescaped_str = xstrdup("w%0rd");
159  rfc1738_unescape(unescaped_str);
160  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%0rd",6)==0);
161  xfree(unescaped_str);
162 
163  /* Handle '0' bytes embedded in encoded % */
164  unescaped_str = xstrdup("w%%00%rd");
165  rfc1738_unescape(unescaped_str);
166  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%00%rd",8)==0);
167  xfree(unescaped_str);
168 
169  /* Handle NULL bytes with encoded % */
170  unescaped_str = xstrdup("w%%%00%rd");
171  rfc1738_unescape(unescaped_str);
172  CPPUNIT_ASSERT(memcmp(unescaped_str, "w%%00%rd",9)==0);
173  xfree(unescaped_str);
174 }
175 
176 int
177 main(int argc, char *argv[])
178 {
179  return TestProgram().run(argc, argv);
180 }
181 
#define RFC1738_ESCAPE_UNSAFE
Definition: rfc1738.h:18
void testUrlDecode()
Definition: testRFC1738.cc:41
#define RFC1738_ESCAPE_RESERVED
Definition: rfc1738.h:19
implements test program's main() function while enabling customization
Definition: unitTestMain.h:25
#define xstrdup
int run(int argc, char *argv[])
Definition: unitTestMain.h:44
void rfc1738_unescape(char *url)
Definition: rfc1738.c:146
CPPUNIT_TEST_SUITE_REGISTRATION(TestRfc1738)
void testUrlEncode()
Definition: testRFC1738.cc:110
CPPUNIT_TEST(testUrlDecode)
CPPUNIT_TEST_SUITE_END()
#define xfree
#define RFC1738_ESCAPE_UNESCAPED
Definition: rfc1738.h:25
char * rfc1738_do_escape(const char *url, int flags)
Definition: rfc1738.c:56
void PercentZeroNullDecoding()
Definition: testRFC1738.cc:147
int main(int argc, char *argv[])
Definition: testRFC1738.cc:177
CPPUNIT_TEST_SUITE(TestRfc1738)

 

Introduction

Documentation

Support

Miscellaneous