diff --git a/src/JsonPointer.php b/src/JsonPointer.php index 8e6a07fe..5f06ea5a 100644 --- a/src/JsonPointer.php +++ b/src/JsonPointer.php @@ -38,7 +38,7 @@ private function __construct(ReferenceToken ...$referenceTokens) */ public static function fromJsonString(string $value): self { - if (1 !== \preg_match('/^(\/(?P((?P[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])|(?P~[01]))*))*$/u', $value)) { + if (1 !== \preg_match(Pattern::JSON_POINTER_JSON_STRING, $value)) { throw Exception\InvalidJsonPointer::fromJsonString($value); } diff --git a/src/Pattern.php b/src/Pattern.php new file mode 100644 index 00000000..3ebd79ce --- /dev/null +++ b/src/Pattern.php @@ -0,0 +1,30 @@ +(\/(?P((?P[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])|(?P~[01]))*))*)$/u'; + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6901#section-3 + */ + public const REFERENCE_TOKEN = '/^(?P((?P[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])|(?P~[01]))*)$/u'; +} diff --git a/src/ReferenceToken.php b/src/ReferenceToken.php index b3541152..199de6bf 100644 --- a/src/ReferenceToken.php +++ b/src/ReferenceToken.php @@ -46,7 +46,7 @@ public static function fromInt(int $value): self */ public static function fromJsonString(string $value): self { - if (1 !== \preg_match('/^(?P((?P[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])|(?P~[01]))*)$/u', $value)) { + if (1 !== \preg_match(Pattern::REFERENCE_TOKEN, $value)) { throw Exception\InvalidReferenceToken::fromJsonString($value); } diff --git a/test/Unit/PatternTest.php b/test/Unit/PatternTest.php new file mode 100644 index 00000000..2c08462b --- /dev/null +++ b/test/Unit/PatternTest.php @@ -0,0 +1,54 @@ +(\\/{$referenceToken})*)$/u"; + + self::assertSame($expected, Pattern::JSON_POINTER_JSON_STRING); + } + + public function testReferenceTokenEqualsPattern(): void + { + $referenceToken = self::referenceToken(); + + $expected = "/^{$referenceToken}$/u"; + + self::assertSame($expected, Pattern::REFERENCE_TOKEN); + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6901#section-3 + */ + private static function referenceToken(): string + { + $unescaped = '(?P[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])'; + $escaped = '(?P~[01])'; + + return "(?P({$unescaped}|{$escaped})*)"; + } +}