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

Skip to content

Commit 38f3c12

Browse files
committed
bug #44131 [Yaml] properly parse quoted strings tagged with !!str (xabbuh)
This PR was merged into the 4.4 branch. Discussion ---------- [Yaml] properly parse quoted strings tagged with !!str | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #44019 | License | MIT | Doc PR | Commits ------- 1e7e7e0 properly parse quoted strings tagged with !!str
2 parents eee7b80 + 1e7e7e0 commit 38f3c12

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

src/Symfony/Component/Yaml/Inline.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,11 @@ private static function dumpNull(int $flags): string
269269
*
270270
* @throws ParseException When malformed inline YAML string is parsed
271271
*/
272-
public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [])
272+
public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], bool &$isQuoted = null)
273273
{
274274
if (\in_array($scalar[$i], ['"', "'"])) {
275275
// quoted scalar
276+
$isQuoted = true;
276277
$output = self::parseQuotedScalar($scalar, $i);
277278

278279
if (null !== $delimiters) {
@@ -286,6 +287,8 @@ public static function parseScalar(string $scalar, int $flags = 0, array $delimi
286287
}
287288
} else {
288289
// "normal" string
290+
$isQuoted = false;
291+
289292
if (!$delimiters) {
290293
$output = substr($scalar, $i);
291294
$i += \strlen($output);
@@ -308,7 +311,7 @@ public static function parseScalar(string $scalar, int $flags = 0, array $delimi
308311
}
309312

310313
if ($evaluate) {
311-
$output = self::evaluateScalar($output, $flags, $references);
314+
$output = self::evaluateScalar($output, $flags, $references, $isQuoted);
312315
}
313316
}
314317

@@ -320,7 +323,7 @@ public static function parseScalar(string $scalar, int $flags = 0, array $delimi
320323
*
321324
* @throws ParseException When malformed inline YAML string is parsed
322325
*/
323-
private static function parseQuotedScalar(string $scalar, int &$i): string
326+
private static function parseQuotedScalar(string $scalar, int &$i = 0): string
324327
{
325328
if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
326329
throw new ParseException(sprintf('Malformed inline YAML string: "%s".', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
@@ -373,8 +376,7 @@ private static function parseSequence(string $sequence, int $flags, int &$i = 0,
373376
$value = self::parseMapping($sequence, $flags, $i, $references);
374377
break;
375378
default:
376-
$isQuoted = \in_array($sequence[$i], ['"', "'"]);
377-
$value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references);
379+
$value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references, $isQuoted);
378380

379381
// the value can be an array if a reference has been resolved to an array var
380382
if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) {
@@ -521,8 +523,7 @@ private static function parseMapping(string $mapping, int $flags, int &$i = 0, a
521523
}
522524
break;
523525
default:
524-
$isValueQuoted = \in_array($mapping[$i], ['"', "'"]);
525-
$value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references);
526+
$value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references, $isValueQuoted);
526527
// Spec: Keys MUST be unique; first one wins.
527528
// Parser cannot abort this mapping earlier, since lines
528529
// are processed sequentially.
@@ -561,8 +562,9 @@ private static function parseMapping(string $mapping, int $flags, int &$i = 0, a
561562
*
562563
* @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
563564
*/
564-
private static function evaluateScalar(string $scalar, int $flags, array &$references = [])
565+
private static function evaluateScalar(string $scalar, int $flags, array &$references = [], bool &$isQuotedString = null)
565566
{
567+
$isQuotedString = false;
566568
$scalar = trim($scalar);
567569
$scalarLower = strtolower($scalar);
568570

@@ -597,7 +599,14 @@ private static function evaluateScalar(string $scalar, int $flags, array &$refer
597599
case '!' === $scalar[0]:
598600
switch (true) {
599601
case 0 === strpos($scalar, '!!str '):
600-
return (string) substr($scalar, 6);
602+
$s = (string) substr($scalar, 6);
603+
604+
if (\in_array($s[0] ?? '', ['"', "'"], true)) {
605+
$isQuotedString = true;
606+
$s = self::parseQuotedScalar($s);
607+
}
608+
609+
return $s;
601610
case 0 === strpos($scalar, '! '):
602611
return substr($scalar, 2);
603612
case 0 === strpos($scalar, '!php/object'):

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -906,21 +906,31 @@ public function ideographicSpaceProvider(): array
906906
];
907907
}
908908

909+
public function testParseSingleQuotedTaggedString()
910+
{
911+
$this->assertSame('foo', Inline::parse("!!str 'foo'"));
912+
}
913+
914+
public function testParseDoubleQuotedTaggedString()
915+
{
916+
$this->assertSame('foo', Inline::parse('!!str "foo"'));
917+
}
918+
909919
public function testParseQuotedReferenceLikeStringsInMapping()
910920
{
911921
$yaml = <<<YAML
912-
{foo: '&foo', bar: "&bar"}
922+
{foo: '&foo', bar: "&bar", baz: !!str '&baz'}
913923
YAML;
914924

915-
$this->assertSame(['foo' => '&foo', 'bar' => '&bar'], Inline::parse($yaml));
925+
$this->assertSame(['foo' => '&foo', 'bar' => '&bar', 'baz' => '&baz'], Inline::parse($yaml));
916926
}
917927

918928
public function testParseQuotedReferenceLikeStringsInSequence()
919929
{
920930
$yaml = <<<YAML
921-
['&foo', "&bar" ]
931+
['&foo', "&bar", !!str '&baz']
922932
YAML;
923933

924-
$this->assertSame(['&foo', '&bar'], Inline::parse($yaml));
934+
$this->assertSame(['&foo', '&bar', '&baz'], Inline::parse($yaml));
925935
}
926936
}

0 commit comments

Comments
 (0)