aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-12-24 20:08:44 +0000
committerDavid Robillard <d@drobilla.net>2011-12-24 20:08:44 +0000
commit4bce0925039b3791779149ec7bec69b5359b3e56 (patch)
tree6e8ecb344634cdc25f3e80099cd972a9f4fcf1c3
parent58dba94bf0cb121873476dff866d0cb08b0260a6 (diff)
downloadserd-4bce0925039b3791779149ec7bec69b5359b3e56.tar.gz
serd-4bce0925039b3791779149ec7bec69b5359b3e56.tar.bz2
serd-4bce0925039b3791779149ec7bec69b5359b3e56.zip
Improve URI resolution to cover most of the abnormal cases from RFC3986.
Improve test coverage of uri.c. git-svn-id: http://svn.drobilla.net/serd/trunk@266 490d8e77-9747-427b-9fa3-0b8f29cee8a0
-rw-r--r--ChangeLog1
-rw-r--r--src/uri.c41
-rw-r--r--tests/test-uri.out14
-rw-r--r--tests/test-uri.ttl24
4 files changed, 70 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index a3fab995..5c73cd2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,7 @@ serd (UNRELEASED) unstable; urgency=low
* Add serd_file_sink for the common case of writing to a FILE* stream.
* Escape ASCII control characters in output (e.g. fix problems with string
literals that start with a backspace)
+ * Improve URI resolution to cover most of the abnormal cases from RFC3986
-- David Robillard <d@drobilla.net> (UNRELEASED)
diff --git a/src/uri.c b/src/uri.c
index 24dd91d1..cd89d818 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -287,7 +287,7 @@ serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream)
WRITE("//", 2);
WRITE(uri->authority.buf, uri->authority.len);
}
- if (uri->path_base.len) {
+ if (uri->path_base.len || uri->path.len) {
if (!uri->path.buf && (uri->fragment.buf || uri->query.buf)) {
WRITE_COMPONENT("", uri->path_base, "");
} else if (uri->path.buf) {
@@ -307,24 +307,47 @@ serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream)
begin += 2; // Chop leading "./"
break;
case '.':
- ++up;
switch (begin[2]) {
+ case '\0':
+ ++up;
+ begin += 2; // Chop input ".."
+ done = true;
+ break;
case '/':
- begin += 3; // Chop lading "../"
+ ++up;
+ begin += 3; // Chop leading "../"
break;
default:
- begin += 2; // Chop leading ".."
+ done = true;
+ break;
}
break;
+ case '\0':
+ ++begin; // Chop input "." (and fall-through)
default:
- ++begin; // Chop leading "."
+ done = true;
+ break;
}
break;
case '/':
- if (begin[1] == '/') {
- ++begin; // Replace leading "//" with "/"
- break;
- } // else fall through
+ switch (begin[1]) {
+ case '.':
+ switch (begin[2]) {
+ case '/':
+ begin += 2; // Leading "/./" => "/"
+ break;
+ case '.':
+ switch (begin[3]) {
+ case '/':
+ ++up;
+ begin += 3; // Leading "/../" => "/"
+ }
+ break;
+ default:
+ done = true;
+ break;
+ }
+ } // else fall through
default:
done = true; // Finished chopping dot components
}
diff --git a/tests/test-uri.out b/tests/test-uri.out
index 1517d2e4..8c984f79 100644
--- a/tests/test-uri.out
+++ b/tests/test-uri.out
@@ -21,6 +21,20 @@
<http://a/> <http://www.w3.org/2002/07/owl#sameAs> <http://a/> .
<http://a/> <http://www.w3.org/2002/07/owl#sameAs> <http://a/> .
<http://a/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/g> .
+<http://a/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/g> .
+<http://a/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/g> .
+<http://a/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/g> .
+<http://a/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/g> .
+<http://a/b/c/g.> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g.> .
+<http://a/b/c/.g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/.g> .
+<http://a/b/c/g..> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g..> .
+<http://a/b/c/..g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/..g> .
+<http://a/b/g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/g> .
+<http://a/b/c/g?y/./x> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g?y/./x> .
+<http://a/b/c/g?y/../x> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g?y/../x> .
+<http://a/b/c/g#s/./x> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g#s/./x> .
+<http://a/b/c/g#s/../x> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/g#s/../x> .
+<http://a/.g> <http://www.w3.org/2002/07/owl#sameAs> <http://a/.g> .
<http://A?aquery> <http://www.w3.org/2002/07/owl#sameAs> <http://A?aquery> .
<http://A#afragment> <http://www.w3.org/2002/07/owl#sameAs> <http://A#afragment> .
<http://a/b/c/d;p?aquery> <http://www.w3.org/2002/07/owl#sameAs> <http://a/b/c/d;p?aquery> .
diff --git a/tests/test-uri.ttl b/tests/test-uri.ttl
index 22799360..cbc699ab 100644
--- a/tests/test-uri.ttl
+++ b/tests/test-uri.ttl
@@ -29,7 +29,29 @@
<../../> owl:sameAs <http://a/> .
<../../g> owl:sameAs <http://a/g> .
+# 5.4.2. Abnormal Examples
+<../../../g> owl:sameAs <http://a/g> .
+<../../../../g> owl:sameAs <http://a/g> .
+</./g> owl:sameAs <http://a/g> .
+</../g> owl:sameAs <http://a/g> .
+<g.> owl:sameAs <http://a/b/c/g.> .
+<.g> owl:sameAs <http://a/b/c/.g> .
+<g..> owl:sameAs <http://a/b/c/g..> .
+<..g> owl:sameAs <http://a/b/c/..g> .
+<./../g> owl:sameAs <http://a/b/g> .
+# Serd only resolves the leading components
+#<./g/.> owl:sameAs <http://a/b/c/g/> .
+#<g/./h> owl:sameAs <http://a/b/c/g/h> .
+#<g/../h> owl:sameAs <http://a/b/c/h> .
+#<g;x=1/./y> owl:sameAs <http://a/b/c/g;x=1/y> .
+#<g;x=1/../y> owl:sameAs <http://a/b/c/y> .
+<g?y/./x> owl:sameAs <http://a/b/c/g?y/./x> .
+<g?y/../x> owl:sameAs <http://a/b/c/g?y/../x> .
+<g#s/./x> owl:sameAs <http://a/b/c/g#s/./x> .
+<g#s/../x> owl:sameAs <http://a/b/c/g#s/../x> .
+
# Additional tests for Serd
+</.g> owl:sameAs <http://a/.g> .
<http://A?aquery> owl:sameAs <http://A?aquery> .
<http://A#afragment> owl:sameAs <http://A#afragment> .
<?aquery> owl:sameAs <http://a/b/c/d;p?aquery> .
@@ -41,4 +63,4 @@
@base <http://C#cfragment> .
-</bar> owl:sameAs <http://C/bar> .
+</bar> owl:sameAs <http://C/bar> .