aboutsummaryrefslogtreecommitdiffstats
path: root/src/uri.c
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 /src/uri.c
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
Diffstat (limited to 'src/uri.c')
-rw-r--r--src/uri.c41
1 files changed, 32 insertions, 9 deletions
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
}