1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set expandtab shiftwidth=4 tabstop=4: */
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "modp_burl.h"
8 #include "minunit.h"
9
10 /**
11 * Test empty input to encode and decode
12 */
testUrlEmpty()13 static char* testUrlEmpty()
14 {
15 int d;
16 char buf[1000];
17 buf[0] = 1;
18 d = modp_burl_encode(buf, "", 0);
19 mu_assert_int_equals(d, 0);
20 mu_assert(buf[0] == 0);
21
22 buf[0] = 1;
23 d = modp_burl_decode(buf, "", 0);
24 mu_assert_int_equals(d, 0);
25 mu_assert(buf[0] == 0);
26
27 return 0;
28 }
29
30 /**
31 * test space <--> plus conversion
32 */
testUrlSpaces()33 static char* testUrlSpaces()
34 {
35 size_t d = 0;
36 char buf[1000];
37 const char* input = " ";
38 const char* output = "+++";
39
40 d = modp_burl_encode(buf, input, strlen(input));
41 mu_assert_int_equals(d, strlen(output));
42 mu_assert_str_equals(buf, output);
43
44 d = modp_burl_decode(buf, output, strlen(output));
45 mu_assert_int_equals(d, strlen(input));
46 mu_assert_str_equals(buf, input);
47
48 return 0;
49 }
50
51 /**
52 * Test charactes that should be unchanged
53 */
testUrlUntouched()54 static char* testUrlUntouched()
55 {
56 const char* lower = "abcdefghijklmnopqrstuvwxyz";
57 const char* upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
58 const char* digits = "0123456789";
59 const char* special = ".-_";
60 char buf[1000];
61 size_t d = 0;
62
63 memset(buf, 0, sizeof(buf));
64 d = modp_burl_encode(buf, lower, strlen(lower));
65 mu_assert_int_equals(d, strlen(lower));
66 mu_assert_str_equals(buf, lower);
67 memset(buf, 0, sizeof(buf));
68 d = modp_burl_decode(buf, lower, strlen(lower));
69 mu_assert_int_equals(d, strlen(lower));
70 mu_assert_str_equals(buf, lower);
71
72 memset(buf, 0, sizeof(buf));
73 d = modp_burl_encode(buf, upper, strlen(upper));
74 mu_assert_int_equals(d, strlen(upper));
75 mu_assert_str_equals(buf, upper);
76 memset(buf, 0, sizeof(buf));
77 d = modp_burl_decode(buf, upper, strlen(upper));
78 mu_assert_int_equals(d, strlen(upper));
79 mu_assert_str_equals(buf, upper);
80
81 memset(buf, 0, sizeof(buf));
82 d = modp_burl_encode(buf, digits, strlen(digits));
83 mu_assert_int_equals(d, strlen(digits));
84 mu_assert_str_equals(buf, digits);
85 memset(buf, 0, sizeof(buf));
86 d = modp_burl_decode(buf, digits, strlen(digits));
87 mu_assert_int_equals(d, strlen(digits));
88 mu_assert_str_equals(buf, digits);
89
90 memset(buf, 0, sizeof(buf));
91 d = modp_burl_encode(buf, special, strlen(special));
92 mu_assert_int_equals(d, strlen(special));
93 mu_assert_str_equals(buf, special);
94 memset(buf, 0, sizeof(buf));
95 d = modp_burl_decode(buf, special, strlen(special));
96 mu_assert_int_equals(d, strlen(special));
97 mu_assert_str_equals(buf, special);
98
99 return 0;
100 }
101
102
103 /**
104 * Test charactes that should be unchanged
105 */
testUrlMinUntouched()106 static char* testUrlMinUntouched()
107 {
108 const char* lower = "abcdefghijklmnopqrstuvwxyz";
109 const char* upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
110 const char* digits = "0123456789";
111 const char* special = ".-_";
112 const char* extra = "~!$()*,;:@/?";
113 char buf[1000];
114 size_t d = 0;
115
116 memset(buf, 0, sizeof(buf));
117 d = modp_burl_min_encode(buf, lower, strlen(lower));
118 mu_assert_int_equals(d, strlen(lower));
119 mu_assert_str_equals(buf, lower);
120 memset(buf, 0, sizeof(buf));
121 d = modp_burl_decode(buf, lower, strlen(lower));
122 mu_assert_int_equals(d, strlen(lower));
123 mu_assert_str_equals(buf, lower);
124
125 memset(buf, 0, sizeof(buf));
126 d = modp_burl_min_encode(buf, upper, strlen(upper));
127 mu_assert_int_equals(d, strlen(upper));
128 mu_assert_str_equals(buf, upper);
129 memset(buf, 0, sizeof(buf));
130 d = modp_burl_decode(buf, upper, strlen(upper));
131 mu_assert_int_equals(d, strlen(upper));
132 mu_assert_str_equals(buf, upper);
133
134 memset(buf, 0, sizeof(buf));
135 d = modp_burl_min_encode(buf, digits, strlen(digits));
136 mu_assert_int_equals(d, strlen(digits));
137 mu_assert_str_equals(buf, digits);
138 memset(buf, 0, sizeof(buf));
139 d = modp_burl_decode(buf, digits, strlen(digits));
140 mu_assert_int_equals(d, strlen(digits));
141 mu_assert_str_equals(buf, digits);
142
143 memset(buf, 0, sizeof(buf));
144 d = modp_burl_min_encode(buf, special, strlen(special));
145 mu_assert_int_equals(d, strlen(special));
146 mu_assert_str_equals(buf, special);
147 memset(buf, 0, sizeof(buf));
148 d = modp_burl_decode(buf, special, strlen(special));
149 mu_assert_int_equals(d, strlen(special));
150 mu_assert_str_equals(buf, special);
151
152 memset(buf, 0, sizeof(buf));
153 d = modp_burl_min_encode(buf, extra, strlen(extra));
154 mu_assert_int_equals(d, strlen(extra));
155 mu_assert_str_equals(buf, extra);
156 memset(buf, 0, sizeof(buf));
157 d = modp_burl_decode(buf, extra, strlen(extra));
158 mu_assert_int_equals(d, strlen(extra));
159 mu_assert_str_equals(buf, extra);
160
161 return 0;
162 }
163
164 /** \brief make sure min encoding actually does hex encoding
165 *
166 */
testUrlMinEncodeHex()167 static char* testUrlMinEncodeHex()
168 {
169 char buf[1000];
170 size_t d = 0;
171
172 memset(buf, 0, sizeof(buf));
173 const char* str1 = "a b";
174 d = modp_burl_min_encode(buf, str1, strlen(str1));
175 mu_assert_int_equals(3, d);
176 mu_assert_str_equals("a+b", buf);
177
178 memset(buf, 0, sizeof(buf));
179 const char* str2 = "ab\n";
180 d = modp_burl_min_encode(buf, str2, strlen(str2));
181 mu_assert_int_equals(5, d);
182 mu_assert_str_equals("ab%0A", buf);
183
184 return 0;
185 }
186
testUrlDecodeHexBad()187 static char* testUrlDecodeHexBad()
188 {
189
190 const char* bad1 = "%0X"; // bad trailing char
191 const char* bad2 = "%X0"; // bad leading char
192 const char* bad3 = "%XX"; // bad chars
193 const char* bad4 = "%2"; // not enough room, good char
194 const char* bad5 = "%X"; // not enought room, bad char
195 const char* bad6 = "%"; // test oddball
196 const char* bad7 = "AA%"; // test end of line
197 char bad8[4]; // %XX where X is high bit (test sign char vs. uint8_t*)
198 bad8[0] = '%';
199 bad8[1] = 0x81;
200 bad8[2] = 0x82;
201 bad8[3] = 0;
202
203 size_t d = 0;
204 char buf[1000];
205
206 memset(buf, 0, sizeof(buf));
207 d = modp_burl_decode(buf, bad1, strlen(bad1));
208 mu_assert_int_equals(d, strlen(bad1));
209 mu_assert_str_equals(buf, bad1);
210
211 memset(buf, 0, sizeof(buf));
212 d = modp_burl_decode(buf, bad2, strlen(bad2));
213 mu_assert_int_equals(d, strlen(bad2));
214 mu_assert_str_equals(bad2, buf);
215
216 memset(buf, 0, sizeof(buf));
217 d = modp_burl_decode(buf, bad3, strlen(bad3));
218 mu_assert_int_equals(d, strlen(bad3));
219 mu_assert_str_equals(buf, bad3);
220
221 memset(buf, 0, sizeof(buf));
222 d = modp_burl_decode(buf, bad4, strlen(bad4));
223 mu_assert_int_equals(d, strlen(bad4));
224 mu_assert_str_equals(buf, bad4);
225
226 memset(buf, 0, sizeof(buf));
227 d = modp_burl_decode(buf, bad5, strlen(bad5));
228 mu_assert_int_equals(d, strlen(bad5));
229 mu_assert_str_equals(buf, bad5);
230
231 memset(buf, 0, sizeof(buf));
232 d= modp_burl_decode(buf, bad6, strlen(bad6));
233 mu_assert_int_equals(d, strlen(bad6));
234 mu_assert_str_equals(buf, bad6);
235
236 memset(buf, 0, sizeof(buf));
237 d= modp_burl_decode(buf, bad7, strlen(bad7));
238 mu_assert_int_equals(d, strlen(bad7));
239 mu_assert_str_equals(buf, bad7);
240
241 memset(buf, 0, sizeof(buf));
242 d = modp_burl_decode(buf, bad8, strlen(bad8));
243 mu_assert_int_equals(d, strlen(bad8));
244 mu_assert_str_equals(buf, bad8);
245 return 0;
246
247 return 0;
248 }
249
testUrlDecodeHex()250 static char* testUrlDecodeHex()
251 {
252 int d; // size of output
253 int i, j; // loops
254 int k = 0; // position in inputbuf;
255 char inputbuf[3*256+1];
256 char output[257];
257 char msg[1000];
258
259 // make input string contain every possible "%XX"
260 static const char* hexdigits1 = "0123456789ABCDEF";
261 memset(inputbuf, 0, sizeof(inputbuf));
262 memset(output, 1, sizeof(output));
263 k = 0;
264 for (i = 0; i < 16; ++i) {
265 for (j = 0; j < 16; ++j) {
266 inputbuf[k++] = '%';
267 inputbuf[k++] = hexdigits1[i];
268 inputbuf[k++] = hexdigits1[j];
269 }
270 }
271
272 d = modp_burl_decode(output, inputbuf, sizeof(inputbuf)-1);
273 mu_assert_int_equals(d, 256);
274 for (i = 0; i < 256; ++i) {
275 sprintf(msg, "Loop at %d", i);
276 mu_assert_int_equals_msg(msg, i, (unsigned char) output[i]);
277 }
278
279 // make input string contain every possible "%XX"
280 static const char* hexdigits2 = "0123456789abcdef";
281 memset(inputbuf, 0, sizeof(inputbuf));
282 memset(output, 1, sizeof(output));
283
284 k = 0;
285 for (i = 0; i < 16; ++i) {
286 for (j = 0; j < 16; ++j) {
287 inputbuf[k++] = '%';
288 inputbuf[k++] = hexdigits2[i];
289 inputbuf[k++] = hexdigits2[j];
290 }
291 }
292
293 d = modp_burl_decode(output, inputbuf, sizeof(inputbuf)-1);
294 mu_assert_int_equals(256, d);
295 for (i = 0; i < 256; ++i) {
296 sprintf(msg, "Loop at %d", i);
297 mu_assert_int_equals_msg(msg, i, (unsigned char)output[i]);
298 }
299 return 0;
300 }
301
302 /**
303 * test hex encoding.. to be done after hex decoding
304 * is tested.
305 */
testHexEncoding()306 static char* testHexEncoding()
307 {
308 int i = 0;
309 int d = 0;
310 char msg[1000];
311 char input[257];
312 memset(input, 0, sizeof(input));
313 char output[257*3];
314 memset(output, 0, sizeof(output));
315 char buf[1000];
316 memset(buf, 0, sizeof(buf));
317 d = modp_burl_encode(output, input, 256);
318 d = modp_burl_decode(buf, output, d);
319 mu_assert_int_equals(256, d);
320 for (i= 0; i < 256; ++i) {
321 sprintf(msg, "Loop at %d failed", i);
322 mu_assert_int_equals_msg(msg, input[i], buf[i]);
323 }
324 return 0;
325 }
326
testEncodeStrlen()327 static char* testEncodeStrlen()
328 {
329 char ibuf[100];
330 char obuf[100];
331 memset(ibuf, 0, sizeof(ibuf));
332 memset(obuf, 0, sizeof(obuf));
333
334 // Empty. should be 0
335 ibuf[0] = 0;
336 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
337
338 // Plain, should be same size
339 strcpy(ibuf, "abcdefg");
340 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
341
342 // Plain and spaces, should be same size
343 strcpy(ibuf, "a b c d e f g");
344 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
345
346 // one bad char, adds two bytes
347 strcpy(ibuf, "abcdefg\n");
348 mu_assert_int_equals(strlen(ibuf)+2, (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
349
350 // 2 bad chars, adds 4 bytes
351 strcpy(ibuf, "\nabcdefg\n");
352 mu_assert_int_equals(strlen(ibuf)+4, (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
353 return 0;
354 }
355
356
357 /** \brief test "modp_burl_min_encode_strlen"
358 *
359 */
testEncodeMinStrlen()360 static char* testEncodeMinStrlen()
361 {
362 char ibuf[100];
363 char obuf[100];
364 memset(ibuf, 0, sizeof(ibuf));
365 memset(obuf, 0, sizeof(obuf));
366
367 // Empty. should be 0
368 ibuf[0] = 0;
369 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
370
371 // Plain, should be same size
372 strcpy(ibuf, "abcdefg");
373 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
374
375 // Plain and spaces, should be same size
376 strcpy(ibuf, "a b c d e f g");
377 mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
378
379 // one bad char, adds two bytes
380 strcpy(ibuf, "abcdefg\n");
381 mu_assert_int_equals(strlen(ibuf)+2, (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
382
383 // 2 bad chars, adds 4 bytes
384 strcpy(ibuf, "\nabcdefg\n");
385 mu_assert_int_equals(strlen(ibuf)+4, (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
386 return 0;
387 }
388
all_tests()389 static char* all_tests()
390 {
391 mu_run_test(testUrlUntouched);
392 mu_run_test(testUrlEmpty);
393 mu_run_test(testUrlSpaces);
394 mu_run_test(testUrlDecodeHex);
395 mu_run_test(testUrlDecodeHexBad);
396 mu_run_test(testHexEncoding);
397 mu_run_test(testEncodeStrlen);
398 mu_run_test(testUrlMinUntouched);
399 mu_run_test(testUrlMinEncodeHex);
400 mu_run_test(testEncodeMinStrlen);
401 return 0;
402 }
403
404 UNITTESTS
405
406