From 3267bb312f50746202226d29cc196bb47941e4d5 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 30 Jul 2018 19:30:34 +0200 Subject: Fix resolving some URIs against base URIs with no trailing slash --- NEWS | 3 ++- src/uri.c | 14 ++++++++++ tests/good/manifest.nt | 54 ++++++++++++++++++++----------------- tests/good/manifest.ttl | 7 +++++ tests/good/test-empty-path-base.nt | 1 + tests/good/test-empty-path-base.ttl | 3 +++ 6 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 tests/good/test-empty-path-base.nt create mode 100644 tests/good/test-empty-path-base.ttl diff --git a/NEWS b/NEWS index b4a0bbd1..90ae965f 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ serd (0.30.1) unstable; * Fix GCC 4 build + * Fix resolving some URIs against base URIs with no trailing slash - -- David Robillard Mon, 23 Jul 2018 23:14:40 +0200 + -- David Robillard Mon, 30 Jul 2018 19:28:32 +0200 serd (0.30.0) stable; diff --git a/src/uri.c b/src/uri.c index 8b3c3c3a..0f0b3ca6 100644 --- a/src/uri.c +++ b/src/uri.c @@ -452,6 +452,14 @@ write_rel_path(SerdSink sink, return len += write_path_tail(sink, stream, uri, last_shared_sep + 1); } +static uint8_t +serd_uri_path_starts_without_slash(const SerdURI* uri) +{ + return ((uri->path_base.len || uri->path.len) && + ((!uri->path_base.len || uri->path_base.buf[0] != '/') && + (!uri->path.len || uri->path.buf[0] != '/'))); +} + /// See http://tools.ietf.org/html/rfc3986#section-5.3 size_t serd_uri_serialise_relative(const SerdURI* uri, @@ -475,6 +483,12 @@ serd_uri_serialise_relative(const SerdURI* uri, if (uri->authority.buf) { len += sink("//", 2, stream); len += sink(uri->authority.buf, uri->authority.len, stream); + if (uri->authority.buf[uri->authority.len - 1] != '/' && + serd_uri_path_starts_without_slash(uri)) { + // Special case: ensure path begins with a slash + // https://tools.ietf.org/html/rfc3986#section-3.2 + len += sink("/", 1, stream); + } } len += write_path_tail(sink, stream, uri, 0); } diff --git a/tests/good/manifest.nt b/tests/good/manifest.nt index ed9bcee0..553c193e 100644 --- a/tests/good/manifest.nt +++ b/tests/good/manifest.nt @@ -43,52 +43,54 @@ _:b20 _:b21 . _:b21 . _:b21 _:b22 . -_:b22 . +_:b22 . _:b22 _:b23 . -_:b23 . +_:b23 . _:b23 _:b24 . -_:b24 . +_:b24 . _:b24 _:b25 . -_:b25 . +_:b25 . _:b25 _:b26 . -_:b26 . +_:b26 . _:b26 _:b27 . -_:b27 . +_:b27 . _:b27 _:b28 . -_:b28 . +_:b28 . _:b28 _:b29 . -_:b29 . +_:b29 . _:b29 _:b30 . -_:b30 . +_:b30 . _:b30 _:b31 . -_:b31 . +_:b31 . _:b31 _:b32 . -_:b32 . +_:b32 . _:b32 _:b33 . -_:b33 . +_:b33 . _:b33 _:b34 . -_:b34 . +_:b34 . _:b34 _:b35 . -_:b35 . +_:b35 . _:b35 _:b36 . -_:b36 . +_:b36 . _:b36 _:b37 . -_:b37 . +_:b37 . _:b37 _:b38 . -_:b38 . +_:b38 . _:b38 _:b39 . -_:b39 . +_:b39 . _:b39 _:b40 . -_:b40 . +_:b40 . _:b40 _:b41 . -_:b41 . +_:b41 . _:b41 _:b42 . -_:b42 . +_:b42 . _:b42 _:b43 . -_:b43 . +_:b43 . _:b43 _:b44 . -_:b44 . -_:b44 . +_:b44 . +_:b44 _:b45 . +_:b45 . +_:b45 . . "test-14" . . @@ -172,6 +174,10 @@ _:b44 "test-digit-start-pname" . . . + . + "test-empty-path-base" . + . + . . "test-empty" . . diff --git a/tests/good/manifest.ttl b/tests/good/manifest.ttl index 8bca9738..72012bbc 100644 --- a/tests/good/manifest.ttl +++ b/tests/good/manifest.ttl @@ -28,6 +28,7 @@ <#test-cr> <#test-delete> <#test-digit-start-pname> + <#test-empty-path-base> <#test-empty> <#test-eof-at-page-end> <#test-escapes> @@ -178,6 +179,12 @@ mf:action ; mf:result . +<#test-empty-path-base> + rdf:type rdft:TestTurtleEval ; + mf:name "test-empty-path-base" ; + mf:action ; + mf:result . + <#test-empty> rdf:type rdft:TestTurtleEval ; mf:name "test-empty" ; diff --git a/tests/good/test-empty-path-base.nt b/tests/good/test-empty-path-base.nt new file mode 100644 index 00000000..9ad50617 --- /dev/null +++ b/tests/good/test-empty-path-base.nt @@ -0,0 +1 @@ + . diff --git a/tests/good/test-empty-path-base.ttl b/tests/good/test-empty-path-base.ttl new file mode 100644 index 00000000..a5cdd1e0 --- /dev/null +++ b/tests/good/test-empty-path-base.ttl @@ -0,0 +1,3 @@ +@base . + + a . -- cgit v1.2.1