This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/Yaml/Escaper.php

90 lines
3.4 KiB
PHP
Raw Normal View History

<?php
/*
* This file is part of the Symfony package.
2013-12-28 07:37:38 +00:00
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
/**
* Escaper encapsulates escaping rules for single and double-quoted
* YAML strings.
*
* @author Matthew Lewinski <matthew@lewinski.org>
*/
class Escaper
{
// Characters that would cause a dumped string to require double quoting.
const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
// Mapping arrays for escaping a double quoted string. The backslash is
// first to ensure proper escaping because str_replace operates iteratively
// on the input arrays. This ordering of the characters avoids the use of strtr,
// which performs more slowly.
merged branch jakzal/yamlDoubleQuotesDumperFix (PR #4320) Commits ------- b631073 [Yaml] Fixed double quotes escaping in Dumper. Discussion ---------- [Yaml] Fixed double quotes escaping in Dumper Issue #4308 is caused by Dumper::escapeWithDoubleQuotes() which uses [str_replace()](http://php.net/str_replace). From the php docs: > Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. We should be very careful in deciding about the order of elements in $escapees array. I'd really appreciate if someone reviewed my fix. Tests say I didn't break anything but I'm not sure what percentage of Yaml specification is covered by tests. Bug fix: yes Feature addition: no Backwards compatibility break: not that I know Symfony2 tests pass: [![Build Status](https://secure.travis-ci.org/jakzal/symfony.png?branch=yamlDoubleQuotesDumperFix)](http://travis-ci.org/jakzal/symfony) Fixes the following tickets: #4308 --------------------------------------------------------------------------- by travisbot at 2012-05-18T08:53:51Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1364279) (merged 5192722c into a04acc89). --------------------------------------------------------------------------- by travisbot at 2012-05-18T23:19:49Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1371539) (merged ecaa1aab into fc3c609b). --------------------------------------------------------------------------- by dinamic at 2012-05-19T07:35:21Z Something is really wrong with this method. You can see clearly that multiple characters would fail proper escaping. Here's an example: ``` $value = '\\\\"some value\n \"some quoted string\" and \'some single quotes one\'"'; var_dump(Escaper::escapeWithDoubleQuotes($value)); string(72) ""\\\"some value\n \\some quoted string\\ and 'some single quotes one'\""" ``` To begin with the backslash - in the initial value you have 2 (escaped ones), that after escaping should result in 4, not in 1 (escaped). I guess this behavior has to be verified with the importer, but imho it does not seem right. Does anyone know why this escaping wasn't done using a regular expression in first place? --------------------------------------------------------------------------- by clemens-tolboom at 2012-05-19T10:18:58Z Searching for https://duckduckgo.com/?q=what+is+\xc2\x85 the table on http://stackoverflow.com/questions/6609895/efficiently-replace-bad-characters is interesting enough to decide we need way more documentation on this file. \xc2\x85 seems to be triple dot (ellipses) \xe2\x80\xa9 seems to be paragraph separator see http://drupal.org/node/914360#comment-3468550 Conflicts: src/Symfony/Component/Yaml/Escaper.php
2012-06-09 16:04:17 +01:00
private static $escapees = array('\\\\', '\\"', '"',
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
"\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
merged branch jakzal/yamlDoubleQuotesDumperFix (PR #4320) Commits ------- b631073 [Yaml] Fixed double quotes escaping in Dumper. Discussion ---------- [Yaml] Fixed double quotes escaping in Dumper Issue #4308 is caused by Dumper::escapeWithDoubleQuotes() which uses [str_replace()](http://php.net/str_replace). From the php docs: > Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. We should be very careful in deciding about the order of elements in $escapees array. I'd really appreciate if someone reviewed my fix. Tests say I didn't break anything but I'm not sure what percentage of Yaml specification is covered by tests. Bug fix: yes Feature addition: no Backwards compatibility break: not that I know Symfony2 tests pass: [![Build Status](https://secure.travis-ci.org/jakzal/symfony.png?branch=yamlDoubleQuotesDumperFix)](http://travis-ci.org/jakzal/symfony) Fixes the following tickets: #4308 --------------------------------------------------------------------------- by travisbot at 2012-05-18T08:53:51Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1364279) (merged 5192722c into a04acc89). --------------------------------------------------------------------------- by travisbot at 2012-05-18T23:19:49Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1371539) (merged ecaa1aab into fc3c609b). --------------------------------------------------------------------------- by dinamic at 2012-05-19T07:35:21Z Something is really wrong with this method. You can see clearly that multiple characters would fail proper escaping. Here's an example: ``` $value = '\\\\"some value\n \"some quoted string\" and \'some single quotes one\'"'; var_dump(Escaper::escapeWithDoubleQuotes($value)); string(72) ""\\\"some value\n \\some quoted string\\ and 'some single quotes one'\""" ``` To begin with the backslash - in the initial value you have 2 (escaped ones), that after escaping should result in 4, not in 1 (escaped). I guess this behavior has to be verified with the importer, but imho it does not seem right. Does anyone know why this escaping wasn't done using a regular expression in first place? --------------------------------------------------------------------------- by clemens-tolboom at 2012-05-19T10:18:58Z Searching for https://duckduckgo.com/?q=what+is+\xc2\x85 the table on http://stackoverflow.com/questions/6609895/efficiently-replace-bad-characters is interesting enough to decide we need way more documentation on this file. \xc2\x85 seems to be triple dot (ellipses) \xe2\x80\xa9 seems to be paragraph separator see http://drupal.org/node/914360#comment-3468550 Conflicts: src/Symfony/Component/Yaml/Escaper.php
2012-06-09 16:04:17 +01:00
private static $escaped = array('\\"', '\\\\', '\\"',
"\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
"\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f",
"\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
"\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f",
"\\N", "\\_", "\\L", "\\P");
/**
* Determines if a PHP value would require double quoting in YAML.
*
* @param string $value A PHP value
*
2014-04-16 11:30:19 +01:00
* @return bool True if the value would require double quotes.
*/
2012-07-09 13:50:58 +01:00
public static function requiresDoubleQuoting($value)
{
return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
}
2011-04-15 20:12:02 +01:00
/**
* Escapes and surrounds a PHP value with double quotes.
*
* @param string $value A PHP value
*
* @return string The quoted, escaped string
*/
2012-07-09 13:50:58 +01:00
public static function escapeWithDoubleQuotes($value)
{
return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
}
/**
* Determines if a PHP value would require single quoting in YAML.
*
* @param string $value A PHP value
*
2014-04-16 11:30:19 +01:00
* @return bool True if the value would require single quotes.
*/
2012-07-09 13:50:58 +01:00
public static function requiresSingleQuoting($value)
{
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
}
/**
* Escapes and surrounds a PHP value with single quotes.
*
* @param string $value A PHP value
*
* @return string The quoted, escaped string
*/
2012-07-09 13:50:58 +01:00
public static function escapeWithSingleQuotes($value)
{
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
}
}