xref: /aosp_15_r20/external/sandboxed-api/contrib/uriparser/test/test_uriparser.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <fstream>
16 
17 #include "contrib/uriparser/sandboxed.h"
18 #include "contrib/uriparser/utils/utils_uriparser.h"
19 #include "sandboxed_api/util/path.h"
20 #include "sandboxed_api/util/status_matchers.h"
21 #include "sandboxed_api/util/temp_file.h"
22 
23 namespace {
24 
25 using ::sapi::IsOk;
26 
27 const struct TestVariant {
28   std::string test;
29   std::string uri;
30   std::string uriescaped;
31   std::string scheme;
32   std::string userinfo;
33   std::string hosttext;
34   std::string hostip;
35   std::string porttext;
36   std::string query;
37   std::string fragment;
38   std::string normalized;
39   std::string add_base_example;
40   std::string remove_base_example;
41   std::vector<std::string> path_elements;
42   std::map<std::string, std::string> query_elements;
43 } TestData[] = {
44     {
45         .test = "http://www.example.com/",
46         .uri = "http://www.example.com/",
47         .uriescaped = "http%3A%2F%2Fwww.example.com%2F",
48         .scheme = "http",
49         .userinfo = "",
50         .hosttext = "www.example.com",
51         .hostip = "",
52         .porttext = "",
53         .query = "",
54         .fragment = "",
55         .normalized = "http://www.example.com/",
56         .add_base_example = "http://www.example.com/",
57         .remove_base_example = "./",
58     },
59     {
60         .test = "https://github.com/google/sandboxed-api/",
61         .uri = "https://github.com/google/sandboxed-api/",
62         .uriescaped = "https%3A%2F%2Fgithub.com%2Fgoogle%2Fsandboxed-api%2F",
63         .scheme = "https",
64         .userinfo = "",
65         .hosttext = "github.com",
66         .hostip = "",
67         .porttext = "",
68         .query = "",
69         .fragment = "",
70         .normalized = "https://github.com/google/sandboxed-api/",
71         .add_base_example = "https://github.com/google/sandboxed-api/",
72         .remove_base_example = "https://github.com/google/sandboxed-api/",
73         .path_elements = {"google", "sandboxed-api"},
74     },
75     {
76         .test = "mailto:[email protected]",
77         .uri = "mailto:[email protected]",
78         .uriescaped = "mailto%3Atest%40example.com",
79         .scheme = "mailto",
80         .userinfo = "",
81         .hosttext = "",
82         .hostip = "",
83         .porttext = "",
84         .query = "",
85         .fragment = "",
86         .normalized = "mailto:[email protected]",
87         .add_base_example = "mailto:[email protected]",
88         .remove_base_example = "mailto:[email protected]",
89         .path_elements = {"[email protected]"},
90     },
91     {
92         .test = "file:///bin/bash",
93         .uri = "file:///bin/bash",
94         .uriescaped = "file%3A%2F%2F%2Fbin%2Fbash",
95         .scheme = "file",
96         .userinfo = "",
97         .hosttext = "",
98         .hostip = "",
99         .porttext = "",
100         .query = "",
101         .fragment = "",
102         .normalized = "file:///bin/bash",
103         .add_base_example = "file:///bin/bash",
104         .remove_base_example = "file:///bin/bash",
105         .path_elements =
106             {
107                 "bin",
108                 "bash",
109             },
110     },
111     {
112         .test = "http://www.example.com/name%20with%20spaces/",
113         .uri = "http://www.example.com/name%20with%20spaces/",
114         .uriescaped =
115             "http%3A%2F%2Fwww.example.com%2Fname%2520with%2520spaces%2F",
116         .scheme = "http",
117         .userinfo = "",
118         .hosttext = "www.example.com",
119         .hostip = "",
120         .porttext = "",
121         .query = "",
122         .fragment = "",
123         .normalized = "http://www.example.com/name%20with%20spaces/",
124         .add_base_example = "http://www.example.com/name%20with%20spaces/",
125         .remove_base_example = "name%20with%20spaces/",
126         .path_elements =
127             {
128                 "name%20with%20spaces",
129             },
130     },
131     {
132         .test = "http://abcdefg@localhost/",
133         .uri = "http://abcdefg@localhost/",
134         .uriescaped = "http%3A%2F%2Fabcdefg%40localhost%2F",
135         .scheme = "http",
136         .userinfo = "abcdefg",
137         .hosttext = "localhost",
138         .hostip = "",
139         .porttext = "",
140         .query = "",
141         .fragment = "",
142         .normalized = "http://abcdefg@localhost/",
143         .add_base_example = "http://abcdefg@localhost/",
144         .remove_base_example = "//abcdefg@localhost/",
145     },
146     {
147         .test = "https://localhost:123/",
148         .uri = "https://localhost:123/",
149         .uriescaped = "https%3A%2F%2Flocalhost%3A123%2F",
150         .scheme = "https",
151         .userinfo = "",
152         .hosttext = "localhost",
153         .hostip = "",
154         .porttext = "123",
155         .query = "",
156         .fragment = "",
157         .normalized = "https://localhost:123/",
158         .add_base_example = "https://localhost:123/",
159         .remove_base_example = "https://localhost:123/",
160     },
161     {
162         .test = "http://[::1]/",
163         .uri = "http://[0000:0000:0000:0000:0000:0000:0000:0001]/",
164         .uriescaped = "http%3A%2F%2F%5B0000%3A0000%3A0000%3A0000%3A0000%3A0000%"
165                       "3A0000%3A0001%5D%2F",
166         .scheme = "http",
167         .userinfo = "",
168         .hosttext = "::1",
169         .hostip = "::1",
170         .porttext = "",
171         .query = "",
172         .fragment = "",
173         .normalized = "http://[0000:0000:0000:0000:0000:0000:0000:0001]/",
174         .add_base_example = "http://[0000:0000:0000:0000:0000:0000:0000:0001]/",
175         .remove_base_example = "//[0000:0000:0000:0000:0000:0000:0000:0001]/",
176     },
177     {
178         .test = "http://a/b/c/d;p?q",
179         .uri = "http://a/b/c/d;p?q",
180         .uriescaped = "http%3A%2F%2Fa%2Fb%2Fc%2Fd%3Bp%3Fq",
181         .scheme = "http",
182         .userinfo = "",
183         .hosttext = "a",
184         .hostip = "",
185         .porttext = "",
186         .query = "q",
187         .fragment = "",
188         .normalized = "http://a/b/c/d;p?q",
189         .add_base_example = "http://a/b/c/d;p?q",
190         .remove_base_example = "//a/b/c/d;p?q",
191         .path_elements = {"b", "c", "d;p"},
192         .query_elements = {{"q", ""}},
193     },
194     {.test = "http://a/b/c/../d;p?q",
195      .uri = "http://a/b/c/../d;p?q",
196      .uriescaped = "http%3A%2F%2Fa%2Fb%2Fc%2F..%2Fd%3Bp%3Fq",
197      .scheme = "http",
198      .userinfo = "",
199      .hosttext = "a",
200      .hostip = "",
201      .porttext = "",
202      .query = "q",
203      .fragment = "",
204      .normalized = "http://a/b/d;p?q",
205      .add_base_example = "http://a/b/d;p?q",
206      .remove_base_example = "//a/b/c/../d;p?q",
207      .path_elements = {"b", "c", "..", "d;p"},
208      .query_elements = {{"q", ""}}},
209     {
210         .test = "http://example.com/abc/def/",
211         .uri = "http://example.com/abc/def/",
212         .uriescaped = "http%3A%2F%2Fexample.com%2Fabc%2Fdef%2F",
213         .scheme = "http",
214         .userinfo = "",
215         .hosttext = "example.com",
216         .hostip = "",
217         .porttext = "",
218         .query = "",
219         .fragment = "",
220         .normalized = "http://example.com/abc/def/",
221         .add_base_example = "http://example.com/abc/def/",
222         .remove_base_example = "//example.com/abc/def/",
223         .path_elements =
224             {
225                 "abc",
226                 "def",
227             },
228     },
229     {.test = "http://example.com/?abc",
230      .uri = "http://example.com/?abc",
231      .uriescaped = "http%3A%2F%2Fexample.com%2F%3Fabc",
232      .scheme = "http",
233      .userinfo = "",
234      .hosttext = "example.com",
235      .hostip = "",
236      .porttext = "",
237      .query = "abc",
238      .fragment = "",
239      .normalized = "http://example.com/?abc",
240      .add_base_example = "http://example.com/?abc",
241      .remove_base_example = "//example.com/?abc",
242      .query_elements = {{"abc", ""}}},
243     {
244         .test = "http://[vA.123456]/",
245         .uri = "http://[vA.123456]/",
246         .uriescaped = "http%3A%2F%2F%5BvA.123456%5D%2F",
247         .scheme = "http",
248         .userinfo = "",
249         .hosttext = "vA.123456",
250         .hostip = "",
251         .porttext = "",
252         .query = "",
253         .fragment = "",
254         .normalized = "http://[va.123456]/",
255         .add_base_example = "http://[vA.123456]/",
256         .remove_base_example = "//[vA.123456]/",
257     },
258     {
259         .test = "http://8.8.8.8/",
260         .uri = "http://8.8.8.8/",
261         .uriescaped = "http%3A%2F%2F8.8.8.8%2F",
262         .scheme = "http",
263         .userinfo = "",
264         .hosttext = "8.8.8.8",
265         .hostip = "8.8.8.8",
266         .porttext = "",
267         .query = "",
268         .fragment = "",
269         .normalized = "http://8.8.8.8/",
270         .add_base_example = "http://8.8.8.8/",
271         .remove_base_example = "//8.8.8.8/",
272     },
273     {.test = "http://www.example.com/?abc",
274      .uri = "http://www.example.com/?abc",
275      .uriescaped = "http%3A%2F%2Fwww.example.com%2F%3Fabc",
276      .scheme = "http",
277      .userinfo = "",
278      .hosttext = "www.example.com",
279      .hostip = "",
280      .porttext = "",
281      .query = "abc",
282      .fragment = "",
283      .normalized = "http://www.example.com/?abc",
284      .add_base_example = "http://www.example.com/?abc",
285      .remove_base_example = "./?abc",
286      .query_elements = {{"abc", ""}}},
287     {.test = "https://google.com?q=asd&x=y&zxc=asd",
288      .uri = "https://google.com?q=asd&x=y&zxc=asd",
289      .uriescaped = "https%3A%2F%2Fgoogle.com%3Fq%3Dasd%26x%3Dy%26zxc%3Dasd",
290      .scheme = "https",
291      .userinfo = "",
292      .hosttext = "google.com",
293      .hostip = "",
294      .porttext = "",
295      .query = "q=asd&x=y&zxc=asd",
296      .fragment = "",
297      .normalized = "https://google.com?q=asd&x=y&zxc=asd",
298      .add_base_example = "https://google.com?q=asd&x=y&zxc=asd",
299      .remove_base_example = "https://google.com?q=asd&x=y&zxc=asd",
300      .query_elements = {{"q", "asd"}, {"x", "y"}, {"zxc", "asd"}}},
301     {.test = "https://google.com?q=asd#newplace",
302      .uri = "https://google.com?q=asd#newplace",
303      .uriescaped = "https%3A%2F%2Fgoogle.com%3Fq%3Dasd%23newplace",
304      .scheme = "https",
305      .userinfo = "",
306      .hosttext = "google.com",
307      .hostip = "",
308      .porttext = "",
309      .query = "q=asd",
310      .fragment = "newplace",
311      .normalized = "https://google.com?q=asd#newplace",
312      .add_base_example = "https://google.com?q=asd#newplace",
313      .remove_base_example = "https://google.com?q=asd#newplace",
314      .query_elements = {{"q", "asd"}}},
315 };
316 
317 class UriParserBase : public testing::Test {
318  protected:
319   void SetUp() override;
320   std::unique_ptr<UriparserSapiSandbox> sandbox_;
321 };
322 
323 class UriParserTestData : public UriParserBase,
324                           public testing::WithParamInterface<TestVariant> {};
325 
SetUp()326 void UriParserBase::SetUp() {
327   sandbox_ = std::make_unique<UriparserSapiSandbox>();
328   ASSERT_THAT(sandbox_->Init(), IsOk());
329 }
330 
TEST_P(UriParserTestData,TestUri)331 TEST_P(UriParserTestData, TestUri) {
332   const TestVariant& tv = GetParam();
333 
334   UriParser uri(sandbox_.get(), tv.test);
335   ASSERT_THAT(uri.GetStatus(), IsOk());
336 
337   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetUri());
338   ASSERT_EQ(ret, tv.uri);
339 }
340 
TEST_P(UriParserTestData,TestUriEscaped)341 TEST_P(UriParserTestData, TestUriEscaped) {
342   const TestVariant& tv = GetParam();
343 
344   UriParser uri(sandbox_.get(), tv.test);
345   ASSERT_THAT(uri.GetStatus(), IsOk());
346 
347   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetUriEscaped(true, true));
348   ASSERT_EQ(ret, tv.uriescaped);
349 }
350 
TEST_P(UriParserTestData,TestScheme)351 TEST_P(UriParserTestData, TestScheme) {
352   const TestVariant& tv = GetParam();
353 
354   UriParser uri(sandbox_.get(), tv.test);
355   ASSERT_THAT(uri.GetStatus(), IsOk());
356 
357   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetScheme());
358   ASSERT_EQ(ret, tv.scheme);
359 }
360 
TEST_P(UriParserTestData,TestUserInfo)361 TEST_P(UriParserTestData, TestUserInfo) {
362   const TestVariant& tv = GetParam();
363 
364   UriParser uri(sandbox_.get(), tv.test);
365   ASSERT_THAT(uri.GetStatus(), IsOk());
366 
367   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetUserInfo());
368   ASSERT_EQ(ret, tv.userinfo);
369 }
370 
TEST_P(UriParserTestData,TestHostText)371 TEST_P(UriParserTestData, TestHostText) {
372   const TestVariant& tv = GetParam();
373 
374   UriParser uri(sandbox_.get(), tv.test);
375   ASSERT_THAT(uri.GetStatus(), IsOk());
376 
377   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetHostText());
378   ASSERT_EQ(ret, tv.hosttext);
379 }
380 
TEST_P(UriParserTestData,TestHostIP)381 TEST_P(UriParserTestData, TestHostIP) {
382   const TestVariant& tv = GetParam();
383 
384   UriParser uri(sandbox_.get(), tv.test);
385   ASSERT_THAT(uri.GetStatus(), IsOk());
386 
387   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetHostIP());
388   ASSERT_EQ(ret, tv.hostip);
389 }
390 
TEST_P(UriParserTestData,TestPortText)391 TEST_P(UriParserTestData, TestPortText) {
392   const TestVariant& tv = GetParam();
393 
394   UriParser uri(sandbox_.get(), tv.test);
395   ASSERT_THAT(uri.GetStatus(), IsOk());
396 
397   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetPortText());
398   ASSERT_EQ(ret, tv.porttext);
399 }
400 
TEST_P(UriParserTestData,TestQuery)401 TEST_P(UriParserTestData, TestQuery) {
402   const TestVariant& tv = GetParam();
403 
404   UriParser uri(sandbox_.get(), tv.test);
405   ASSERT_THAT(uri.GetStatus(), IsOk());
406 
407   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetQuery());
408   ASSERT_EQ(ret, tv.query);
409 }
410 
TEST_P(UriParserTestData,TestFragment)411 TEST_P(UriParserTestData, TestFragment) {
412   const TestVariant& tv = GetParam();
413 
414   UriParser uri(sandbox_.get(), tv.test);
415   ASSERT_THAT(uri.GetStatus(), IsOk());
416 
417   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetFragment());
418   ASSERT_EQ(ret, tv.fragment);
419 }
420 
TEST_P(UriParserTestData,TestNormalize)421 TEST_P(UriParserTestData, TestNormalize) {
422   const TestVariant& tv = GetParam();
423 
424   UriParser uri(sandbox_.get(), tv.test);
425   ASSERT_THAT(uri.GetStatus(), IsOk());
426 
427   ASSERT_THAT(uri.NormalizeSyntax(), IsOk());
428   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret, uri.GetUri());
429   ASSERT_EQ(ret, tv.normalized);
430 }
431 
TEST_P(UriParserTestData,TestMultiple)432 TEST_P(UriParserTestData, TestMultiple) {
433   const TestVariant& tv = GetParam();
434 
435   UriParser uri(sandbox_.get(), tv.test);
436   ASSERT_THAT(uri.GetStatus(), IsOk());
437 
438   std::string ret;
439   SAPI_ASSERT_OK_AND_ASSIGN(ret, uri.GetQuery());
440   ASSERT_EQ(ret, tv.query);
441 
442   SAPI_ASSERT_OK_AND_ASSIGN(ret, uri.GetHostIP());
443   ASSERT_EQ(ret, tv.hostip);
444 
445   ASSERT_THAT(uri.NormalizeSyntax(), IsOk());
446   SAPI_ASSERT_OK_AND_ASSIGN(ret, uri.GetUri());
447   ASSERT_EQ(ret, tv.normalized);
448 }
449 
TEST_P(UriParserTestData,TestAddBaseExample)450 TEST_P(UriParserTestData, TestAddBaseExample) {
451   const TestVariant& tv = GetParam();
452 
453   UriParser uri(sandbox_.get(), tv.test);
454   ASSERT_THAT(uri.GetStatus(), IsOk());
455 
456   SAPI_ASSERT_OK_AND_ASSIGN(std::string ret,
457                             uri.GetUriWithBase("http://www.example.com"));
458   ASSERT_EQ(ret, tv.add_base_example);
459 }
460 
TEST_P(UriParserTestData,TestRemoveBaseExample)461 TEST_P(UriParserTestData, TestRemoveBaseExample) {
462   const TestVariant& tv = GetParam();
463 
464   UriParser uri(sandbox_.get(), tv.test);
465   ASSERT_THAT(uri.GetStatus(), IsOk());
466 
467   SAPI_ASSERT_OK_AND_ASSIGN(
468       std::string ret, uri.GetUriWithoutBase("http://www.example.com", false));
469   ASSERT_EQ(ret, tv.remove_base_example);
470 }
471 
TEST_P(UriParserTestData,TestPath)472 TEST_P(UriParserTestData, TestPath) {
473   const TestVariant& tv = GetParam();
474 
475   UriParser uri(sandbox_.get(), tv.test);
476   ASSERT_THAT(uri.GetStatus(), IsOk());
477 
478   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<std::string> ret, uri.GetPath());
479   ASSERT_EQ(ret.size(), tv.path_elements.size());
480   for (int i = 0; i < ret.size(); ++i) {
481     ASSERT_EQ(ret[i], tv.path_elements[i]);
482   }
483 }
484 
TEST_P(UriParserTestData,TestQueryElements)485 TEST_P(UriParserTestData, TestQueryElements) {
486   const TestVariant& tv = GetParam();
487 
488   UriParser uri(sandbox_.get(), tv.test);
489   ASSERT_THAT(uri.GetStatus(), IsOk());
490 
491   SAPI_ASSERT_OK_AND_ASSIGN(auto ret, uri.GetQueryElements());
492   ASSERT_EQ(ret.size(), tv.query_elements.size());
493   for (auto orig : tv.query_elements) {
494     ASSERT_NE(ret.find(orig.first), ret.end());
495     ASSERT_EQ(ret[orig.first], orig.second);
496   }
497 }
498 
499 INSTANTIATE_TEST_SUITE_P(UriParserBase, UriParserTestData,
500                          testing::ValuesIn(TestData));
501 
502 }  // namespace
503