Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[JsonPath] Improve escape sequence validation in name selector #60802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 7.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/Symfony/Component/JsonPath/JsonPathUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\JsonPath;

use Symfony\Component\JsonPath\Exception\InvalidArgumentException;
use Symfony\Component\JsonPath\Exception\JsonCrawlerException;
use Symfony\Component\JsonPath\Tokenizer\JsonPathToken;
use Symfony\Component\JsonPath\Tokenizer\TokenType;
use Symfony\Component\JsonStreamer\Read\Splitter;
Expand Down Expand Up @@ -86,8 +87,13 @@ public static function findSmallestDeserializableStringAndPath(array $tokens, mi
];
}

/**
* @throws JsonCrawlerException When an invalid Unicode escape sequence occurs
*/
public static function unescapeString(string $str, string $quoteChar): string
{
self::validateEscapeSequences($str, $quoteChar);

if ('"' === $quoteChar) {
// try JSON decoding first for unicode sequences
$jsonStr = '"'.$str.'"';
Expand All @@ -108,7 +114,7 @@ public static function unescapeString(string $str, string $quoteChar): string
"'" => "'",
'\\' => '\\',
'/' => '/',
'b' => "\b",
'b' => "\x08",
'f' => "\f",
'n' => "\n",
'r' => "\r",
Expand Down Expand Up @@ -227,4 +233,24 @@ public static function parseCommaSeparatedValues(string $expr): array

return $parts;
}

private static function validateEscapeSequences(string $str, string $quoteChar): void
{
$i = -1;
while (null !== $char = $str[++$i] ?? null) {
if ('\\' !== $char || !isset($str[$i + 1])) {
continue;
}

if (!\in_array($next = $str[$i + 1], [$quoteChar, '\\', '/', 'b', 'f', 'n', 'r', 't', 'u'], true)) {
throw new JsonCrawlerException('', \sprintf('Invalid escape sequence "\\%s" in %s-quoted string', $next, "'" === $quoteChar ? 'single' : 'double'));
}

if ('u' === $next && (!isset($str[$i + 5]) || !ctype_xdigit(substr($str, $i + 2, 4)))) {
throw new JsonCrawlerException('', 'Invalid unicode escape sequence');
}

++$i;
}
}
}
31 changes: 2 additions & 29 deletions src/Symfony/Component/JsonPath/Tests/JsonCrawlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function testEscapedDoubleQuotesInFieldName()
{"a": {"b\\"c": 42}}
JSON);

$result = $crawler->find("$['a']['b\\\"c']");
$result = $crawler->find('$["a"]["b\"c"]');

$this->assertSame(42, $result[0]);
}
Expand Down Expand Up @@ -641,10 +641,6 @@ public static function provideSingleQuotedStringProvider(): array
"$['\\u65e5\\u672c']",
['Japan'],
],
[
"$['quote\"here']",
['with quote'],
],
[
"$['M\\u00fcller']",
[],
Expand All @@ -658,7 +654,7 @@ public static function provideSingleQuotedStringProvider(): array
['with tab'],
],
[
"$['quote\\\"here']",
"$['quote\"here']",
['with quote'],
],
[
Expand Down Expand Up @@ -725,29 +721,6 @@ public static function provideFilterWithUnicodeProvider(): array
];
}

/**
* @dataProvider provideInvalidUnicodeSequenceProvider
*/
public function testInvalidUnicodeSequencesAreProcessedAsLiterals(string $jsonPath)
{
$this->assertIsArray(self::getUnicodeDocumentCrawler()->find($jsonPath), 'invalid unicode sequence should be treated as literal and not throw');
}

public static function provideInvalidUnicodeSequenceProvider(): array
{
return [
[
'$["test\uZZZZ"]',
],
[
'$["test\u123"]',
],
[
'$["test\u"]',
],
];
}

/**
* @dataProvider provideComplexUnicodePath
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,30 +148,6 @@ final class JsonPathComplianceTestSuiteTest extends TestCase
'index selector, leading 0',
'index selector, -0',
'index selector, leading -0',
'name selector, double quotes, escaped line feed',
'name selector, double quotes, invalid escaped single quote',
'name selector, double quotes, question mark escape',
'name selector, double quotes, bell escape',
'name selector, double quotes, vertical tab escape',
'name selector, double quotes, 0 escape',
'name selector, double quotes, x escape',
'name selector, double quotes, n escape',
'name selector, double quotes, unicode escape no hex',
'name selector, double quotes, unicode escape too few hex',
'name selector, double quotes, unicode escape upper u',
'name selector, double quotes, unicode escape upper u long',
'name selector, double quotes, unicode escape plus',
'name selector, double quotes, unicode escape brackets',
'name selector, double quotes, unicode escape brackets long',
'name selector, double quotes, single high surrogate',
'name selector, double quotes, single low surrogate',
'name selector, double quotes, high high surrogate',
'name selector, double quotes, low low surrogate',
'name selector, double quotes, supplementary surrogate',
'name selector, double quotes, surrogate incomplete low',
'name selector, single quotes, escaped backspace',
'name selector, single quotes, escaped line feed',
'name selector, single quotes, invalid escaped double quote',
'slice selector, excessively large from value with negative step',
'slice selector, step, min exact - 1',
'slice selector, step, max exact + 1',
Expand Down
Loading