8000 [Yaml] Improve YAML boolean escaping by petert82 · Pull Request #13262 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
[Yaml] Improve YAML boolean escaping
- Moves dumping single-quoting logic into Yaml\Escaper
- Ensures that PHP values which would be interpreted as booleans in
  older versions of the YAML spec are escaped with single quotes when
  dumped by the Dumper.
  • Loading branch information
petert82 committed Jan 5, 2015
commit 3760e67cb234b940abddf5d348eb6e62411d62eb
26 changes: 25 additions & 1 deletion src/Symfony/Component/Yaml/Escaper.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static function escapeWithDoubleQuotes($value)
*/
public static function requiresSingleQuoting($value)
{
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
return self::containsCharRequiresSingleQuoting($value) || self::isValueRequiresSingleQuoting($value);
}

/**
Expand All @@ -86,4 +86,28 @@ public static function escapeWithSingleQuotes($value)
{
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
}

/**
* Determines if a PHP value contains any single characters that would cause
* the value to require single quoting in YAML.
*
* @param string $value A PHP value
* @return bool True if the value would require single quotes.
*/
private static function containsCharRequiresSingleQuoting($value)
{
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
}

/**
* Determines if a PHP value is entirely composed of a value that would
* require require single quoting in YAML.
*
* @param string $value A PHP value
* @return bool True if the value would require single quotes.
*/
private static function isValueRequiresSingleQuoting($value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesValueRequireSingleQuoting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm wondering if we really need those 2 private methods. What about inlining them with the right comments instead? Especially as they can be called quite a lot.

{
return in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to myself and others: even if we do not support 'y', 'n', ... as valid Booleans, it does not hurt to escape them here for interoperability.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding it as a comment to avoid removing it by mistake in the future

}
}
4 changes: 1 addition & 3 deletions src/Symfony/Component/Yaml/Inline.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,10 @@ public static function dump($value, $exceptionOnInvalidType = false, $objectSupp
case Escaper::requiresDoubleQuoting($value):
return Escaper::escapeWithDoubleQuotes($value);
case Escaper::requiresSingleQuoting($value):
case preg_match(self::getTimestampRegex(), $value):
return Escaper::escapeWithSingleQuotes($value);
case '' == $value:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest moving this fast comparison before the heavier regex checks

return "''";
case preg_match(self::getTimestampRegex(), $value):
case in_array(strtolower($value), array('null', '~', 'true', 'false')):
return "'$value'";
default:
return $value;
}
Expand Down
16 changes: 16 additions & 0 deletions src/Symfony/Component/Yaml/Tests/InlineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ protected function getTestsForParse()
"'#cfcfcf'" => '#cfcfcf',
'::form_base.html.twig' => '::form_base.html.twig',

// Pre-YAML-1.2 booleans
"'y'" => 'y',
"'n'" => 'n',
"'yes'" => 'yes',
"'no'" => 'no',
"'on'" => 'on',
"'off'" => 'off',

'2007-10-30' => mktime(0, 0, 0, 10, 30, 2007),
'2007-10-30T02:59:43Z' => gmmktime(2, 59, 43, 10, 30, 2007),
'2007-10-30 02:59:43 Z' => gmmktime(2, 59, 43, 10, 30, 2007),
Expand Down Expand Up @@ -257,6 +265,14 @@ protected function getTestsForDump()
"'-dash'" => '-dash',
"'-'" => '-',

// Pre-YAML-1.2 booleans
"'y'" => 'y',
"'n'" => 'n',
"'yes'" => 'yes',
"'no'" => 'no',
"'on'" => 'on',
"'off'" => 'off',

// sequences
'[foo, bar, false, null, 12]' => array('foo', 'bar', false, null, 12),
'[\'foo,bar\', \'foo bar\']' => array('foo,bar', 'foo bar'),
Expand Down
0