summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhsoting.net>2014-08-06 18:24:22 +0200
committerJörg Frings-Fürst <debian@jff-webhsoting.net>2014-08-06 18:24:22 +0200
commit886e5076c8e81fd0cdfe82dbf4a80d19e778d594 (patch)
tree5c837ed148fbb2bd73dd310fcea07daeddc095d6 /test
Imported Upstream version 0.8.0.1upstream/0.8.0.1
Diffstat (limited to 'test')
-rw-r--r--test/FourSuite.cpp623
-rw-r--r--test/FourSuite.h70
-rw-r--r--test/test.cpp1751
3 files changed, 2444 insertions, 0 deletions
diff --git a/test/FourSuite.cpp b/test/FourSuite.cpp
new file mode 100644
index 0000000..706ee56
--- /dev/null
+++ b/test/FourSuite.cpp
@@ -0,0 +1,623 @@
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "FourSuite.h"
+
+#include <uriparser/Uri.h>
+
+
+
+// All testcases in this file are coming from
+// http://cvs.4suite.org/viewcvs/4Suite/test/Lib/test_uri.py
+
+
+
+bool FourSuite::testAddOrRemoveBaseHelper(const char * ref, const char * base,
+ const char * expected, bool add, bool domainRootMode) {
+ UriParserStateA stateA;
+
+ // Base
+ UriUriA baseUri;
+ stateA.uri = &baseUri;
+ int res = uriParseUriA(&stateA, base);
+ if (res != 0) {
+ return false;
+ }
+
+ // Rel
+ UriUriA relUri;
+ stateA.uri = &relUri;
+ res = uriParseUriA(&stateA, ref);
+ if (res != 0) {
+ uriFreeUriMembersA(&baseUri);
+ return false;
+ }
+
+ // Expected result
+ UriUriA expectedUri;
+ stateA.uri = &expectedUri;
+ res = uriParseUriA(&stateA, expected);
+ if (res != 0) {
+ uriFreeUriMembersA(&baseUri);
+ uriFreeUriMembersA(&relUri);
+ uriFreeUriMembersA(&expectedUri);
+ return false;
+ }
+
+ // Transform
+ UriUriA transformedUri;
+ if (add) {
+ res = uriAddBaseUriA(&transformedUri, &relUri, &baseUri);
+ } else {
+ res = uriRemoveBaseUriA(&transformedUri, &relUri, &baseUri,
+ domainRootMode ? URI_TRUE : URI_FALSE);
+ }
+ if (res != 0) {
+ uriFreeUriMembersA(&baseUri);
+ uriFreeUriMembersA(&relUri);
+ uriFreeUriMembersA(&expectedUri);
+ uriFreeUriMembersA(&transformedUri);
+ return false;
+ }
+
+ const bool equal = (URI_TRUE == uriEqualsUriA(&transformedUri, &expectedUri));
+ if (!equal) {
+ char transformedUriText[1024 * 8];
+ char expectedUriText[1024 * 8];
+ uriToStringA(transformedUriText, &transformedUri, 1024 * 8, NULL);
+ uriToStringA(expectedUriText, &expectedUri, 1024 * 8, NULL);
+ printf("\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", expectedUriText, transformedUriText);
+ }
+
+ uriFreeUriMembersA(&baseUri);
+ uriFreeUriMembersA(&relUri);
+ uriFreeUriMembersA(&expectedUri);
+ uriFreeUriMembersA(&transformedUri);
+ return equal;
+}
+
+
+
+void FourSuite::absolutize_test_cases() {
+ const char * const BASE_URI[] = {
+ "http://a/b/c/d;p?q",
+ "http://a/b/c/d;p?q=1/2",
+ "http://a/b/c/d;p=1/2?q",
+ "fred:///s//a/b/c",
+ "http:///s//a/b/c"};
+
+ // ref, base, exptected
+
+ // http://lists.w3.org/Archives/Public/uri/2004Feb/0114.html
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../c", "foo:a/b", "foo:c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("foo:.", "foo:a", "foo:"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/foo/../../../bar", "zz:abc", "zz:/bar"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/foo/../bar", "zz:abc", "zz:/bar"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("foo/../../../bar", "zz:abc", "zz:bar"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("foo/../bar", "zz:abc", "zz:bar"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("zz:.", "zz:abc", "zz:"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/.", BASE_URI[0], "http://a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/.foo", BASE_URI[0], "http://a/.foo"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(".foo", BASE_URI[0], "http://a/b/c/.foo"));
+
+ // http://gbiv.com/protocols/uri/test/rel_examples1.html
+ // examples from RFC 2396
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g:h", BASE_URI[0], "g:h"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g", BASE_URI[0], "http://a/b/c/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g", BASE_URI[0], "http://a/b/c/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/", BASE_URI[0], "http://a/b/c/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/g", BASE_URI[0], "http://a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g", BASE_URI[0], "http://g"));
+
+ // changed with RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("?y", BASE_URI[0], "http://a/b/c/d;p?y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y", BASE_URI[0], "http://a/b/c/g?y"));
+
+ // changed with RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("#s", BASE_URI[0], "http://a/b/c/d;p?q#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s", BASE_URI[0], "http://a/b/c/g#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y#s", BASE_URI[0], "http://a/b/c/g?y#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(";x", BASE_URI[0], "http://a/b/c/;x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x", BASE_URI[0], "http://a/b/c/g;x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x?y#s", BASE_URI[0], "http://a/b/c/g;x?y#s"));
+
+ // changed with RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", BASE_URI[0], "http://a/b/c/d;p?q"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(".", BASE_URI[0], "http://a/b/c/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", BASE_URI[0], "http://a/b/c/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("..", BASE_URI[0], "http://a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../", BASE_URI[0], "http://a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../g", BASE_URI[0], "http://a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../..", BASE_URI[0], "http://a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../", BASE_URI[0], "http://a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../g", BASE_URI[0], "http://a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../g", BASE_URI[0], "http://a/g")); // http://a/../g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[0], "http://a/g")); // http://a/../../g
+
+ // changed with RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/./g", BASE_URI[0], "http://a/g"));
+
+ // changed with RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/../g", BASE_URI[0], "http://a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g.", BASE_URI[0], "http://a/b/c/g."));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(".g", BASE_URI[0], "http://a/b/c/.g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g..", BASE_URI[0], "http://a/b/c/g.."));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("..g", BASE_URI[0], "http://a/b/c/..g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./../g", BASE_URI[0], "http://a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g/.", BASE_URI[0], "http://a/b/c/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/./h", BASE_URI[0], "http://a/b/c/g/h"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/../h", BASE_URI[0], "http://a/b/c/h"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x=1/./y", BASE_URI[0], "http://a/b/c/g;x=1/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x=1/../y", BASE_URI[0], "http://a/b/c/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y/./x", BASE_URI[0], "http://a/b/c/g?y/./x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y/../x", BASE_URI[0], "http://a/b/c/g?y/../x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s/./x", BASE_URI[0], "http://a/b/c/g#s/./x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s/../x", BASE_URI[0], "http://a/b/c/g#s/../x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http:g", BASE_URI[0], "http:g")); // http://a/b/c/g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http:", BASE_URI[0], "http:")); // BASE_URI[0]
+
+ // not sure where this one originated
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/a/b/c/./../../g", BASE_URI[0], "http://a/a/g"));
+
+ // http://gbiv.com/protocols/uri/test/rel_examples2.html
+ // slashes in base URI's query args
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g", BASE_URI[1], "http://a/b/c/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g", BASE_URI[1], "http://a/b/c/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/", BASE_URI[1], "http://a/b/c/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/g", BASE_URI[1], "http://a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g", BASE_URI[1], "http://g"));
+
+ // changed in RFC 2396bis
+ // TEST_ASSERT(testAddOrRemoveBaseHelper("?y", BASE_URI[1], "http://a/b/c/?y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("?y", BASE_URI[1], "http://a/b/c/d;p?y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y", BASE_URI[1], "http://a/b/c/g?y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y/./x", BASE_URI[1], "http://a/b/c/g?y/./x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y/../x", BASE_URI[1], "http://a/b/c/g?y/../x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s", BASE_URI[1], "http://a/b/c/g#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s/./x", BASE_URI[1], "http://a/b/c/g#s/./x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g#s/../x", BASE_URI[1], "http://a/b/c/g#s/../x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", BASE_URI[1], "http://a/b/c/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../", BASE_URI[1], "http://a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../g", BASE_URI[1], "http://a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../", BASE_URI[1], "http://a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../g", BASE_URI[1], "http://a/g"));
+
+ // http://gbiv.com/protocols/uri/test/rel_examples3.html
+ // slashes in path params
+ // all of these changed in RFC 2396bis
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g", BASE_URI[2], "http://a/b/c/d;p=1/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g", BASE_URI[2], "http://a/b/c/d;p=1/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/", BASE_URI[2], "http://a/b/c/d;p=1/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g?y", BASE_URI[2], "http://a/b/c/d;p=1/g?y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(";x", BASE_URI[2], "http://a/b/c/d;p=1/;x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x", BASE_URI[2], "http://a/b/c/d;p=1/g;x"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x=1/./y", BASE_URI[2], "http://a/b/c/d;p=1/g;x=1/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g;x=1/../y", BASE_URI[2], "http://a/b/c/d;p=1/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", BASE_URI[2], "http://a/b/c/d;p=1/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../", BASE_URI[2], "http://a/b/c/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../g", BASE_URI[2], "http://a/b/c/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../", BASE_URI[2], "http://a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../g", BASE_URI[2], "http://a/b/g"));
+
+ // http://gbiv.com/protocols/uri/test/rel_examples4.html
+ // double and triple slash, unknown scheme
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g:h", BASE_URI[3], "g:h"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g", BASE_URI[3], "fred:///s//a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g", BASE_URI[3], "fred:///s//a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/", BASE_URI[3], "fred:///s//a/b/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/g", BASE_URI[3], "fred:///g")); // may change to fred:///s//a/g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g", BASE_URI[3], "fred://g")); // may change to fred:///s//g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g/x", BASE_URI[3], "fred://g/x")); // may change to fred:///s//g/x
+ TEST_ASSERT(testAddOrRemoveBaseHelper("///g", BASE_URI[3], "fred:///g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", BASE_URI[3], "fred:///s//a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../", BASE_URI[3], "fred:///s//a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../g", BASE_URI[3], "fred:///s//a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../", BASE_URI[3], "fred:///s//")); // may change to fred:///s//a/../
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../g", BASE_URI[3], "fred:///s//g")); // may change to fred:///s//a/../g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../g", BASE_URI[3], "fred:///s/g")); // may change to fred:///s//a/../../g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[3], "fred:///g")); // may change to fred:///s//a/../../../g
+
+ // http://gbiv.com/protocols/uri/test/rel_examples5.html
+ // double and triple slash, well-known scheme
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g:h", BASE_URI[4], "g:h"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g", BASE_URI[4], "http:///s//a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./g", BASE_URI[4], "http:///s//a/b/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("g/", BASE_URI[4], "http:///s//a/b/g/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/g", BASE_URI[4], "http:///g")); // may change to http:///s//a/g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g", BASE_URI[4], "http://g")); // may change to http:///s//g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("//g/x", BASE_URI[4], "http://g/x")); // may change to http:///s//g/x
+ TEST_ASSERT(testAddOrRemoveBaseHelper("///g", BASE_URI[4], "http:///g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", BASE_URI[4], "http:///s//a/b/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../", BASE_URI[4], "http:///s//a/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../g", BASE_URI[4], "http:///s//a/g"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../", BASE_URI[4], "http:///s//")); // may change to http:///s//a/../
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../g", BASE_URI[4], "http:///s//g")); // may change to http:///s//a/../g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../g", BASE_URI[4], "http:///s/g")); // may change to http:///s//a/../../g
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[4], "http:///g")); // may change to http:///s//a/../../../g
+
+ // from Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py
+ TEST_ASSERT(testAddOrRemoveBaseHelper("bar:abc", "foo:xyz", "bar:abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../abc", "http://example/x/y/z", "http://example/x/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http://example/x/abc", "http://example2/x/y/z", "http://example/x/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../r", "http://ex/x/y/z", "http://ex/x/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r", "http://ex/x/y", "http://ex/x/q/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r#s", "http://ex/x/y", "http://ex/x/q/r#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r#s/t", "http://ex/x/y", "http://ex/x/q/r#s/t"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("ftp://ex/x/q/r", "http://ex/x/y", "ftp://ex/x/q/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "http://ex/x/y", "http://ex/x/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "http://ex/x/y/", "http://ex/x/y/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "http://ex/x/y/pdq", "http://ex/x/y/pdq"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("z/", "http://ex/x/y/", "http://ex/x/y/z/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("#Animal", "file:/swap/test/animal.rdf", "file:/swap/test/animal.rdf#Animal"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../abc", "file:/e/x/y/z", "file:/e/x/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/example/x/abc", "file:/example2/x/y/z", "file:/example/x/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../r", "file:/ex/x/y/z", "file:/ex/x/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/r", "file:/ex/x/y/z", "file:/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r", "file:/ex/x/y", "file:/ex/x/q/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r#s", "file:/ex/x/y", "file:/ex/x/q/r#s"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r#", "file:/ex/x/y", "file:/ex/x/q/r#"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q/r#s/t", "file:/ex/x/y", "file:/ex/x/q/r#s/t"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("ftp://ex/x/q/r", "file:/ex/x/y", "ftp://ex/x/q/r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "file:/ex/x/y", "file:/ex/x/y"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "file:/ex/x/y/", "file:/ex/x/y/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "file:/ex/x/y/pdq", "file:/ex/x/y/pdq"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("z/", "file:/ex/x/y/", "file:/ex/x/y/z/"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("file://meetings.example.com/cal#m1", "file:/devel/WWW/2000/10/swap/test/reluri-1.n3", "file://meetings.example.com/cal#m1"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("file://meetings.example.com/cal#m1", "file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3", "file://meetings.example.com/cal#m1"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./#blort", "file:/some/dir/foo", "file:/some/dir/#blort"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./#", "file:/some/dir/foo", "file:/some/dir/#"));
+
+ // Ryan Lee
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./", "http://example/x/abc.efg", "http://example/x/"));
+
+ // Graham Klyne's tests
+ // http://www.ninebynine.org/Software/HaskellUtils/Network/UriTest.xls
+ // 01-31 are from Connelly's cases
+
+ // 32-49
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./q:r", "http://ex/x/y", "http://ex/x/q:r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./p=q:r", "http://ex/x/y", "http://ex/x/p=q:r"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("?pp/rr", "http://ex/x/y?pp/qq", "http://ex/x/y?pp/rr"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("y/z", "http://ex/x/y?pp/qq", "http://ex/x/y/z"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("local/qual@domain.org#frag", "mailto:local", "mailto:local/qual@domain.org#frag"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("more/qual2@domain2.org#frag", "mailto:local/qual1@domain1.org", "mailto:local/more/qual2@domain2.org#frag"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("y?q", "http://ex/x/y?q", "http://ex/x/y?q"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/x/y?q", "http://ex?p", "http://ex/x/y?q"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("c/d", "foo:a/b", "foo:a/c/d"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/c/d", "foo:a/b", "foo:/c/d"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("", "foo:a/b?c#d", "foo:a/b?c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("b/c", "foo:a", "foo:b/c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../b/c", "foo:/a/y/z", "foo:/a/b/c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("./b/c", "foo:a", "foo:b/c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/./b/c", "foo:a", "foo:/b/c"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../d", "foo://a//b/c", "foo://a/d"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper(".", "foo:a", "foo:"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("..", "foo:a", "foo:"));
+
+ // 50-57 (cf. TimBL comments --
+ // http://lists.w3.org/Archives/Public/uri/2003Feb/0028.html,
+ // http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html)
+ TEST_ASSERT(testAddOrRemoveBaseHelper("abc", "http://example/x/y%2Fz", "http://example/x/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../../x%2Fabc", "http://example/a/x/y/z", "http://example/a/x%2Fabc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../x%2Fabc", "http://example/a/x/y%2Fz", "http://example/a/x%2Fabc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("abc", "http://example/x%2Fy/z", "http://example/x%2Fy/abc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("q%3Ar", "http://ex/x/y", "http://ex/x/q%3Ar"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y%2Fz", "http://example/x%2Fabc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y/z", "http://example/x%2Fabc"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y%2Fz", "http://example/x%2Fabc"));
+
+ // 70-77
+ TEST_ASSERT(testAddOrRemoveBaseHelper("local2@domain2", "mailto:local1@domain1?query1", "mailto:local2@domain2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("local2@domain2?query2", "mailto:local1@domain1", "mailto:local2@domain2?query2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("local2@domain2?query2", "mailto:local1@domain1?query1", "mailto:local2@domain2?query2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("?query2", "mailto:local@domain?query1", "mailto:local@domain?query2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("local@domain?query2", "mailto:?query1", "mailto:local@domain?query2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("?query2", "mailto:local@domain?query1", "mailto:local@domain?query2"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http://example/a/b?c/../d", "foo:bar", "http://example/a/b?c/../d"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http://example/a/b#c/../d", "foo:bar", "http://example/a/b#c/../d"));
+
+ // 82-88
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http:this", "http://example.org/base/uri", "http:this"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("http:this", "http:base", "http:this"));
+ // Whole in the URI spec, see http://lists.w3.org/Archives/Public/uri/2007Aug/0003.html
+ // TEST_ASSERT(testAddOrRemoveBaseHelper(".//g", "f:/a", "f://g")); // ORIGINAL
+ TEST_ASSERT(testAddOrRemoveBaseHelper(".//g", "f:/a", "f:/.//g")); // FIXED ONE
+ TEST_ASSERT(testAddOrRemoveBaseHelper("b/c//d/e", "f://example.org/base/a", "f://example.org/base/b/c//d/e"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("m2@example.ord/c2@example.org", "mid:m@example.ord/c@example.org", "mid:m@example.ord/m2@example.ord/c2@example.org"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("mini1.xml", "file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/", "file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml"));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("../b/c", "foo:a/y/z", "foo:a/b/c"));
+}
+
+
+
+void FourSuite::relativize_test_cases() {
+ const bool REMOVE_MODE = false;
+ const bool DOMAIN_ROOT_MODE = true;
+
+ // to convert, base, exptected
+
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/d", "b/c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/b/b/c", "s://ex/a/d", "/b/b/c", REMOVE_MODE, DOMAIN_ROOT_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/b/", "c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://other.ex/a/b/", "s://ex/a/d", "//other.ex/a/b/", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://other.ex/a/d", "//ex/a/b/c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("t://ex/a/b/c", "s://ex/a/d", "t://ex/a/b/c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "t://ex/a/d", "s://ex/a/b/c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a", "s://ex/b/c/d", "/a", REMOVE_MODE, DOMAIN_ROOT_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/b/c/d", "s://ex/a", "b/c/d", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c?h", "s://ex/a/d?w", "b/c?h", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c#h", "s://ex/a/d#w", "b/c#h", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c?h#i", "s://ex/a/d?w#j", "b/c?h#i", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a#i", "s://ex/a", "#i", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a?i", "s://ex/a", "?i", REMOVE_MODE));
+
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/", "s://ex/a/b/", "", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b", "s://ex/a/b", "", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/", "s://ex/", "", REMOVE_MODE));
+
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/d/c", "../b/c", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c/", "s://ex/a/d/c", "../b/c/", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c/d", "s://ex/a/d/c/d", "../../b/c/d", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/d/e/f", "/a/b/c", REMOVE_MODE, DOMAIN_ROOT_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b/", "s://ex/a/c/d/e", "../../b/", REMOVE_MODE));
+
+ // Some tests to ensure that empty path segments don't cause problems.
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/b", "s://ex/a//b/c", "../../b", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a///b", "s://ex/a/", ".///b", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a/", "s://ex/a///b", "../../", REMOVE_MODE));
+ TEST_ASSERT(testAddOrRemoveBaseHelper("s://ex/a//b/c", "s://ex/a/b", ".//b/c", REMOVE_MODE));
+}
+
+
+
+int FourSuite::testParseUri(const char * uriText, const char ** expectedErrorPos) {
+ UriParserStateA state;
+ UriUriA uri;
+ state.uri = &uri;
+ int res = uriParseUriA(&state, uriText);
+ if (expectedErrorPos != NULL) {
+ *expectedErrorPos = state.errorPos;
+ }
+ uriFreeUriMembersA(&uri);
+ return res;
+}
+
+
+
+bool FourSuite::testGoodUri(const char * uriText) {
+ return (testParseUri(uriText) == 0);
+}
+
+
+
+bool FourSuite::testBadUri(const char * uriText, int expectedErrorOffset) {
+ const char * errorPos = NULL;
+ const int ret = testParseUri(uriText, &errorPos);
+ return ((ret == URI_ERROR_SYNTAX)
+ && (errorPos != NULL)
+ && (
+ (expectedErrorOffset == -1)
+ || (errorPos == (uriText + expectedErrorOffset))
+ ));
+}
+
+
+
+void FourSuite::good_URI_references() {
+ TEST_ASSERT(testGoodUri("file:///foo/bar"));
+ TEST_ASSERT(testGoodUri("mailto:user@host?subject=blah"));
+ TEST_ASSERT(testGoodUri("dav:")); // empty opaque part / rel-path allowed by RFC 2396bis
+ TEST_ASSERT(testGoodUri("about:")); // empty opaque part / rel-path allowed by RFC 2396bis
+
+ // the following test cases are from a Perl script by David A. Wheeler
+ // at http://www.dwheeler.com/secure-programs/url.pl
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/"));
+ TEST_ASSERT(testGoodUri("http://1.2.3.4/"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/stuff"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/stuff/"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/hello%20world/"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?name=obi"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?name=obi+wan&status=jedi"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?onery"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com#bottom"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/yelp.html#bottom"));
+ TEST_ASSERT(testGoodUri("https://www.yahoo.com/"));
+ TEST_ASSERT(testGoodUri("ftp://www.yahoo.com/"));
+ TEST_ASSERT(testGoodUri("ftp://www.yahoo.com/hello"));
+ TEST_ASSERT(testGoodUri("demo.txt"));
+ TEST_ASSERT(testGoodUri("demo/hello.txt"));
+ TEST_ASSERT(testGoodUri("demo/hello.txt?query=hello#fragment"));
+ TEST_ASSERT(testGoodUri("/cgi-bin/query?query=hello#fragment"));
+ TEST_ASSERT(testGoodUri("/demo.txt"));
+ TEST_ASSERT(testGoodUri("/hello/demo.txt"));
+ TEST_ASSERT(testGoodUri("hello/demo.txt"));
+ TEST_ASSERT(testGoodUri("/"));
+ TEST_ASSERT(testGoodUri(""));
+ TEST_ASSERT(testGoodUri("#"));
+ TEST_ASSERT(testGoodUri("#here"));
+
+ // Wheeler's script says these are invalid, but they aren't
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?name=%00%01"));
+ TEST_ASSERT(testGoodUri("http://www.yaho%6f.com"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/hello%00world/"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/hello+world/"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?name=obi&"));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com?name=obi&type="));
+ TEST_ASSERT(testGoodUri("http://www.yahoo.com/yelp.html#"));
+ TEST_ASSERT(testGoodUri("//"));
+
+ // the following test cases are from a Haskell program by Graham Klyne
+ // at http://www.ninebynine.org/Software/HaskellUtils/Network/URITest.hs
+ TEST_ASSERT(testGoodUri("http://example.org/aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("mailto:local@domain.org"));
+ TEST_ASSERT(testGoodUri("mailto:local@domain.org#frag"));
+ TEST_ASSERT(testGoodUri("HTTP://EXAMPLE.ORG/AAA/BBB#CCC"));
+ TEST_ASSERT(testGoodUri("//example.org/aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("/aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("bbb#ccc"));
+ TEST_ASSERT(testGoodUri("#ccc"));
+ TEST_ASSERT(testGoodUri("#"));
+ TEST_ASSERT(testGoodUri("A'C"));
+
+ // escapes
+ TEST_ASSERT(testGoodUri("http://example.org/aaa%2fbbb#ccc"));
+ TEST_ASSERT(testGoodUri("http://example.org/aaa%2Fbbb#ccc"));
+ TEST_ASSERT(testGoodUri("%2F"));
+ TEST_ASSERT(testGoodUri("aaa%2Fbbb"));
+
+ // ports
+ TEST_ASSERT(testGoodUri("http://example.org:80/aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("http://example.org:/aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("http://example.org./aaa/bbb#ccc"));
+ TEST_ASSERT(testGoodUri("http://example.123./aaa/bbb#ccc"));
+
+ // bare authority
+ TEST_ASSERT(testGoodUri("http://example.org"));
+
+ // IPv6 literals (from RFC2732):
+ TEST_ASSERT(testGoodUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html"));
+ TEST_ASSERT(testGoodUri("http://[1080:0:0:0:8:800:200C:417A]/index.html"));
+ TEST_ASSERT(testGoodUri("http://[3ffe:2a00:100:7031::1]"));
+ TEST_ASSERT(testGoodUri("http://[1080::8:800:200C:417A]/foo"));
+ TEST_ASSERT(testGoodUri("http://[::192.9.5.5]/ipng"));
+ TEST_ASSERT(testGoodUri("http://[::FFFF:129.144.52.38]:80/index.html"));
+ TEST_ASSERT(testGoodUri("http://[2010:836B:4179::836B:4179]"));
+ TEST_ASSERT(testGoodUri("//[2010:836B:4179::836B:4179]"));
+
+ // Random other things that crop up
+ TEST_ASSERT(testGoodUri("http://example/Andr&#567;"));
+ TEST_ASSERT(testGoodUri("file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/"));
+}
+
+
+
+void FourSuite::bad_URI_references() {
+ TEST_ASSERT(testBadUri("beepbeep\x07\x07", 8));
+ TEST_ASSERT(testBadUri("\n", 0));
+ TEST_ASSERT(testBadUri("::", 0)); // not OK, per Roy Fielding on the W3C uri list on 2004-04-01
+
+ // the following test cases are from a Perl script by David A. Wheeler
+ // at http://www.dwheeler.com/secure-programs/url.pl
+ TEST_ASSERT(testBadUri("http://www yahoo.com", 10));
+ TEST_ASSERT(testBadUri("http://www.yahoo.com/hello world/", 26));
+ TEST_ASSERT(testBadUri("http://www.yahoo.com/yelp.html#\"", 31));
+
+ // the following test cases are from a Haskell program by Graham Klyne
+ // at http://www.ninebynine.org/Software/HaskellUtils/Network/URITest.hs
+ TEST_ASSERT(testBadUri("[2010:836B:4179::836B:4179]", 0));
+ TEST_ASSERT(testBadUri(" ", 0));
+ TEST_ASSERT(testBadUri("%", 1));
+ TEST_ASSERT(testBadUri("A%Z", 2));
+ TEST_ASSERT(testBadUri("%ZZ", 1));
+ TEST_ASSERT(testBadUri("%AZ", 2));
+ TEST_ASSERT(testBadUri("A C", 1));
+ TEST_ASSERT(testBadUri("A\\'C", 1)); // r"A\'C"
+ TEST_ASSERT(testBadUri("A`C", 1));
+ TEST_ASSERT(testBadUri("A<C", 1));
+ TEST_ASSERT(testBadUri("A>C", 1));
+ TEST_ASSERT(testBadUri("A^C", 1));
+ TEST_ASSERT(testBadUri("A\\\\C", 1)); // r'A\\C'
+ TEST_ASSERT(testBadUri("A{C", 1));
+ TEST_ASSERT(testBadUri("A|C", 1));
+ TEST_ASSERT(testBadUri("A}C", 1));
+ TEST_ASSERT(testBadUri("A[C", 1));
+ TEST_ASSERT(testBadUri("A]C", 1));
+ TEST_ASSERT(testBadUri("A[**]C", 1));
+ TEST_ASSERT(testBadUri("http://[xyz]/", 8));
+ TEST_ASSERT(testBadUri("http://]/", 7));
+ TEST_ASSERT(testBadUri("http://example.org/[2010:836B:4179::836B:4179]", 19));
+ TEST_ASSERT(testBadUri("http://example.org/abc#[2010:836B:4179::836B:4179]", 23));
+ TEST_ASSERT(testBadUri("http://example.org/xxx/[qwerty]#a[b]", 23));
+
+ // from a post to the W3C uri list on 2004-02-17
+ // breaks at 22 instead of 17 because everything up to that point is a valid userinfo
+ TEST_ASSERT(testBadUri("http://w3c.org:80path1/path2", 22));
+}
+
+
+
+bool FourSuite::normalizeAndCompare(const char * uriText,
+ const char * expectedNormalized) {
+ UriParserStateA stateA;
+ int res;
+
+ UriUriA testUri;
+ stateA.uri = &testUri;
+ res = uriParseUriA(&stateA, uriText);
+ if (res != 0) {
+ uriFreeUriMembersA(&testUri);
+ return false;
+ }
+
+ // Expected result
+ UriUriA expectedUri;
+ stateA.uri = &expectedUri;
+ res = uriParseUriA(&stateA, expectedNormalized);
+ if (res != 0) {
+ uriFreeUriMembersA(&testUri);
+ uriFreeUriMembersA(&expectedUri);
+ return false;
+ }
+
+ res = uriNormalizeSyntaxA(&testUri);
+ if (res != 0) {
+ uriFreeUriMembersA(&testUri);
+ uriFreeUriMembersA(&expectedUri);
+ return false;
+ }
+
+ const bool equalAfter = (URI_TRUE == uriEqualsUriA(&testUri, &expectedUri));
+ uriFreeUriMembersA(&testUri);
+ uriFreeUriMembersA(&expectedUri);
+ return equalAfter;
+}
+
+
+
+void FourSuite::caseNormalizationTests() {
+ TEST_ASSERT(normalizeAndCompare("HTTP://www.EXAMPLE.com/", "http://www.example.com/"));
+ TEST_ASSERT(normalizeAndCompare("example://A/b/c/%7bfoo%7d", "example://a/b/c/%7Bfoo%7D"));
+}
+
+
+
+void FourSuite::pctEncNormalizationTests() {
+ TEST_ASSERT(normalizeAndCompare("http://host/%7Euser/x/y/z", "http://host/~user/x/y/z"));
+ TEST_ASSERT(normalizeAndCompare("http://host/%7euser/x/y/z", "http://host/~user/x/y/z"));
+}
+
+
+
+void FourSuite::pathSegmentNormalizationTests() {
+ TEST_ASSERT(normalizeAndCompare("/a/b/../../c", "/c"));
+ // TEST_ASSERT(normalizeAndCompare("a/b/../../c", "a/b/../../c"));
+ // Fixed:
+ TEST_ASSERT(normalizeAndCompare("a/b/../../c", "c"));
+ TEST_ASSERT(normalizeAndCompare("/a/b/././c", "/a/b/c"));
+ // TEST_ASSERT(normalizeAndCompare("a/b/././c", "a/b/././c"));
+ // Fixed:
+ TEST_ASSERT(normalizeAndCompare("a/b/././c", "a/b/c"));
+ TEST_ASSERT(normalizeAndCompare("/a/b/../c/././d", "/a/c/d"));
+ // TEST_ASSERT(normalizeAndCompare("a/b/../c/././d", "a/b/../c/././d"));
+ // Fixed:
+ TEST_ASSERT(normalizeAndCompare("a/b/../c/././d", "a/c/d"));
+}
diff --git a/test/FourSuite.h b/test/FourSuite.h
new file mode 100644
index 0000000..24144cc
--- /dev/null
+++ b/test/FourSuite.h
@@ -0,0 +1,70 @@
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TEST_FOUR_SUITE_H
+#define TEST_FOUR_SUITE_H 1
+
+
+
+#include <cpptest.h>
+
+using namespace Test;
+
+
+
+class FourSuite : public Suite {
+
+public:
+ FourSuite() {
+ TEST_ADD(FourSuite::absolutize_test_cases)
+ TEST_ADD(FourSuite::relativize_test_cases)
+ TEST_ADD(FourSuite::good_URI_references)
+ TEST_ADD(FourSuite::bad_URI_references)
+ TEST_ADD(FourSuite::caseNormalizationTests)
+ TEST_ADD(FourSuite::pctEncNormalizationTests)
+ TEST_ADD(FourSuite::pathSegmentNormalizationTests)
+ }
+
+private:
+ bool testAddOrRemoveBaseHelper(const char * ref,
+ const char * base, const char * expected, bool add = true,
+ bool domainRootMode = false);
+
+ void absolutize_test_cases();
+ void relativize_test_cases();
+
+ int testParseUri(const char * uriText, const char ** expectedErrorPos = NULL);
+ bool testGoodUri(const char * uriText);
+ bool testBadUri(const char * uriText, int expectedErrorOffset = -1);
+ void good_URI_references();
+ void bad_URI_references();
+
+ bool normalizeAndCompare(const char * uriText,
+ const char * expectedNormalized);
+ void caseNormalizationTests();
+ void pctEncNormalizationTests();
+ void pathSegmentNormalizationTests();
+
+};
+
+
+
+#endif // TEST_FOUR_SUITE_H
diff --git a/test/test.cpp b/test/test.cpp
new file mode 100644
index 0000000..8eef547
--- /dev/null
+++ b/test/test.cpp
@@ -0,0 +1,1751 @@
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <uriparser/Uri.h>
+#include <cpptest.h>
+#include <memory>
+#include <stdio.h>
+#include <wchar.h>
+
+#include "FourSuite.h"
+
+using namespace Test;
+using namespace std;
+
+
+
+extern "C" {
+UriBool uri_TESTING_ONLY_ParseIpSixA(const char * text);
+UriBool uri_TESTING_ONLY_ParseIpFourA(const char * text);
+}
+
+
+
+#define URI_TEST_IP_FOUR_FAIL(x) TEST_ASSERT(URI_FALSE == uri_TESTING_ONLY_ParseIpFourA(x))
+#define URI_TEST_IP_FOUR_PASS(x) TEST_ASSERT(URI_TRUE == uri_TESTING_ONLY_ParseIpFourA(x))
+
+// Note the closing brackets! TODO
+#define URI_TEST_IP_SIX_FAIL(x) TEST_ASSERT(URI_FALSE == uri_TESTING_ONLY_ParseIpSixA(x "]"))
+#define URI_TEST_IP_SIX_PASS(x) TEST_ASSERT(URI_TRUE == uri_TESTING_ONLY_ParseIpSixA(x "]"))
+
+
+
+class UriSuite : public Suite {
+
+public:
+ UriSuite() {
+ TEST_ADD(UriSuite::testDistinction)
+ TEST_ADD(UriSuite::testIpFour)
+ TEST_ADD(UriSuite::testIpSixPass)
+ TEST_ADD(UriSuite::testIpSixFail)
+ TEST_ADD(UriSuite::testUri)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort1)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort2)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort22_Bug1948038)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_1)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_2)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_3)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_4)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_related_1)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_related_12)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort23_Bug3510198_related_2)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort3)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort4)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort5)
+ TEST_ADD(UriSuite::testUriUserInfoHostPort6)
+ TEST_ADD(UriSuite::testUriHostRegname)
+ TEST_ADD(UriSuite::testUriHostIpFour1)
+ TEST_ADD(UriSuite::testUriHostIpFour2)
+ TEST_ADD(UriSuite::testUriHostIpSix1)
+ TEST_ADD(UriSuite::testUriHostIpSix2)
+ TEST_ADD(UriSuite::testUriHostIpFuture)
+ TEST_ADD(UriSuite::testUriHostEmpty)
+ TEST_ADD(UriSuite::testUriComponents)
+ TEST_ADD(UriSuite::testUriComponents_Bug20070701)
+ TEST_ADD(UriSuite::testEscaping)
+ TEST_ADD(UriSuite::testUnescaping)
+ TEST_ADD(UriSuite::testTrailingSlash)
+ TEST_ADD(UriSuite::testAddBase)
+ TEST_ADD(UriSuite::testToString)
+ TEST_ADD(UriSuite::testToString_Bug1950126)
+ TEST_ADD(UriSuite::testToStringCharsRequired)
+ TEST_ADD(UriSuite::testToStringCharsRequired)
+ TEST_ADD(UriSuite::testNormalizeSyntaxMaskRequired)
+ TEST_ADD(UriSuite::testNormalizeSyntax)
+ TEST_ADD(UriSuite::testNormalizeSyntaxComponents)
+ TEST_ADD(UriSuite::testNormalizeCrash_Bug20080224)
+ TEST_ADD(UriSuite::testFilenameUriConversion)
+ TEST_ADD(UriSuite::testCrash_FreeUriMembers_Bug20080116)
+ TEST_ADD(UriSuite::testCrash_Report2418192)
+ TEST_ADD(UriSuite::testPervertedQueryString);
+ TEST_ADD(UriSuite::testCrash_MakeOwner_Bug20080207)
+ TEST_ADD(UriSuite::testQueryList)
+ TEST_ADD(UriSuite::testQueryListPair)
+ TEST_ADD(UriSuite::testQueryDissection_Bug3590761)
+ TEST_ADD(UriSuite::testFreeCrash_Bug20080827)
+ TEST_ADD(UriSuite::testParseInvalid_Bug16)
+ }
+
+private:
+ bool testDistinctionHelper(const char * uriText, bool expectedHostSet,
+ bool expectedAbsPath, bool expectedEmptyTailSegment) {
+ UriParserStateA state;
+ UriUriA uri;
+ state.uri = &uri;
+
+ int res = uriParseUriA(&state, uriText);
+ if (res != URI_SUCCESS) {
+ uriFreeUriMembersA(&uri);
+ return false;
+ }
+
+ if (expectedHostSet != (uri.hostText.first != NULL)) {
+ uriFreeUriMembersA(&uri);
+ return false;
+ }
+
+ if (expectedAbsPath != (uri.absolutePath == URI_TRUE)) {
+ uriFreeUriMembersA(&uri);
+ return false;
+ }
+
+ if (expectedEmptyTailSegment != ((uri.pathTail != NULL)
+ && (uri.pathTail->text.first == uri.pathTail->text.afterLast))) {
+ uriFreeUriMembersA(&uri);
+ return false;
+ }
+
+ uriFreeUriMembersA(&uri);
+ return true;
+ }
+
+ void testDistinction() {
+ /*
+============================================================================
+Rule | Example | hostSet | absPath | emptySeg
+------------------------------------|---------|---------|---------|---------
+1) URI = scheme ":" hier-part ... | | | |
+ 1) "//" authority path-abempty | "s://" | true | false | false
+ | "s:///" | true | false | true
+ | "s://a" | true | false | false
+ | "s://a/"| true | false | true
+ 2) path-absolute | "s:/" | false | true | false
+ 3) path-rootless | "s:a" | false | false | false
+ | "s:a/" | false | false | true
+ 4) path-empty | "s:" | false | false | false
+------------------------------------|---------|---------|---------|---------
+2) relative-ref = relative-part ... | | | |
+ 1) "//" authority path-abempty | "//" | true | false | false
+ | "///" | true | false | true
+ 2) path-absolute | "/" | false | true | false
+ 3) path-noscheme | "a" | false | false | false
+ | "a/" | false | false | true
+ 4) path-empty | "" | false | false | false
+============================================================================
+ */
+ TEST_ASSERT(testDistinctionHelper("s://", true, false, false));
+ TEST_ASSERT(testDistinctionHelper("s:///", true, false, true));
+ TEST_ASSERT(testDistinctionHelper("s://a", true, false, false));
+ TEST_ASSERT(testDistinctionHelper("s://a/", true, false, true));
+ TEST_ASSERT(testDistinctionHelper("s:/", false, true, false));
+ TEST_ASSERT(testDistinctionHelper("s:a", false, false, false));
+ TEST_ASSERT(testDistinctionHelper("s:a/", false, false, true));
+ TEST_ASSERT(testDistinctionHelper("s:", false, false, false));
+
+ TEST_ASSERT(testDistinctionHelper("//", true, false, false));
+ TEST_ASSERT(testDistinctionHelper("///", true, false, true));
+ TEST_ASSERT(testDistinctionHelper("/", false, true, false));
+ TEST_ASSERT(testDistinctionHelper("a", false, false, false));
+ TEST_ASSERT(testDistinctionHelper("a/", false, false, true));
+ TEST_ASSERT(testDistinctionHelper("", false, false, false));
+ }
+
+ void testIpFour() {
+ URI_TEST_IP_FOUR_FAIL("01.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("001.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("00.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("000.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("256.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("300.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("1111.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("-1.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("0.0.0");
+ URI_TEST_IP_FOUR_FAIL("0.0.0.");
+ URI_TEST_IP_FOUR_FAIL("0.0.0.0.");
+ URI_TEST_IP_FOUR_FAIL("0.0.0.0.0");
+ URI_TEST_IP_FOUR_FAIL("0.0..0");
+ URI_TEST_IP_FOUR_FAIL(".0.0.0");
+
+ URI_TEST_IP_FOUR_PASS("255.0.0.0");
+ URI_TEST_IP_FOUR_PASS("0.0.0.0");
+ URI_TEST_IP_FOUR_PASS("1.0.0.0");
+ URI_TEST_IP_FOUR_PASS("2.0.0.0");
+ URI_TEST_IP_FOUR_PASS("3.0.0.0");
+ URI_TEST_IP_FOUR_PASS("30.0.0.0");
+ }
+
+ void testIpSixPass() {
+ // Quad length
+ URI_TEST_IP_SIX_PASS("abcd::");
+
+ URI_TEST_IP_SIX_PASS("abcd::1");
+ URI_TEST_IP_SIX_PASS("abcd::12");
+ URI_TEST_IP_SIX_PASS("abcd::123");
+ URI_TEST_IP_SIX_PASS("abcd::1234");
+
+ // Full length
+ URI_TEST_IP_SIX_PASS("2001:0db8:0100:f101:0210:a4ff:fee3:9566"); // lower hex
+ URI_TEST_IP_SIX_PASS("2001:0DB8:0100:F101:0210:A4FF:FEE3:9566"); // Upper hex
+ URI_TEST_IP_SIX_PASS("2001:db8:100:f101:210:a4ff:fee3:9566");
+ URI_TEST_IP_SIX_PASS("2001:0db8:100:f101:0:0:0:1");
+ URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:255.255.255.255");
+
+ // Legal IPv4
+ URI_TEST_IP_SIX_PASS("::1.2.3.4");
+ URI_TEST_IP_SIX_PASS("3:4::5:1.2.3.4");
+ URI_TEST_IP_SIX_PASS("::ffff:1.2.3.4");
+ URI_TEST_IP_SIX_PASS("::0.0.0.0"); // Min IPv4
+ URI_TEST_IP_SIX_PASS("::255.255.255.255"); // Max IPv4
+
+ // Zipper position
+ URI_TEST_IP_SIX_PASS("::1:2:3:4:5:6:7");
+ URI_TEST_IP_SIX_PASS("1::1:2:3:4:5:6");
+ URI_TEST_IP_SIX_PASS("1:2::1:2:3:4:5");
+ URI_TEST_IP_SIX_PASS("1:2:3::1:2:3:4");
+ URI_TEST_IP_SIX_PASS("1:2:3:4::1:2:3");
+ URI_TEST_IP_SIX_PASS("1:2:3:4:5::1:2");
+ URI_TEST_IP_SIX_PASS("1:2:3:4:5:6::1");
+ URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:7::");
+
+ // Zipper length
+ URI_TEST_IP_SIX_PASS("1:1:1::1:1:1:1");
+ URI_TEST_IP_SIX_PASS("1:1:1::1:1:1");
+ URI_TEST_IP_SIX_PASS("1:1:1::1:1");
+ URI_TEST_IP_SIX_PASS("1:1::1:1");
+ URI_TEST_IP_SIX_PASS("1:1::1");
+ URI_TEST_IP_SIX_PASS("1::1");
+ URI_TEST_IP_SIX_PASS("::1"); // == localhost
+ URI_TEST_IP_SIX_PASS("::"); // == all addresses
+
+ // A few more variations
+ URI_TEST_IP_SIX_PASS("21ff:abcd::1");
+ URI_TEST_IP_SIX_PASS("2001:db8:100:f101::1");
+ URI_TEST_IP_SIX_PASS("a:b:c::12:1");
+ URI_TEST_IP_SIX_PASS("a:b::0:1:2:3");
+ }
+
+ void testIpSixFail() {
+ // 5 char quad
+ URI_TEST_IP_SIX_FAIL("::12345");
+
+ // Two zippers
+ URI_TEST_IP_SIX_FAIL("abcd::abcd::abcd");
+
+ // Triple-colon zipper
+ URI_TEST_IP_SIX_FAIL(":::1234");
+ URI_TEST_IP_SIX_FAIL("1234:::1234:1234");
+ URI_TEST_IP_SIX_FAIL("1234:1234:::1234");
+ URI_TEST_IP_SIX_FAIL("1234:::");
+
+ // No quads, just IPv4
+ URI_TEST_IP_SIX_FAIL("1.2.3.4");
+ URI_TEST_IP_SIX_FAIL("0001.0002.0003.0004");
+
+ // Five quads
+ URI_TEST_IP_SIX_FAIL("0000:0000:0000:0000:0000:1.2.3.4");
+
+ // Seven quads
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0");
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:");
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:1.2.3.4");
+
+ // Nine quads
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:0:0");
+
+ // Invalid IPv4 part
+ URI_TEST_IP_SIX_FAIL("::ffff:001.02.03.004"); // Leading zeros
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.1111"); // Four char octet
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.256"); // > 255
+ URI_TEST_IP_SIX_FAIL("::ffff:311.2.3.4"); // > 155
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3:4"); // Not a dot
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3"); // Missing octet
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3."); // Missing octet
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3a.4"); // Hex in octet
+ URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.4:123"); // Crap input
+
+ // Nonhex
+ URI_TEST_IP_SIX_FAIL("g:0:0:0:0:0:0");
+ }
+
+ void testUri() {
+ UriParserStateA stateA;
+ UriParserStateW stateW;
+ UriUriA uriA;
+ UriUriW uriW;
+
+ stateA.uri = &uriA;
+ stateW.uri = &uriW;
+
+ // On/off for each
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "//user:pass@[::1]:80/segment/index.html?query#frag"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://[::1]:80/segment/index.html?query#frag"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://user:pass@[::1]/segment/index.html?query#frag"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80?query#frag"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html#frag"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html?query"));
+ uriFreeUriMembersA(&uriA);
+
+ // Schema, port, one segment
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "ftp://host:21/gnu/"));
+ uriFreeUriMembersA(&uriA);
+
+ // Relative
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "one/two/three"));
+ TEST_ASSERT(!uriA.absolutePath);
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "/one/two/three"));
+ TEST_ASSERT(uriA.absolutePath);
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "//user:pass@localhost/one/two/three"));
+ uriFreeUriMembersA(&uriA);
+
+ // ANSI and Unicode
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://www.example.com/"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriW(&stateW, L"http://www.example.com/"));
+ uriFreeUriMembersW(&uriW);
+
+ // Real life examples
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://sourceforge.net/projects/uriparser/"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://sourceforge.net/project/platformdownload.php?group_id=182840"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "mailto:test@example.com"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "../../"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "/"));
+ TEST_ASSERT(uriA.absolutePath)
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, ""));
+ TEST_ASSERT(!uriA.absolutePath)
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "file:///bin/bash"));
+ uriFreeUriMembersA(&uriA);
+
+ // Percent encoding
+ TEST_ASSERT(0 == uriParseUriA(&stateA, "http://www.example.com/name%20with%20spaces/"));
+ uriFreeUriMembersA(&uriA);
+ TEST_ASSERT(0 != uriParseUriA(&stateA, "http://www.example.com/name with spaces/"));
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriComponents() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 15 01 0 7 01
+ const char * const input = "http" "://" "sourceforge.net" "/" "project" "/"
+ // 0 20 01 0 15
+ "platformdownload.php" "?" "group_id=182840";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.scheme.first == input);
+ TEST_ASSERT(uriA.scheme.afterLast == input + 4);
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 15);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+
+ TEST_ASSERT(uriA.pathHead->text.first == input + 4 + 3 + 15 + 1);
+ TEST_ASSERT(uriA.pathHead->text.afterLast == input + 4 + 3 + 15 + 1 + 7);
+ TEST_ASSERT(uriA.pathHead->next->text.first == input + 4 + 3 + 15 + 1 + 7 + 1);
+ TEST_ASSERT(uriA.pathHead->next->text.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20);
+ TEST_ASSERT(uriA.pathHead->next->next == NULL);
+ TEST_ASSERT(uriA.pathTail == uriA.pathHead->next);
+
+ TEST_ASSERT(uriA.query.first == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1);
+ TEST_ASSERT(uriA.query.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1 + 15);
+ TEST_ASSERT(uriA.fragment.first == NULL);
+ TEST_ASSERT(uriA.fragment.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriComponents_Bug20070701() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 01 01 01
+ const char * const input = "a" ":" "b";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.scheme.first == input);
+ TEST_ASSERT(uriA.scheme.afterLast == input + 1);
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.hostText.first == NULL);
+ TEST_ASSERT(uriA.hostText.afterLast == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+
+ TEST_ASSERT(uriA.pathHead->text.first == input + 1 + 1);
+ TEST_ASSERT(uriA.pathHead->text.afterLast == input + 1 + 1 + 1);
+ TEST_ASSERT(uriA.pathHead->next == NULL);
+ TEST_ASSERT(uriA.pathTail == uriA.pathHead);
+
+ TEST_ASSERT(uriA.query.first == NULL);
+ TEST_ASSERT(uriA.query.afterLast == NULL);
+ TEST_ASSERT(uriA.fragment.first == NULL);
+ TEST_ASSERT(uriA.fragment.afterLast == NULL);
+
+ TEST_ASSERT(!uriA.absolutePath);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort1() {
+ // User info with ":", no port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7 01 0 9
+ const char * const input = "http" "://" "abc:def" "@" "localhost";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == input + 4 + 3);
+ TEST_ASSERT(uriA.userInfo.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 7 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort2() {
+ // User info with ":", with port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7 01 0 9
+ const char * const input = "http" "://" "abc:def" "@" "localhost"
+ // 01 0 3
+ ":" "123";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == input + 4 + 3);
+ TEST_ASSERT(uriA.userInfo.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 7 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
+ TEST_ASSERT(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1);
+ TEST_ASSERT(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort22_Bug1948038() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+
+ res = uriParseUriA(&stateA, "http://user:21@host/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "user:21", 7 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 7);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+
+ res = uriParseUriA(&stateA, "http://user:1234@192.168.0.1:1234/foo.com");
+ TEST_ASSERT(URI_SUCCESS == res);
+ uriFreeUriMembersA(&uriA);
+
+ res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo/");
+ TEST_ASSERT(URI_ERROR_SYNTAX == res);
+ uriFreeUriMembersA(&uriA);
+
+ res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo:21/");
+ TEST_ASSERT(URI_ERROR_SYNTAX == res);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_1() {
+ // User info with ":", with port, with escaped chars in password
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 10 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "user:%2F21" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "user:%2F21", 10 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 10);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_2() {
+ // User info with ":", with port, with escaped chars in user name and password
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 13 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "%2Fuser:%2F21" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "%2Fuser:%2F21", 13 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 13);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_3() {
+ // User info with ":", with port, with escaped chars in password
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 16 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "user:!$&'()*+,;=" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "user:!$&'()*+,;=", 16 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 16);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_4() {
+ // User info with ":", with port, with escaped chars in user name and password
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 20 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "!$&'()*+,;=:password" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "!$&'()*+,;=:password", 20 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 20);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_related_1() {
+ // Empty user info
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(uriA.userInfo.afterLast != NULL);
+ TEST_ASSERT(uriA.userInfo.first != NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 0);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_related_12() {
+ // Empty user info
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 7 01
+ res = uriParseUriA(&stateA, "http" "://" "%2Fhost" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "%2Fhost", 7 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 7);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort23_Bug3510198_related_2() {
+ // Several colons in userinfo
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ int res;
+ // 0 4 0 3 0 2 01 0 4 01
+ res = uriParseUriA(&stateA, "http" "://" "::" "@" "host" "/");
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(!memcmp(uriA.userInfo.first, "::", 2 * sizeof(char)));
+ TEST_ASSERT(uriA.userInfo.afterLast - uriA.userInfo.first == 2);
+ TEST_ASSERT(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 4);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort3() {
+ // User info without ":", no port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7 01 0 9
+ const char * const input = "http" "://" "abcdefg" "@" "localhost";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == input + 4 + 3);
+ TEST_ASSERT(uriA.userInfo.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 7 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort4() {
+ // User info without ":", with port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7 01 0 9
+ const char * const input = "http" "://" "abcdefg" "@" "localhost"
+ // 01 0 3
+ ":" "123";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == input + 4 + 3);
+ TEST_ASSERT(uriA.userInfo.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 7 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
+ TEST_ASSERT(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1);
+ TEST_ASSERT(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort5() {
+ // No user info, no port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 9
+ const char * const input = "http" "://" "localhost";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 9);
+ TEST_ASSERT(uriA.portText.first == NULL);
+ TEST_ASSERT(uriA.portText.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriUserInfoHostPort6() {
+ // No user info, with port
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 9 01 0 3
+ const char * const input = "http" "://" "localhost" ":" "123";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 9);
+ TEST_ASSERT(uriA.portText.first == input + 4 + 3 + 9 + 1);
+ TEST_ASSERT(uriA.portText.afterLast == input + 4 + 3 + 9 + 1 + 3);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostRegname() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 11
+ const char * const input = "http" "://" "example.com";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 11);
+ TEST_ASSERT(uriA.hostData.ip4 == NULL);
+ TEST_ASSERT(uriA.hostData.ip6 == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostIpFour1() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7 01 0 2
+ const char * const input = "http" "://" "1.2.3.4" ":" "80";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostData.ip4 != NULL);
+ TEST_ASSERT(uriA.hostData.ip6 == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostIpFour2() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 0 7
+ const char * const input = "http" "://" "1.2.3.4";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 7);
+ TEST_ASSERT(uriA.hostData.ip4 != NULL);
+ TEST_ASSERT(uriA.hostData.ip6 == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostIpSix1() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 01 45 01 0 2
+ const char * const input = "http" "://" "[::1]" ":" "80";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 4);
+ TEST_ASSERT(uriA.hostData.ip4 == NULL);
+ TEST_ASSERT(uriA.hostData.ip6 != NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostIpSix2() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 01 45
+ const char * const input = "http" "://" "[::1]";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.hostText.first == input + 4 + 3 + 1);
+ TEST_ASSERT(uriA.hostText.afterLast == input + 4 + 3 + 4);
+ TEST_ASSERT(uriA.hostData.ip4 == NULL);
+ TEST_ASSERT(uriA.hostData.ip6 != NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.first == NULL);
+ TEST_ASSERT(uriA.hostData.ipFuture.afterLast == NULL);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostEmpty() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 4 0 3 01 0 3
+ const char * const input = "http" "://" ":" "123";
+ const int res = uriParseUriA(&stateA, input);
+ TEST_ASSERT(URI_SUCCESS == res);
+ TEST_ASSERT(uriA.userInfo.first == NULL);
+ TEST_ASSERT(uriA.userInfo.afterLast == NULL);
+ TEST_ASSERT(uriA.hostText.first != NULL);
+ TEST_ASSERT(uriA.hostText.afterLast != NULL);
+ TEST_ASSERT(uriA.hostText.afterLast - uriA.hostText.first == 0);
+ TEST_ASSERT(uriA.portText.first == input + 4 + 3 + 1);
+ TEST_ASSERT(uriA.portText.afterLast == input + 4 + 3 + 1 + 3);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testUriHostIpFuture() {
+ // TODO
+ }
+
+ bool testEscapingHelper(const wchar_t * in, const wchar_t * expectedOut,
+ bool spaceToPlus = false, bool normalizeBreaks = false) {
+ wchar_t * const buffer = new wchar_t[(normalizeBreaks ? 6 : 3)
+ * wcslen(in) + 1];
+ if (uriEscapeW(in, buffer, spaceToPlus, normalizeBreaks)
+ != buffer + wcslen(expectedOut)) {
+ delete [] buffer;
+ return false;
+ }
+
+ const bool equal = !wcscmp(buffer, expectedOut);
+ delete [] buffer;
+ return equal;
+ }
+
+ void testEscaping() {
+ const bool SPACE_TO_PLUS = true;
+ const bool SPACE_TO_PERCENT = false;
+ const bool KEEP_UNMODIFIED = false;
+ const bool NORMALIZE = true;
+
+ // '+' to ' '
+ TEST_ASSERT(testEscapingHelper(L"abc def", L"abc+def", SPACE_TO_PLUS));
+ TEST_ASSERT(testEscapingHelper(L"abc def", L"abc%20def", SPACE_TO_PERCENT));
+
+ // Percent encoding
+ TEST_ASSERT(testEscapingHelper(L"\x00", L"\0"));
+ TEST_ASSERT(testEscapingHelper(L"\x01", L"%01"));
+ TEST_ASSERT(testEscapingHelper(L"\xff", L"%FF"));
+
+ // Linebreak normalization
+ TEST_ASSERT(testEscapingHelper(L"\x0d", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"g\x0d", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0dg", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0d", L"%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"g\x0d", L"g%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"\x0dg", L"%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+
+ TEST_ASSERT(testEscapingHelper(L"\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"g\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0a", L"%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"g\x0a", L"g%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"\x0ag", L"%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+
+ TEST_ASSERT(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+
+ TEST_ASSERT(testEscapingHelper(L"\x0a\x0d", L"%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"g\x0a\x0d", L"g%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0a\x0dg", L"%0D%0A%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
+ TEST_ASSERT(testEscapingHelper(L"\x0a\x0d", L"%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"g\x0a\x0d", L"g%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ TEST_ASSERT(testEscapingHelper(L"\x0a\x0dg", L"%0A%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED));
+ }
+
+ bool testUnescapingHelper(const wchar_t * input, const wchar_t * output,
+ bool plusToSpace = false, UriBreakConversion breakConversion = URI_BR_DONT_TOUCH) {
+ wchar_t * working = new wchar_t[URI_STRLEN(input) + 1];
+ wcscpy(working, input);
+ const wchar_t * newTermZero = uriUnescapeInPlaceExW(working,
+ plusToSpace ? URI_TRUE : URI_FALSE, breakConversion);
+ const bool success = ((newTermZero == working + wcslen(output))
+ && !wcscmp(working, output));
+ delete[] working;
+ return success;
+ }
+
+ void testUnescaping() {
+ const bool PLUS_TO_SPACE = true;
+ const bool PLUS_DONT_TOUCH = false;
+
+
+ // Proper
+ TEST_ASSERT(testUnescapingHelper(L"abc%20%41BC", L"abc ABC"));
+ TEST_ASSERT(testUnescapingHelper(L"%20", L" "));
+
+ // Incomplete
+ TEST_ASSERT(testUnescapingHelper(L"%0", L"%0"));
+
+ // Nonhex
+ TEST_ASSERT(testUnescapingHelper(L"%0g", L"%0g"));
+ TEST_ASSERT(testUnescapingHelper(L"%G0", L"%G0"));
+
+ // No double decoding
+ TEST_ASSERT(testUnescapingHelper(L"%2520", L"%20"));
+
+ // Decoding of '+'
+ TEST_ASSERT(testUnescapingHelper(L"abc+def", L"abc+def", PLUS_DONT_TOUCH));
+ TEST_ASSERT(testUnescapingHelper(L"abc+def", L"abc def", PLUS_TO_SPACE));
+
+ // Line break conversion
+ TEST_ASSERT(testUnescapingHelper(L"%0d", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d", L"\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
+ TEST_ASSERT(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
+ }
+
+ bool testAddBaseHelper(const wchar_t * base, const wchar_t * rel, const wchar_t * expectedResult) {
+ UriParserStateW stateW;
+
+ // Base
+ UriUriW baseUri;
+ stateW.uri = &baseUri;
+ int res = uriParseUriW(&stateW, base);
+ if (res != 0) {
+ uriFreeUriMembersW(&baseUri);
+ return false;
+ }
+
+ // Rel
+ UriUriW relUri;
+ stateW.uri = &relUri;
+ res = uriParseUriW(&stateW, rel);
+ if (res != 0) {
+ uriFreeUriMembersW(&baseUri);
+ uriFreeUriMembersW(&relUri);
+ return false;
+ }
+
+ // Expected result
+ UriUriW expectedUri;
+ stateW.uri = &expectedUri;
+ res = uriParseUriW(&stateW, expectedResult);
+ if (res != 0) {
+ uriFreeUriMembersW(&baseUri);
+ uriFreeUriMembersW(&relUri);
+ uriFreeUriMembersW(&expectedUri);
+ return false;
+ }
+
+ // Transform
+ UriUriW transformedUri;
+ res = uriAddBaseUriW(&transformedUri, &relUri, &baseUri);
+ if (res != 0) {
+ uriFreeUriMembersW(&baseUri);
+ uriFreeUriMembersW(&relUri);
+ uriFreeUriMembersW(&expectedUri);
+ uriFreeUriMembersW(&transformedUri);
+ return false;
+ }
+
+ const bool equal = (URI_TRUE == uriEqualsUriW(&transformedUri, &expectedUri));
+ if (!equal) {
+ wchar_t transformedUriText[1024 * 8];
+ wchar_t expectedUriText[1024 * 8];
+ uriToStringW(transformedUriText, &transformedUri, 1024 * 8, NULL);
+ uriToStringW(expectedUriText, &expectedUri, 1024 * 8, NULL);
+#ifdef HAVE_WPRINTF
+ wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", expectedUriText, transformedUriText);
+#endif
+ }
+
+ uriFreeUriMembersW(&baseUri);
+ uriFreeUriMembersW(&relUri);
+ uriFreeUriMembersW(&expectedUri);
+ uriFreeUriMembersW(&transformedUri);
+ return equal;
+ }
+
+ void testTrailingSlash() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ // 0 3 01
+ const char * const input = "abc" "/";
+ TEST_ASSERT(0 == uriParseUriA(&stateA, input));
+
+ TEST_ASSERT(uriA.pathHead->text.first == input);
+ TEST_ASSERT(uriA.pathHead->text.afterLast == input + 3);
+ TEST_ASSERT(uriA.pathHead->next->text.first == uriA.pathHead->next->text.afterLast);
+ TEST_ASSERT(uriA.pathHead->next->next == NULL);
+ TEST_ASSERT(uriA.pathTail == uriA.pathHead->next);
+ uriFreeUriMembersA(&uriA);
+ }
+
+ void testAddBase() {
+ // 5.4.1. Normal Examples
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g:h", L"g:h"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g", L"http://a/b/c/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g", L"http://a/b/c/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/", L"http://a/b/c/g/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g", L"http://a/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"//g", L"http://g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"?y", L"http://a/b/c/d;p?y"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y", L"http://a/b/c/g?y"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"#s", L"http://a/b/c/d;p?q#s"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s", L"http://a/b/c/g#s"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y#s", L"http://a/b/c/g?y#s"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L";x", L"http://a/b/c/;x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x", L"http://a/b/c/g;x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x?y#s", L"http://a/b/c/g;x?y#s"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"", L"http://a/b/c/d;p?q"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L".", L"http://a/b/c/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./", L"http://a/b/c/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..", L"http://a/b/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../", L"http://a/b/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../g", L"http://a/b/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../..", L"http://a/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../", L"http://a/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../g", L"http://a/g"));
+
+ // 5.4.2. Abnormal Examples
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../g", L"http://a/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../../g", L"http://a/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/./g", L"http://a/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/../g", L"http://a/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g.", L"http://a/b/c/g."));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L".g", L"http://a/b/c/.g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g..", L"http://a/b/c/g.."));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..g", L"http://a/b/c/..g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./../g", L"http://a/b/g"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g/.", L"http://a/b/c/g/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/./h", L"http://a/b/c/g/h"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/../h", L"http://a/b/c/h"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/./y", L"http://a/b/c/g;x=1/y"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/../y", L"http://a/b/c/y"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/./x", L"http://a/b/c/g?y/./x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/../x", L"http://a/b/c/g?y/../x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/./x", L"http://a/b/c/g#s/./x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/../x", L"http://a/b/c/g#s/../x"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http:g"));
+
+ // Bug related to absolutePath flag set despite presence of host
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/", L"http://a/"));
+ TEST_ASSERT(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g/", L"http://a/g/"));
+ }
+
+ bool testToStringHelper(const wchar_t * text) {
+ // Parse
+ UriParserStateW state;
+ UriUriW uri;
+ state.uri = &uri;
+ int res = uriParseUriW(&state, text);
+ if (res != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ // Back to string, _huge_ limit
+ wchar_t shouldbeTheSame[1024 * 8];
+ res = uriToStringW(shouldbeTheSame, &uri, 1024 * 8, NULL);
+ if (res != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ // Compare
+ bool equals = (0 == wcscmp(shouldbeTheSame, text));
+ if (!equals) {
+#ifdef HAVE_WPRINTF
+ wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", text, shouldbeTheSame);
+#endif
+ }
+
+ // Back to string, _exact_ limit
+ const int len = static_cast<int>(wcslen(text));
+ int charsWritten;
+ res = uriToStringW(shouldbeTheSame, &uri, len + 1, &charsWritten);
+ if ((res != 0) || (charsWritten != len + 1)) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ // Back to string, _too small_ limit
+ res = uriToStringW(shouldbeTheSame, &uri, len, &charsWritten);
+ if ((res == 0) || (charsWritten >= len + 1)) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ uriFreeUriMembersW(&uri);
+ return equals;
+ }
+
+ void testToString() {
+ // Scheme
+ TEST_ASSERT(testToStringHelper(L"ftp://localhost/"));
+ // UserInfo
+ TEST_ASSERT(testToStringHelper(L"http://user:pass@localhost/"));
+ // IPv4
+ TEST_ASSERT(testToStringHelper(L"http://123.0.1.255/"));
+ // IPv6
+ TEST_ASSERT(testToStringHelper(L"http://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]/"));
+ // IPvFuture
+ TEST_ASSERT(testToStringHelper(L"http://[vA.123456]/"));
+ // Port
+ TEST_ASSERT(testToStringHelper(L"http://example.com:123/"));
+ // Path
+ TEST_ASSERT(testToStringHelper(L"http://example.com"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/abc/"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/abc/def"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/abc/def/"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com//"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/./.."));
+ // Query
+ TEST_ASSERT(testToStringHelper(L"http://example.com/?abc"));
+ // Fragment
+ TEST_ASSERT(testToStringHelper(L"http://example.com/#abc"));
+ TEST_ASSERT(testToStringHelper(L"http://example.com/?def#abc"));
+
+ // Relative
+ TEST_ASSERT(testToStringHelper(L"a"));
+ TEST_ASSERT(testToStringHelper(L"a/"));
+ TEST_ASSERT(testToStringHelper(L"/a"));
+ TEST_ASSERT(testToStringHelper(L"/a/"));
+ TEST_ASSERT(testToStringHelper(L"abc"));
+ TEST_ASSERT(testToStringHelper(L"abc/"));
+ TEST_ASSERT(testToStringHelper(L"/abc"));
+ TEST_ASSERT(testToStringHelper(L"/abc/"));
+ TEST_ASSERT(testToStringHelper(L"a/def"));
+ TEST_ASSERT(testToStringHelper(L"a/def/"));
+ TEST_ASSERT(testToStringHelper(L"/a/def"));
+ TEST_ASSERT(testToStringHelper(L"/a/def/"));
+ TEST_ASSERT(testToStringHelper(L"abc/def"));
+ TEST_ASSERT(testToStringHelper(L"abc/def/"));
+ TEST_ASSERT(testToStringHelper(L"/abc/def"));
+ TEST_ASSERT(testToStringHelper(L"/abc/def/"));
+ TEST_ASSERT(testToStringHelper(L"/"));
+ TEST_ASSERT(testToStringHelper(L"//a/"));
+ TEST_ASSERT(testToStringHelper(L"."));
+ TEST_ASSERT(testToStringHelper(L"./"));
+ TEST_ASSERT(testToStringHelper(L"/."));
+ TEST_ASSERT(testToStringHelper(L"/./"));
+ TEST_ASSERT(testToStringHelper(L""));
+ TEST_ASSERT(testToStringHelper(L"./abc/def"));
+ TEST_ASSERT(testToStringHelper(L"?query"));
+ TEST_ASSERT(testToStringHelper(L"#fragment"));
+ TEST_ASSERT(testToStringHelper(L"?query#fragment"));
+
+ // Tests for bugs from the past
+ TEST_ASSERT(testToStringHelper(L"f:/.//g"));
+ }
+
+ void testToString_Bug1950126() {
+ UriParserStateW state;
+ UriUriW uriOne;
+ UriUriW uriTwo;
+ const wchar_t * const uriOneString = L"http://e.com/";
+ const wchar_t * const uriTwoString = L"http://e.com";
+ state.uri = &uriOne;
+ TEST_ASSERT(URI_SUCCESS == uriParseUriW(&state, uriOneString));
+ state.uri = &uriTwo;
+ TEST_ASSERT(URI_SUCCESS == uriParseUriW(&state, uriTwoString));
+ TEST_ASSERT(URI_FALSE == uriEqualsUriW(&uriOne, &uriTwo));
+ uriFreeUriMembersW(&uriOne);
+ uriFreeUriMembersW(&uriTwo);
+
+ TEST_ASSERT(testToStringHelper(uriOneString));
+ TEST_ASSERT(testToStringHelper(uriTwoString));
+ }
+
+ bool testToStringCharsRequiredHelper(const wchar_t * text) {
+ // Parse
+ UriParserStateW state;
+ UriUriW uri;
+ state.uri = &uri;
+ int res = uriParseUriW(&state, text);
+ if (res != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ // Required space?
+ int charsRequired;
+ if (uriToStringCharsRequiredW(&uri, &charsRequired) != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ // Minimum
+ wchar_t * buffer = new wchar_t[charsRequired + 1];
+ if (uriToStringW(buffer, &uri, charsRequired + 1, NULL) != 0) {
+ uriFreeUriMembersW(&uri);
+ delete [] buffer;
+ return false;
+ }
+
+ // One less than minimum
+ if (uriToStringW(buffer, &uri, charsRequired, NULL) == 0) {
+ uriFreeUriMembersW(&uri);
+ delete [] buffer;
+ return false;
+ }
+
+ uriFreeUriMembersW(&uri);
+ delete [] buffer;
+ return true;
+ }
+
+ void testToStringCharsRequired() {
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com/"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com:80/"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://user:pass@www.example.com/"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com/index.html"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com/?abc"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com/#def"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"http://www.example.com/?abc#def"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"/test"));
+ TEST_ASSERT(testToStringCharsRequiredHelper(L"test"));
+ }
+
+ bool testNormalizeMaskHelper(const wchar_t * uriText, unsigned int expectedMask) {
+ UriParserStateW state;
+ UriUriW uri;
+ state.uri = &uri;
+ int res = uriParseUriW(&state, uriText);
+ if (res != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ const unsigned int maskBefore = uriNormalizeSyntaxMaskRequiredW(&uri);
+ if (maskBefore != expectedMask) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ res = uriNormalizeSyntaxW(&uri);
+ if (res != 0) {
+ uriFreeUriMembersW(&uri);
+ return false;
+ }
+
+ const unsigned int maskAfter = uriNormalizeSyntaxMaskRequiredW(&uri);
+ uriFreeUriMembersW(&uri);
+
+ // Second call should be no problem
+ uriFreeUriMembersW(&uri);
+
+ return (maskAfter == URI_NORMALIZED);
+ }
+
+ void testNormalizeSyntaxMaskRequired() {
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://localhost/", URI_NORMALIZED));
+ TEST_ASSERT(testNormalizeMaskHelper(L"httP://localhost/", URI_NORMALIZE_SCHEME));
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://%0d@localhost/", URI_NORMALIZE_USER_INFO));
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://localhosT/", URI_NORMALIZE_HOST));
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://localhost/./abc", URI_NORMALIZE_PATH));
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://localhost/?AB%43", URI_NORMALIZE_QUERY));
+ TEST_ASSERT(testNormalizeMaskHelper(L"http://localhost/#AB%43", URI_NORMALIZE_FRAGMENT));
+ }
+
+ bool testNormalizeSyntaxHelper(const wchar_t * uriText, const wchar_t * expectedNormalized,
+ unsigned int mask = static_cast<unsigned int>(-1)) {
+ UriParserStateW stateW;
+ int res;
+
+ UriUriW testUri;
+ stateW.uri = &testUri;
+ res = uriParseUriW(&stateW, uriText);
+ if (res != 0) {
+ uriFreeUriMembersW(&testUri);
+ return false;
+ }
+
+ // Expected result
+ UriUriW expectedUri;
+ stateW.uri = &expectedUri;
+ res = uriParseUriW(&stateW, expectedNormalized);
+ if (res != 0) {
+ uriFreeUriMembersW(&testUri);
+ uriFreeUriMembersW(&expectedUri);
+ return false;
+ }
+
+ // First run
+ res = uriNormalizeSyntaxExW(&testUri, mask);
+ if (res != 0) {
+ uriFreeUriMembersW(&testUri);
+ uriFreeUriMembersW(&expectedUri);
+ return false;
+ }
+
+ bool equalAfter = (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri));
+
+ // Second run
+ res = uriNormalizeSyntaxExW(&testUri, mask);
+ if (res != 0) {
+ uriFreeUriMembersW(&testUri);
+ uriFreeUriMembersW(&expectedUri);
+ return false;
+ }
+
+ equalAfter = equalAfter
+ && (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri));
+
+ uriFreeUriMembersW(&testUri);
+ uriFreeUriMembersW(&expectedUri);
+ return equalAfter;
+ }
+
+ void testNormalizeSyntax() {
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"eXAMPLE://a/./b/../b/%63/%7bfoo%7d",
+ L"example://a/b/c/%7Bfoo%7D"));
+
+ // Testcase by Adrian Manrique
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"http://examp%4Ce.com/",
+ L"http://example.com/"));
+
+ // Testcase by Adrian Manrique
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"http://example.com/a/b/%2E%2E/",
+ L"http://example.com/a/"));
+
+ // Reported by Adrian Manrique
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"http://user:pass@SOMEHOST.COM:123",
+ L"http://user:pass@somehost.com:123"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://a:b@HOST:123/./1/2/../%41?abc#def",
+ L"http://a:b@host:123/1/A?abc#def"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"../../abc",
+ L"../../abc"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"../../abc/..",
+ L"../../"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"../../abc/../def",
+ L"../../def"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"abc/..",
+ L""));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"abc/../",
+ L""));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"../../abc/./def",
+ L"../../abc/def"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"./def",
+ L"def"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"def/.",
+ L"def/"));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"./abc:def",
+ L"./abc:def"));
+ }
+
+ void testNormalizeSyntaxComponents() {
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"http://%41@EXAMPLE.ORG/../a?%41#%41",
+ URI_NORMALIZE_SCHEME));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"HTTP://A@EXAMPLE.ORG/../a?%41#%41",
+ URI_NORMALIZE_USER_INFO));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"HTTP://%41@example.org/../a?%41#%41",
+ URI_NORMALIZE_HOST));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"HTTP://%41@EXAMPLE.ORG/a?%41#%41",
+ URI_NORMALIZE_PATH));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"HTTP://%41@EXAMPLE.ORG/../a?A#%41",
+ URI_NORMALIZE_QUERY));
+
+ TEST_ASSERT(testNormalizeSyntaxHelper(
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
+ L"HTTP://%41@EXAMPLE.ORG/../a?%41#A",
+ URI_NORMALIZE_FRAGMENT));
+ }
+
+ void testNormalizeCrash_Bug20080224() {
+ UriParserStateW stateW;
+ int res;
+ UriUriW testUri;
+ stateW.uri = &testUri;
+
+ res = uriParseUriW(&stateW, L"http://example.org/abc//../def");
+ TEST_ASSERT(res == 0);
+
+ // First call will make us owner of copied memory
+ res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_SCHEME);
+ TEST_ASSERT(res == 0);
+ res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_HOST);
+ TEST_ASSERT(res == 0);
+
+ // Frees empty path segment -> crash
+ res = uriNormalizeSyntaxW(&testUri);
+ TEST_ASSERT(res == 0);
+
+ uriFreeUriMembersW(&testUri);
+ }
+
+ void testFilenameUriConversionHelper(const wchar_t * filename,
+ const wchar_t * uriString, bool forUnix) {
+ const int prefixLen = forUnix ? 7 : 8;
+
+ // Filename to URI string
+ const size_t uriBufferLen = prefixLen + 3 * wcslen(filename) + 1;
+ wchar_t * uriBuffer = new wchar_t[uriBufferLen];
+ if (forUnix) {
+ uriUnixFilenameToUriStringW(filename, uriBuffer);
+ } else {
+ uriWindowsFilenameToUriStringW(filename, uriBuffer);
+ }
+#ifdef HAVE_WPRINTF
+ // wprintf(L"1 [%s][%s]\n", uriBuffer, uriString);
+#endif
+ TEST_ASSERT(!wcscmp(uriBuffer, uriString));
+ delete [] uriBuffer;
+
+ // URI string to filename
+ const size_t filenameBufferLen = wcslen(uriString) + 1;
+ wchar_t * filenameBuffer = new wchar_t[filenameBufferLen];
+ if (forUnix) {
+ uriUriStringToUnixFilenameW(uriString, filenameBuffer);
+ } else {
+ uriUriStringToWindowsFilenameW(uriString, filenameBuffer);
+ }
+#ifdef HAVE_WPRINTF
+ // wprintf(L"2 [%s][%s]\n", filenameBuffer, filename);
+#endif
+ TEST_ASSERT(!wcscmp(filenameBuffer, filename));
+ delete [] filenameBuffer;
+ }
+
+ void testFilenameUriConversion() {
+ const bool FOR_UNIX = true;
+ const bool FOR_WINDOWS = false;
+ testFilenameUriConversionHelper(L"/bin/bash", L"file:///bin/bash", FOR_UNIX);
+ testFilenameUriConversionHelper(L"./configure", L"./configure", FOR_UNIX);
+
+ testFilenameUriConversionHelper(L"E:\\Documents and Settings", L"file:///E:/Documents%20and%20Settings", FOR_WINDOWS);
+ testFilenameUriConversionHelper(L".\\Readme.txt", L"./Readme.txt", FOR_WINDOWS);
+
+ testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_WINDOWS);
+ testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_UNIX);
+
+ testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_WINDOWS);
+ testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_UNIX);
+ }
+
+ void testCrash_FreeUriMembers_Bug20080116() {
+ // Testcase by Adrian Manrique
+ UriParserStateA state;
+ UriUriA uri;
+ state.uri = &uri;
+ uriParseUriA(&state, "http://test/?");
+ uriNormalizeSyntaxA(&uri);
+ uriFreeUriMembersA(&uri);
+
+ TEST_ASSERT(true);
+ }
+
+ void testCrash_Report2418192() {
+ // Testcase by Harvey Vrsalovic
+ helperTestQueryString("http://svcs.cnn.com/weather/wrapper.jsp?&csiID=csi1", 1);
+ }
+
+ void testPervertedQueryString() {
+ helperTestQueryString("http://example.org/?&&=&&&=&&&&==&===&====", 5);
+ }
+
+ void helperTestQueryString(char const * uriString, int pairsExpected) {
+ UriParserStateA state;
+ UriUriA uri;
+ state.uri = &uri;
+ int res = uriParseUriA(&state, uriString);
+ TEST_ASSERT(res == URI_SUCCESS);
+
+ UriQueryListA * queryList = NULL;
+ int itemCount = 0;
+
+ res = uriDissectQueryMallocA(&queryList, &itemCount,
+ uri.query.first, uri.query.afterLast);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(queryList != NULL);
+ TEST_ASSERT(itemCount == pairsExpected);
+ uriFreeQueryListA(queryList);
+ uriFreeUriMembersA(&uri);
+ }
+
+ void testCrash_MakeOwner_Bug20080207() {
+ // Testcase by Adrian Manrique
+ UriParserStateA state;
+ UriUriA sourceUri;
+ state.uri = &sourceUri;
+ const char * const sourceUriString = "http://user:pass@somehost.com:80/";
+ if (uriParseUriA(&state, sourceUriString) != 0) {
+ TEST_ASSERT(false);
+ }
+ if (uriNormalizeSyntaxA(&sourceUri) != 0) {
+ TEST_ASSERT(false);
+ }
+ uriFreeUriMembersA(&sourceUri);
+ TEST_ASSERT(true);
+ }
+
+ void testQueryListHelper(const wchar_t * input, int expectedItemCount) {
+ int res;
+
+ UriBool spacePlusConversion = URI_TRUE;
+ UriBool normalizeBreaks = URI_FALSE;
+ UriBreakConversion breakConversion = URI_BR_DONT_TOUCH;
+
+ int itemCount;
+ UriQueryListW * queryList;
+ res = uriDissectQueryMallocExW(&queryList, &itemCount,
+ input, input + wcslen(input), spacePlusConversion, breakConversion);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(itemCount == expectedItemCount);
+ TEST_ASSERT((queryList == NULL) == (expectedItemCount == 0));
+
+ if (expectedItemCount != 0) {
+ // First
+ int charsRequired;
+ res = uriComposeQueryCharsRequiredExW(queryList, &charsRequired, spacePlusConversion,
+ normalizeBreaks);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(charsRequired >= (int)wcslen(input));
+
+ wchar_t * recomposed = new wchar_t[charsRequired + 1];
+ int charsWritten;
+ res = uriComposeQueryExW(recomposed, queryList, charsRequired + 1,
+ &charsWritten, spacePlusConversion, normalizeBreaks);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(charsWritten <= charsRequired);
+ TEST_ASSERT(charsWritten == (int)wcslen(input) + 1);
+ TEST_ASSERT(!wcscmp(input, recomposed));
+ delete [] recomposed;
+
+ recomposed = NULL;
+ res = uriComposeQueryMallocW(&recomposed, queryList);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(recomposed != NULL);
+ TEST_ASSERT(charsWritten == (int)wcslen(input) + 1);
+ TEST_ASSERT(!wcscmp(input, recomposed));
+ free(recomposed);
+ }
+
+ uriFreeQueryListW(queryList);
+ }
+
+ void testQueryList() {
+ testQueryListHelper(L"one=ONE&two=TWO", 2);
+ testQueryListHelper(L"one=ONE&two=&three=THREE", 3);
+ testQueryListHelper(L"one=ONE&two&three=THREE", 3);
+ testQueryListHelper(L"one=ONE", 1);
+ testQueryListHelper(L"one", 1);
+ testQueryListHelper(L"", 0);
+ }
+
+ void testQueryListPairHelper(const char * pair, const char * unescapedKey,
+ const char * unescapedValue, const char * fixed = NULL) {
+ int res;
+ UriQueryListA * queryList;
+ int itemCount;
+
+ res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair));
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(queryList != NULL);
+ TEST_ASSERT(itemCount == 1);
+ TEST_ASSERT(!strcmp(queryList->key, unescapedKey));
+ TEST_ASSERT(!strcmp(queryList->value, unescapedValue));
+
+ char * recomposed;
+ res = uriComposeQueryMallocA(&recomposed, queryList);
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(recomposed != NULL);
+ TEST_ASSERT(!strcmp(recomposed, (fixed != NULL) ? fixed : pair));
+ free(recomposed);
+ uriFreeQueryListA(queryList);
+ }
+
+ void testQueryListPair() {
+ testQueryListPairHelper("one+two+%26+three=%2B", "one two & three", "+");
+ testQueryListPairHelper("one=two=three", "one", "two=three", "one=two%3Dthree");
+ testQueryListPairHelper("one=two=three=four", "one", "two=three=four", "one=two%3Dthree%3Dfour");
+ }
+
+ void testQueryDissection_Bug3590761() {
+ int res;
+ UriQueryListA * queryList;
+ int itemCount;
+ const char * const pair = "q=hello&x=&y=";
+
+ res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair));
+ TEST_ASSERT(res == URI_SUCCESS);
+ TEST_ASSERT(queryList != NULL);
+ TEST_ASSERT(itemCount == 3);
+
+ TEST_ASSERT(!strcmp(queryList->key, "q"));
+ TEST_ASSERT(!strcmp(queryList->value, "hello"));
+
+ TEST_ASSERT(!strcmp(queryList->next->key, "x"));
+ TEST_ASSERT(!strcmp(queryList->next->value, ""));
+
+ TEST_ASSERT(!strcmp(queryList->next->next->key, "y"));
+ TEST_ASSERT(!strcmp(queryList->next->next->value, ""));
+
+ TEST_ASSERT(! queryList->next->next->next);
+
+ uriFreeQueryListA(queryList);
+ }
+
+ void testFreeCrash_Bug20080827() {
+ char const * const sourceUri = "abc";
+ char const * const baseUri = "http://www.example.org/";
+
+ int res;
+ UriParserStateA state;
+ UriUriA absoluteDest;
+ UriUriA relativeSource;
+ UriUriA absoluteBase;
+
+ state.uri = &relativeSource;
+ res = uriParseUriA(&state, sourceUri);
+ TEST_ASSERT(res == URI_SUCCESS);
+
+ state.uri = &absoluteBase;
+ res = uriParseUriA(&state, baseUri);
+ TEST_ASSERT(res == URI_SUCCESS);
+
+ res = uriRemoveBaseUriA(&absoluteDest, &relativeSource, &absoluteBase, URI_FALSE);
+ TEST_ASSERT(res == URI_ERROR_REMOVEBASE_REL_SOURCE);
+
+ uriFreeUriMembersA(&relativeSource);
+ uriFreeUriMembersA(&absoluteBase);
+ uriFreeUriMembersA(&absoluteDest); // Crashed here
+ }
+
+ void testParseInvalid_Bug16() {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+ const char * const input = "A>B";
+
+ const int res = uriParseUriA(&stateA, input);
+
+ TEST_ASSERT(res == URI_ERROR_SYNTAX);
+ TEST_ASSERT(stateA.errorPos == input + 1);
+ TEST_ASSERT(stateA.errorCode == URI_ERROR_SYNTAX); /* failed previously */
+
+ uriFreeUriMembersA(&uriA);
+ }
+};
+
+
+
+int main() {
+ Suite suite;
+ suite.add(auto_ptr<Suite>(new UriSuite()));
+ suite.add(auto_ptr<Suite>(new FourSuite()));
+ TextOutput output(TextOutput::Verbose);
+ return suite.run(output, false) ? 0 : 1;
+}