Skip to content

Commit

Permalink
Merge branch '4.4' into 5.3
Browse files Browse the repository at this point in the history
* 4.4:
  added missing translations for portuguese [#43726]
  [HttpClient][Mime] Add correct IDN flags for IDNA2008 compliance
  properly parse quoted strings tagged with !!str
  do not merge label classes into expanded choice labels
  [Serializer] PropertyNormalizer - return unique (i.e. filter duplicate ) attributes in extractAttributes function
  • Loading branch information
derrabus committed Nov 20, 2021
2 parents cc94e33 + 2c309e2 commit 226638a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
27 changes: 18 additions & 9 deletions Inline.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,11 @@ private static function dumpNull(int $flags): string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [])
public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], bool &$isQuoted = null)
{
if (\in_array($scalar[$i], ['"', "'"], true)) {
// quoted scalar
$isQuoted = true;
$output = self::parseQuotedScalar($scalar, $i);

if (null !== $delimiters) {
Expand All @@ -286,6 +287,8 @@ public static function parseScalar(string $scalar, int $flags = 0, array $delimi
}
} else {
// "normal" string
$isQuoted = false;

if (!$delimiters) {
$output = substr($scalar, $i);
$i += \strlen($output);
Expand All @@ -308,7 +311,7 @@ public static function parseScalar(string $scalar, int $flags = 0, array $delimi
}

if ($evaluate) {
$output = self::evaluateScalar($output, $flags, $references);
$output = self::evaluateScalar($output, $flags, $references, $isQuoted);
}
}

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

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

if (0 === strpos($scalar, '*')) {
Expand Down Expand Up @@ -598,7 +600,14 @@ private static function evaluateScalar(string $scalar, int $flags, array &$refer
case '!' === $scalar[0]:
switch (true) {
case 0 === strpos($scalar, '!!str '):
return (string) substr($scalar, 6);
$s = (string) substr($scalar, 6);

if (\in_array($s[0] ?? '', ['"', "'"], true)) {
$isQuotedString = true;
$s = self::parseQuotedScalar($s);
}

return $s;
case 0 === strpos($scalar, '! '):
return substr($scalar, 2);
case 0 === strpos($scalar, '!php/object'):
Expand Down
18 changes: 14 additions & 4 deletions Tests/InlineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -944,21 +944,31 @@ public function ideographicSpaceProvider(): array
];
}

public function testParseSingleQuotedTaggedString()
{
$this->assertSame('foo', Inline::parse("!!str 'foo'"));
}

public function testParseDoubleQuotedTaggedString()
{
$this->assertSame('foo', Inline::parse('!!str "foo"'));
}

public function testParseQuotedReferenceLikeStringsInMapping()
{
$yaml = <<<YAML
{foo: '&foo', bar: "&bar"}
{foo: '&foo', bar: "&bar", baz: !!str '&baz'}
YAML;

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

public function testParseQuotedReferenceLikeStringsInSequence()
{
$yaml = <<<YAML
['&foo', "&bar" ]
['&foo', "&bar", !!str '&baz']
YAML;

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

0 comments on commit 226638a

Please sign in to comment.