VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTUri.cpp@ 57723

Last change on this file since 57723 was 57723, checked in by vboxsync, 10 years ago

RTUri: Reworked the API to a one time parsing and make sure we get UTF-8 clean strings from it.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 KB
Line 
1/* $Id: tstRTUri.cpp 57723 2015-09-11 20:02:15Z vboxsync $ */
2/** @file
3 * IPRT Testcase - URI parsing and creation.
4 */
5
6/*
7 * Copyright (C) 2011-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/uri.h>
32
33#include <iprt/string.h>
34#include <iprt/err.h>
35#include <iprt/mem.h>
36#include <iprt/test.h>
37
38
39/*********************************************************************************************************************************
40* Test data *
41*********************************************************************************************************************************/
42
43static struct
44{
45 const char *pszUri;
46 const char *pszScheme;
47 const char *pszAuthority;
48 const char *pszPath;
49 const char *pszQuery;
50 const char *pszFragment;
51
52 const char *pszUsername;
53 const char *pszPassword;
54 const char *pszHost;
55 uint32_t uPort;
56} g_aTests[] =
57{
58 { /* #0 */
59 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
60 /*.pszScheme =*/ "foo",
61 /*.pszAuthority =*/ "tt:[email protected]:8042",
62 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there",
63 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
64 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
65 /*.pszUsername =*/ "tt",
66 /*.pszPassword =*/ "yt",
67 /*.pszHost =*/ "example.com",
68 /*.uPort =*/ 8042,
69 },
70 { /* #1 */
71 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret",
72 /*.pszScheme =*/ "foo",
73 /*.pszAuthority =*/ "tt:[email protected]:8042",
74 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there",
75 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
76 /*.pszFragment =*/ NULL,
77 /*.pszUsername =*/ "tt",
78 /*.pszPassword =*/ "yt",
79 /*.pszHost =*/ "example.com",
80 /*.uPort =*/ 8042,
81 },
82 { /* #2 */
83 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there",
84 /*.pszScheme =*/ "foo",
85 /*.pszAuthority =*/ "tt:[email protected]:8042",
86 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there",
87 /*.pszQuery =*/ NULL,
88 /*.pszFragment =*/ NULL,
89 /*.pszUsername =*/ "tt",
90 /*.pszPassword =*/ "yt",
91 /*.pszHost =*/ "example.com",
92 /*.uPort =*/ 8042,
93 },
94 { /* #3 */
95 "foo:[email protected]",
96 /*.pszScheme =*/ "foo",
97 /*.pszAuthority =*/ NULL,
98 /*.pszPath =*/ "[email protected]",
99 /*.pszQuery =*/ NULL,
100 /*.pszFragment =*/ NULL,
101 /*.pszUsername =*/ NULL,
102 /*.pszPassword =*/ NULL,
103 /*.pszHost =*/ NULL,
104 /*.uPort =*/ UINT32_MAX,
105 },
106 { /* #4 */
107 "foo:/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
108 /*.pszScheme =*/ "foo",
109 /*.pszAuthority =*/ NULL,
110 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there",
111 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
112 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
113 /*.pszUsername =*/ NULL,
114 /*.pszPassword =*/ NULL,
115 /*.pszHost =*/ NULL,
116 /*.uPort =*/ UINT32_MAX,
117 },
118 { /* #5 */
119 "foo:/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
120 /*.pszScheme =*/ "foo",
121 /*.pszAuthority =*/ NULL,
122 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there",
123 /*.pszQuery =*/ NULL,
124 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
125 /*.pszUsername =*/ NULL,
126 /*.pszPassword =*/ NULL,
127 /*.pszHost =*/ NULL,
128 /*.uPort =*/ UINT32_MAX,
129 },
130 { /* #6 */
131 "urn:example:animal:ferret:nose",
132 /*.pszScheme =*/ "urn",
133 /*.pszAuthority =*/ NULL,
134 /*.pszPath =*/ "example:animal:ferret:nose",
135 /*.pszQuery =*/ NULL,
136 /*.pszFragment =*/ NULL,
137 /*.pszUsername =*/ NULL,
138 /*.pszPassword =*/ NULL,
139 /*.pszHost =*/ NULL,
140 /*.uPort =*/ UINT32_MAX,
141 },
142 { /* #7 */
143 "foo:?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
144 /*.pszScheme =*/ "foo",
145 /*.pszAuthority =*/ NULL,
146 /*.pszPath =*/ NULL,
147 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
148 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
149 /*.pszUsername =*/ NULL,
150 /*.pszPassword =*/ NULL,
151 /*.pszHost =*/ NULL,
152 /*.uPort =*/ UINT32_MAX,
153 },
154 { /* #8 */
155 "foo:#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
156 /*.pszScheme =*/ "foo",
157 /*.pszAuthority =*/ NULL,
158 /*.pszPath =*/ NULL,
159 /*.pszQuery =*/ NULL,
160 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
161 /*.pszUsername =*/ NULL,
162 /*.pszPassword =*/ NULL,
163 /*.pszHost =*/ NULL,
164 /*.uPort =*/ UINT32_MAX,
165 },
166 { /* #9 */
167 "foo://tt:[email protected]:8042/?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
168 /*.pszScheme =*/ "foo",
169 /*.pszAuthority =*/ "tt:[email protected]:8042",
170 /*.pszPath =*/ "/",
171 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
172 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
173 /*.pszUsername =*/ "tt",
174 /*.pszPassword =*/ "yt",
175 /*.pszHost =*/ "example.com",
176 /*.uPort =*/ 8042,
177 },
178 { /* #10 */
179 "foo://tt:[email protected]:8042/",
180 /*.pszScheme =*/ "foo",
181 /*.pszAuthority =*/ "tt:[email protected]:8042",
182 /*.pszPath =*/ "/",
183 /*.pszQuery =*/ NULL,
184 /*.pszFragment =*/ NULL,
185 /*.pszUsername =*/ "tt",
186 /*.pszPassword =*/ "yt",
187 /*.pszHost =*/ "example.com",
188 /*.uPort =*/ 8042,
189 },
190 { /* #11 */
191 "foo://tt:[email protected]:8042?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
192 /*.pszScheme =*/ "foo",
193 /*.pszAuthority =*/ "tt:[email protected]:8042",
194 /*.pszPath =*/ NULL,
195 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret",
196 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
197 /*.pszUsername =*/ "tt",
198 /*.pszPassword =*/ "yt",
199 /*.pszHost =*/ "example.com",
200 /*.uPort =*/ 8042,
201 },
202 { /* #12 */
203 "foo://tt:[email protected]:8042#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",
204 /*.pszScheme =*/ "foo",
205 /*.pszAuthority =*/ "tt:[email protected]:8042",
206 /*.pszPath =*/ NULL,
207 /*.pszQuery =*/ NULL,
208 /*.pszFragment =*/ "nose <>#%\"{}|^[]`",
209 /*.pszUsername =*/ "tt",
210 /*.pszPassword =*/ "yt",
211 /*.pszHost =*/ "example.com",
212 /*.uPort =*/ 8042,
213 },
214 { /* #13 */
215 "foo://tt:[email protected]:8042",
216 /*.pszScheme =*/ "foo",
217 /*.pszAuthority =*/ "tt:[email protected]:8042",
218 /*.pszPath =*/ NULL,
219 /*.pszQuery =*/ NULL,
220 /*.pszFragment =*/ NULL,
221 /*.pszUsername =*/ "tt",
222 /*.pszPassword =*/ "yt",
223 /*.pszHost =*/ "example.com",
224 /*.uPort =*/ 8042,
225 },
226 { /* #14 */
227 "foo:///",
228 /*.pszScheme =*/ "foo",
229 /*.pszAuthority =*/ "",
230 /*.pszPath =*/ "/",
231 /*.pszQuery =*/ NULL,
232 /*.pszFragment =*/ NULL,
233 /*.pszUsername =*/ NULL,
234 /*.pszPassword =*/ NULL,
235 /*.pszHost =*/ NULL,
236 /*.uPort =*/ UINT32_MAX,
237 },
238 { /* #15 */
239 "foo://",
240 /*.pszScheme =*/ "foo",
241 /*.pszAuthority =*/ "",
242 /*.pszPath =*/ NULL,
243 /*.pszQuery =*/ NULL,
244 /*.pszFragment =*/ NULL,
245 /*.pszUsername =*/ NULL,
246 /*.pszPassword =*/ NULL,
247 /*.pszHost =*/ NULL,
248 /*.uPort =*/ UINT32_MAX,
249 },
250};
251
252
253struct URIFILETEST
254{
255 const char *pcszPath;
256 const char *pcszUri;
257 uint32_t uFormat;
258}
259g_apCreateFileURIs[] =
260{
261 { "C:\\over\\ <>#%\"{}|^[]`\\there", "file:///C:%5Cover%5C%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60%5Cthere", URI_FILE_FORMAT_WIN },
262 { "/over/ <>#%\"{}|^[]`/there", "file:///over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there", URI_FILE_FORMAT_UNIX },
263 { "/", "file:///", URI_FILE_FORMAT_UNIX },
264 { "/C:/over/ <>#%\"{}|^[]`/there", "file:///C:%5Cover%5C%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60%5Cthere", URI_FILE_FORMAT_UNIX },
265 { "\\over\\ <>#%\"{}|^[]`\\there", "file:///over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there", URI_FILE_FORMAT_WIN }
266};
267
268
269
270static void tstCreate(size_t idxTest, const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, const char *pszFragment, const char *pszTest)
271{
272 char *pszResult = RTUriCreate(pszScheme, pszAuthority, pszPath, pszQuery, pszFragment);
273 if (pszTest)
274 {
275 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
276 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
277 }
278 else
279 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
280
281 if (pszResult)
282 RTStrFree(pszResult);
283 return;
284}
285
286static void tstFileCreate(size_t idxTest, const char *pszPath, const char *pszTest)
287{
288 char *pszResult = RTUriFileCreate(pszPath);
289 if (pszTest)
290 {
291 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
292 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
293 }
294 else
295 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
296
297 if (pszResult)
298 RTStrFree(pszResult);
299 return;
300}
301
302static void tstFilePath(size_t idxTest, const char *pszUri, const char *pszTest, uint32_t uFormat)
303{
304 char *pszResult = RTUriFilePath(pszUri, uFormat);
305 if (pszTest)
306 {
307 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
308 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
309 }
310 else
311 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest));
312
313 if (pszResult)
314 RTStrFree(pszResult);
315 return;
316}
317
318int main()
319{
320 RTTEST hTest;
321 int rc = RTTestInitAndCreate("tstRTUri", &hTest);
322 if (rc)
323 return rc;
324 RTTestBanner(hTest);
325
326 RTTestISub("RTUriParse & RTUriParsed*");
327 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
328 {
329 RTURIPARSED Parsed;
330 RTTESTI_CHECK_RC(rc = RTUriParse(g_aTests[i].pszUri, &Parsed), VINF_SUCCESS);
331 if (RT_SUCCESS(rc))
332 {
333#define CHECK_STR_API(a_Call, a_pszExpected) \
334 do { \
335 char *pszTmp = a_Call; \
336 if (a_pszExpected) \
337 { \
338 if (!pszTmp) \
339 RTTestIFailed("#%u: %s returns NULL, expected '%s'", i, #a_Call, a_pszExpected); \
340 else if (strcmp(pszTmp, a_pszExpected)) \
341 RTTestIFailed("#%u: %s returns '%s', expected '%s'", i, #a_Call, pszTmp, a_pszExpected); \
342 } \
343 else if (pszTmp) \
344 RTTestIFailed("#%u: %s returns '%s', expected NULL", i, #a_Call, pszTmp); \
345 RTStrFree(pszTmp); \
346 } while (0)
347 CHECK_STR_API(RTUriParsedScheme(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszScheme);
348 CHECK_STR_API(RTUriParsedAuthority(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszAuthority);
349 CHECK_STR_API(RTUriParsedAuthorityUsername(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszUsername);
350 CHECK_STR_API(RTUriParsedAuthorityPassword(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszPassword);
351 CHECK_STR_API(RTUriParsedAuthorityHost(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszHost);
352 CHECK_STR_API(RTUriParsedPath(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszPath);
353 CHECK_STR_API(RTUriParsedQuery(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszQuery);
354 CHECK_STR_API(RTUriParsedFragment(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszFragment);
355 uint32_t uPort = RTUriParsedAuthorityPort(g_aTests[i].pszUri, &Parsed);
356 if (uPort != g_aTests[i].uPort)
357 RTTestIFailed("#%u: RTUriParsedAuthorityPort returns %#x, expected %#x", i, uPort, g_aTests[i].uPort);
358 }
359 }
360
361 /* Creation */
362 RTTestISub("RTUriCreate");
363 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
364 tstCreate(i, g_aTests[i].pszScheme, g_aTests[i].pszAuthority, g_aTests[i].pszPath,
365 g_aTests[i].pszQuery, g_aTests[i].pszFragment, g_aTests[i].pszUri);
366
367 /* File Uri path */
368 RTTestISub("RTUriFilePath");
369 for (size_t i = 0; i < RT_ELEMENTS(g_apCreateFileURIs); ++i)
370 tstFilePath(i, g_apCreateFileURIs[i].pcszUri, g_apCreateFileURIs[i].pcszPath, g_apCreateFileURIs[i].uFormat);
371
372 /* File Uri creation */
373 RTTestISub("RTUriFileCreate");
374 for (size_t i = 0; i < 3; ++i)
375 tstFileCreate(i, g_apCreateFileURIs[i].pcszPath, g_apCreateFileURIs[i].pcszUri);
376
377 return RTTestSummaryAndDestroy(hTest);
378}
379
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette