From 899d102dc3c0df6dd6b5b6cef004b09b1ebb47e3 Mon Sep 17 00:00:00 2001 From: Konrad Abicht Date: Tue, 29 Aug 2023 14:17:06 +0200 Subject: [PATCH] ported PR https://github.com/easyrdf/easyrdf/pull/404 (#35) Author: @nevali Title: Prevent RdfNamespace::splitUri() from generating prefix:#fragment qnames Quote from original PR: > it's possible to coax EasyRdf\RdfNamespace::splitUri() into generating a qname in the form prefix:#fragment, which is not valid, for example by defining a namespace as https://www.example.com/foo/ and then referring to https://www.example.com/foo/#bar; this fix prevents that --- lib/RdfNamespace.php | 6 +++--- tests/EasyRdf/RdfNamespaceTest.php | 12 ++++++++++++ tests/EasyRdf/Serialiser/TurtleTest.php | 17 +++++++++++++++-- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/RdfNamespace.php b/lib/RdfNamespace.php index b264e52d..7fdd7c4c 100644 --- a/lib/RdfNamespace.php +++ b/lib/RdfNamespace.php @@ -346,8 +346,8 @@ public static function splitUri($uri, $createNamespace = false) $local_part = substr($uri, \strlen($long)); - if (str_contains($local_part, '/')) { - // we can't have '/' in local part + // we can't have '/' or '#' in local part + if (str_contains($local_part, '/') || str_contains($local_part, '#')) { continue; } @@ -394,7 +394,7 @@ public static function prefixOfUri($uri) * @param string $uri The full URI (eg 'http://xmlns.com/foaf/0.1/name') * @param bool $createNamespace If true, a new namespace will be created * - * @return string|void The shortened URI (eg 'foaf:name') or null + * @return string|void The shortened URI (eg 'foaf:name') or void */ public static function shorten($uri, $createNamespace = false) { diff --git a/tests/EasyRdf/RdfNamespaceTest.php b/tests/EasyRdf/RdfNamespaceTest.php index f33df802..ffd8c0ae 100644 --- a/tests/EasyRdf/RdfNamespaceTest.php +++ b/tests/EasyRdf/RdfNamespaceTest.php @@ -683,4 +683,16 @@ public function testShortNamespace() RdfNamespace::shorten('http://example.org/bar/baz') ); } + + /** + * URIs with fragments can only be shortened if the '#' character + * is part of the prefix. `prefix:[...]#fragment` is not a valid result + */ + public function testNoShortFragment() + { + RdfNamespace::set('ex', 'http://example.org/'); + + $this->assertNull(RdfNamespace::shorten('http://example.org/foo#bar')); + $this->assertNull(RdfNamespace::shorten('http://example.org/#quack')); + } } diff --git a/tests/EasyRdf/Serialiser/TurtleTest.php b/tests/EasyRdf/Serialiser/TurtleTest.php index 5bb46bb7..60c351b5 100644 --- a/tests/EasyRdf/Serialiser/TurtleTest.php +++ b/tests/EasyRdf/Serialiser/TurtleTest.php @@ -653,13 +653,26 @@ public function testSerialiseUnknownDatatype() public function testSerialiseShortenableResource() { RdfNamespace::set('example', 'http://example.com/'); - $joe = $this->graph->resource('http://example.com/joe#me'); + $joe = $this->graph->resource('http://example.com/joe'); $joe->add('rdf:type', 'foaf:Person'); $turtle = $this->serialiser->serialise($this->graph, 'turtle'); $this->assertSame( "@prefix example: .\n\n". - "example:joe#me a \"foaf:Person\" .\n", + "example:joe a \"foaf:Person\" .\n", + $turtle + ); + } + + public function testSerialiseUnshortenableResource() + { + RdfNamespace::set('example', 'http://example.com/'); + $joe = $this->graph->resource('http://example.com/joe#me'); + $joe->add('rdf:type', 'foaf:Person'); + + $turtle = $this->serialiser->serialise($this->graph, 'turtle'); + $this->assertSame( + " a \"foaf:Person\" .\n", $turtle ); }