Treat COIDs with query or fragment as invalid

This commit is contained in:
lukas committed 2026-10-18 16:33:13 +00:00
1 parent b9141326b1
commit b3c810473f
2 files changed
+45 -6

No files matched your search

+11 -6
View File
@@ -36,7 +36,11 @@ class COIDParser {
(strtolower(substr($coidString, 0, 7)) == 'coid://') ? $coidString : 'coid://'.$coidString (strtolower(substr($coidString, 0, 7)) == 'coid://') ? $coidString : 'coid://'.$coidString
); );
// Normalize scheme and host segments to lower case // Normalize scheme and host segments to lower case
return new IRI('coid://'.strtolower($coidPre->getHost()).$coidPre->getPath()); // Keep query and fragment (will currently make those IRIs invalid as COIDs
// but may be used in future)
return new IRI('coid://'.strtolower($coidPre->getHost()).$coidPre->getPath()
.($coidPre->getQuery() !== null ? '?'.$coidPre->getQuery() : '')
.($coidPre->getFragment() !== null ? '#'.$coidPre->getFragment() : ''));
} }
/** /**
@@ -47,7 +51,8 @@ class COIDParser {
*/ */
public static function getType(IRI $coid) : ?int { public static function getType(IRI $coid) : ?int {
if ($coid->getScheme()!='coid' || $coid->getHost()=='' if ($coid->getScheme()!='coid' || $coid->getHost()==''
|| preg_match(self::REGEX_HOSTNAME, $coid->getHost()) != 1) || preg_match(self::REGEX_HOSTNAME, $coid->getHost()) !== 1
|| $coid->getQuery() !== null || $coid->getFragment() !== null)
return self::COID_INVALID; return self::COID_INVALID;
if ($coid->getPath()=='' || $coid->getPath()=='/') if ($coid->getPath()=='' || $coid->getPath()=='/')
@@ -55,10 +60,10 @@ class COIDParser {
$segments = explode('/', $coid->getPath()); $segments = explode('/', $coid->getPath());
switch (count($segments)) { switch (count($segments)) {
case 2: case 2:
return (preg_match(self::REGEX_SEGMENT, $segments[1]) == 1) return (preg_match(self::REGEX_SEGMENT, $segments[1]) == 1)
? self::COID_UNVERSIONED ? self::COID_UNVERSIONED
: self::COID_INVALID; : self::COID_INVALID;
case 3: case 3:
if (preg_match(self::REGEX_SEGMENT, $segments[1]) != 1) if (preg_match(self::REGEX_SEGMENT, $segments[1]) != 1)
return self::COID_INVALID; return self::COID_INVALID;
+34
View File
@@ -50,6 +50,24 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
$coid = new IRI('coid://exAMPle.CoM'); $coid = new IRI('coid://exAMPle.CoM');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com#hash=something');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com?query=something');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.0?query=something');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example#hash');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com?');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com#');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
} }
public function testUnversionedCOID() { public function testUnversionedCOID() {
@@ -145,4 +163,20 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
$this->assertFalse($coid1->equals($coid4)); $this->assertFalse($coid1->equals($coid4));
} }
public function testQueryAndFragmentFromString() {
$coid = COIDParser::fromString('example.com/Example?query=something');
$this->assertEquals('coid://example.com/Example?query=something', (string)$coid);
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = COIDParser::fromString('COID://Example.com/Example/1.0#hash');
$this->assertEquals('coid://example.com/Example/1.0#hash', (string)$coid);
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = COIDParser::fromString('example.com?');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = COIDParser::fromString('example.com#');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
} }