Skip to content

Commit cd26b16

Browse files
Streamline validation of patternProperties Regex (#653)
* Streamline validation of patternProperties Regex * Factorize pattern-to-regex * Use a safer delimiter in jsonPatternToPhpRegex()
1 parent f4f0c34 commit cd26b16

File tree

4 files changed

+17
-12
lines changed

4 files changed

+17
-12
lines changed

src/JsonSchema/Constraints/BaseConstraint.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,16 @@ public static function arrayToObjectRecursive($array)
153153

154154
return (object) json_decode($json);
155155
}
156+
157+
/**
158+
* Transform a JSON pattern into a PCRE regex
159+
*
160+
* @param string $pattern
161+
*
162+
* @return string
163+
*/
164+
public static function jsonPatternToPhpRegex($pattern)
165+
{
166+
return '~' . str_replace('~', '\\~', $pattern) . '~u';
167+
}
156168
}

src/JsonSchema/Constraints/FormatConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ protected function validateDateTime($datetime, $format)
197197

198198
protected function validateRegex($regex)
199199
{
200-
return false !== @preg_match('#' . str_replace('#', '\\#', $regex) . '#u', '');
200+
return false !== @preg_match(self::jsonPatternToPhpRegex($regex), '');
201201
}
202202

203203
protected function validateColor($color)

src/JsonSchema/Constraints/ObjectConstraint.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,17 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $prop
5454

5555
public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties)
5656
{
57-
$try = array('/', '#', '+', '~', '%');
5857
$matches = array();
5958
foreach ($patternProperties as $pregex => $schema) {
60-
$delimiter = '/';
61-
// Choose delimiter. Necessary for patterns like ^/ , otherwise you get error
62-
foreach ($try as $delimiter) {
63-
if (strpos($pregex, $delimiter) === false) { // safe to use
64-
break;
65-
}
66-
}
59+
$fullRegex = self::jsonPatternToPhpRegex($pregex);
6760

6861
// Validate the pattern before using it to test for matches
69-
if (@preg_match($delimiter . $pregex . $delimiter . 'u', '') === false) {
62+
if (@preg_match($fullRegex, '') === false) {
7063
$this->addError(ConstraintError::PREGEX_INVALID(), $path, array('pregex' => $pregex));
7164
continue;
7265
}
7366
foreach ($element as $i => $value) {
74-
if (preg_match($delimiter . $pregex . $delimiter . 'u', $i)) {
67+
if (preg_match($fullRegex, $i)) {
7568
$matches[] = $i;
7669
$this->checkUndefined($value, $schema ?: new \stdClass(), $path, $i, in_array($i, $this->appliedDefaults));
7770
}

src/JsonSchema/Constraints/StringConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =
4040
}
4141

4242
// Verify a regex pattern
43-
if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#u', $element)) {
43+
if (isset($schema->pattern) && !preg_match(self::jsonPatternToPhpRegex($schema->pattern), $element)) {
4444
$this->addError(ConstraintError::PATTERN(), $path, array(
4545
'pattern' => $schema->pattern,
4646
));

0 commit comments

Comments
 (0)