Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: symfony/yaml
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.3.9
Choose a base ref
...
head repository: symfony/yaml
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v4.3.10
Choose a head ref
  • 12 commits
  • 7 files changed
  • 7 contributors

Commits on Dec 4, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    1b78a23 View commit details

Commits on Dec 7, 2019

  1. Merge branch '3.4' into 4.3

    * 3.4:
      [Cache] fix memory leak when using PhpArrayAdapter
      fix parsing negative octal numbers
      [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass
      [Config] never try loading failed classes twice with ClassExistenceResource
    nicolas-grekas committed Dec 7, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    2375571 View commit details

Commits on Dec 10, 2019

  1. Copy the full SHA
    2d6c344 View commit details
  2. bug #34449 [Yaml] Implement multiline string as scalar block for tagg…

    …ed values (natepage)
    
    This PR was squashed before being merged into the 3.4 branch.
    
    Discussion
    ----------
    
    [Yaml] Implement multiline string as scalar block for tagged values
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 3.4
    | Bug fix?      | yes
    | New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
    | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
    | Tickets       | Fix #... <!-- prefix each issue number with "Fix #", if any -->
    | License       | MIT
    
    At the moment you can parse a tagged value defined as a scalar block. But you can't actually dump a multiline string as scalar block when using a tagged value.
    
    This PR implements the multiline string as scalar block for tagged values as well.
    
    Commits
    -------
    
    84241d4e62 [Yaml] Implement multiline string as scalar block for tagged values
    nicolas-grekas committed Dec 10, 2019
    Copy the full SHA
    44b1f27 View commit details
  3. Merge branch '3.4' into 4.3

    * 3.4:
      [Yaml] Implement multiline string as scalar block for tagged values
      [HttpFoundation] Use `Cache-Control: must-revalidate` only if explicit lifetime has been given
      [FrameworkBundle] Use UserInterface to @return in getUser method
      [CI] Replace php7.4snapshot with php7.4 in Travis configuration
      [ExpressionLanguage][Node][BinaryNode] Process division by zero
      forward caught exception
      [Validator][ConstraintValidator] Stop passing unnecessary timezone argument to \DateTime
      add tags before processing them
      [MonologBridge] Fix debug processor datetime type
    nicolas-grekas committed Dec 10, 2019
    Copy the full SHA
    13934d9 View commit details

Commits on Jan 1, 2020

  1. Update year in license files

    rosier committed Jan 1, 2020
    Copy the full SHA
    91f7f20 View commit details

Commits on Jan 4, 2020

  1. Copy the full SHA
    ef67314 View commit details
  2. Merge branch '3.4' into 4.3

    * 3.4:
      Update links to documentation
      [Validator] Add the missing translations for the Arabic (ar) locale
      ensure to expect no validation for the right reasons
      [PhpUnitBridge] Add test case for @expectedDeprecation annotation
      Update year in license files
      [Console][FormatterHelper] Use helper strlen statically and remove duplicated code
      Fix BC issue in phpDoc Reflection library
      [Translator] Performance improvement in MessageCatalogue and catalogue operations.
    nicolas-grekas committed Jan 4, 2020
    Copy the full SHA
    ba65ebe View commit details

Commits on Jan 13, 2020

  1. Copy the full SHA
    aa46bc2 View commit details

Commits on Jan 17, 2020

  1. Copy the full SHA
    12df25e View commit details

Commits on Jan 21, 2020

  1. Merge branch '3.4' into 4.3

    * 3.4:
      chown and chgrp should also accept int as owner and group
      Fix RememberMe with null password
      [Validator] Fix plurals for sr_Latn (Serbian language written in latin script) validation messages
      [PhpUnitBridge][SymfonyTestsListenerTrait] Remove some unneeded code
      fix PHP const mapping keys using the inline notation
      Fix that no-cache requires positive validation with the origin, even for fresh responses
    fabpot committed Jan 21, 2020
    Copy the full SHA
    5e3a474 View commit details
  2. bug #35364 [Yaml] Throw on unquoted exclamation mark (fancyweb)

    This PR was merged into the 4.3 branch.
    
    Discussion
    ----------
    
    [Yaml] Throw on unquoted exclamation mark
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 4.3
    | Bug fix?      | yes
    | New feature?  | no
    | Deprecations? |
    | Tickets       | symfony/symfony#35344
    | License       | MIT
    | Doc PR        | -
    
    Commits
    -------
    
    6b4147c991 [Yaml] Throw on unquoted exclamation mark
    nicolas-grekas committed Jan 21, 2020
    Copy the full SHA
    8e0a954 View commit details
Showing with 147 additions and 8 deletions.
  1. +14 −1 Dumper.php
  2. +14 −5 Inline.php
  3. +1 −1 LICENSE
  4. +1 −1 README.md
  5. +33 −0 Tests/DumperTest.php
  6. +2 −0 Tests/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml
  7. +82 −0 Tests/InlineTest.php
15 changes: 14 additions & 1 deletion Dumper.php
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
$blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';
$output .= sprintf("%s%s%s |%s\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator);

foreach (preg_split('/\n|\r\n/', $value) as $row) {
foreach (explode("\n", $value) as $row) {
$output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
}

@@ -80,6 +80,19 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
if ($value instanceof TaggedValue) {
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());

if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
// http://www.yaml.org/spec/1.2/spec.html#id2793979
$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
$output .= sprintf(" |%s\n", $blockIndentationIndicator);

foreach (explode("\n", $value->getValue()) as $row) {
$output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
}

continue;
}

if ($inline - 1 <= 0 || null === $value->getValue() || is_scalar($value->getValue())) {
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
} else {
19 changes: 14 additions & 5 deletions Inline.php
Original file line number Diff line number Diff line change
@@ -434,6 +434,11 @@ private static function parseMapping(string $mapping, int $flags, int &$i = 0, a
throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
}

if ('!php/const' === $key) {
$key .= ' '.self::parseScalar($mapping, $flags, [':'], $i, false, []);
$key = self::evaluateScalar($key, $flags);
}

if (false === $i = strpos($mapping, ':', $i)) {
break;
}
@@ -612,11 +617,11 @@ private static function evaluateScalar(string $scalar, int $flags, array $refere
// Optimize for returning strings.
// no break
case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]):
if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
$scalar = str_replace('_', '', (string) $scalar);
}

switch (true) {
case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar):
$scalar = str_replace('_', '', (string) $scalar);
// omitting the break / return as integers are handled in the next case
// no break
case ctype_digit($scalar):
$raw = $scalar;
$cast = (int) $scalar;
@@ -626,7 +631,7 @@ private static function evaluateScalar(string $scalar, int $flags, array $refere
$raw = $scalar;
$cast = (int) $scalar;

return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
return '0' == $scalar[1] ? -octdec(substr($scalar, 1)) : (($raw === (string) $cast) ? $cast : $raw);
case is_numeric($scalar):
case Parser::preg_match(self::getHexRegex(), $scalar):
$scalar = str_replace('_', '', $scalar);
@@ -669,6 +674,10 @@ private static function parseTag(string $value, int &$i, int $flags): ?string
$nextOffset = $i + $tagLength + 1;
$nextOffset += strspn($value, ' ', $nextOffset);

if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) {
throw new ParseException(sprintf('Using the unquoted scalar value "!" is not supported. You must quote it.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

// Is followed by a scalar and is a built-in tag
if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
// Manage in {@link self::evaluateScalar()}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ The Yaml component loads and dumps YAML files.
Resources
---------

* [Documentation](https://symfony.com/doc/current/components/yaml/index.html)
* [Documentation](https://symfony.com/doc/current/components/yaml.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
33 changes: 33 additions & 0 deletions Tests/DumperTest.php
Original file line number Diff line number Diff line change
@@ -487,6 +487,39 @@ public function testDumpingNotInlinedNullTaggedValue()
$this->assertSame($expected, $this->dumper->dump($data, 2));
}

public function testDumpingMultiLineStringAsScalarBlockTaggedValue()
{
$data = [
'foo' => new TaggedValue('bar', "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"),
];
$expected = <<<YAML
foo: !bar |
foo
line with trailing spaces:
bar
integer like line:
123456789
empty line:
baz
YAML;

$this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
}

public function testDumpingInlinedMultiLineIfRnBreakLineInTaggedValue()
{
$data = [
'data' => [
'foo' => new TaggedValue('bar', "foo\r\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"),
],
];

$this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
}

public function testDumpMultiLineStringAsScalarBlock()
{
$data = [
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
data:
foo: !bar "foo\r\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"
82 changes: 82 additions & 0 deletions Tests/InlineTest.php
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ public function getTestsForParsePhpConstants()
['!php/const PHP_INT_MAX', PHP_INT_MAX],
['[!php/const PHP_INT_MAX]', [PHP_INT_MAX]],
['{ foo: !php/const PHP_INT_MAX }', ['foo' => PHP_INT_MAX]],
['{ !php/const PHP_INT_MAX: foo }', [PHP_INT_MAX => 'foo']],
['!php/const NULL', null],
];
}
@@ -720,4 +721,85 @@ public function testUnfinishedInlineMap()
$this->expectExceptionMessage('Unexpected end of line, expected one of ",}" at line 1 (near "{abc: \'def\'").');
Inline::parse("{abc: 'def'");
}

/**
* @dataProvider getTestsForOctalNumbers
*/
public function testParseOctalNumbers($expected, $yaml)
{
self::assertSame($expected, Inline::parse($yaml));
}

public function getTestsForOctalNumbers()
{
return [
'positive octal number' => [28, '034'],
'negative octal number' => [-28, '-034'],
];
}

/**
* @dataProvider unquotedExclamationMarkThrowsProvider
*/
public function testUnquotedExclamationMarkThrows(string $value)
{
$this->expectException(ParseException::class);
$this->expectExceptionMessageRegExp('/^Using the unquoted scalar value "!" is not supported\. You must quote it at line 1 \(near "/');

Inline::parse($value);
}

public function unquotedExclamationMarkThrowsProvider()
{
return [
['!'],
['! '],
['! '],
[' ! '],
['[!]'],
['[! ]'],
['[! ]'],
['[!, "foo"]'],
['["foo", !, "ccc"]'],
['{foo: !}'],
['{foo: !}'],
['{foo: !, bar: "ccc"}'],
['{bar: "ccc", foo: ! }'],
['!]]]'],
['!}'],
['!,}foo,]'],
['! [!]'],
];
}

/**
* @dataProvider quotedExclamationMarkProvider
*/
public function testQuotedExclamationMark($expected, string $value)
{
$this->assertSame($expected, Inline::parse($value));
}

// This provider should stay consistent with unquotedExclamationMarkThrowsProvider
public function quotedExclamationMarkProvider()
{
return [
['!', '"!"'],
['! ', '"! "'],
[' !', '" !"'],
[' ! ', '" ! "'],
[['!'], '["!"]'],
[['! '], '["! "]'],
[['!', 'foo'], '["!", "foo"]'],
[['foo', '!', 'ccc'], '["foo", "!", "ccc"]'],
[['foo' => '!'], '{foo: "!"}'],
[['foo' => ' !'], '{foo: " !"}'],
[['foo' => '!', 'bar' => 'ccc'], '{foo: "!", bar: "ccc"}'],
[['bar' => 'ccc', 'foo' => '! '], '{bar: "ccc", foo: "! "}'],
['!]]]', '"!]]]"'],
['!}', '"!}"'],
['!,}foo,]', '"!,}foo,]"'],
[['!'], '! ["!"]'],
];
}
}