From d5cb86a61b56683ff3168020b0b1d60b1db7b1da Mon Sep 17 00:00:00 2001 From: Manuel Dalla Lana Date: Mon, 11 Sep 2017 10:50:14 +0200 Subject: [PATCH 1/2] Add PSR-0 autoloading of sfYaml classes --- .gitignore | 1 + composer.json | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7cdc81d2a..2d91747fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +/vendor tests/DoctrineTest/doctrine_tests/* *TestCase.php \ No newline at end of file diff --git a/composer.json b/composer.json index 58741c701..31b2f40ef 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,9 @@ "ext-pdo": "*" }, "autoload": { - "psr-0": { "Doctrine_": "lib/" } + "psr-0": { + "Doctrine_": "lib/", + "sfYaml": "lib/Doctrine/Parser/sfYaml" + } } } From 8438aba83144e619440f6380ae4258ea13e9b7d7 Mon Sep 17 00:00:00 2001 From: Manuel Dalla Lana Date: Mon, 2 Oct 2017 10:08:37 +0200 Subject: [PATCH 2/2] Align sfYaml classes to LExpress/symfony1@ca84921 This update fixes a bug in array merging, permits dumping of PHP resource in a YAML file, fixes dumpArray() for PHP 7.1, enforce UTF-8 encoding of YAML files, and remove unused echoln() function --- lib/Doctrine/Parser/sfYaml/sfYaml.php | 60 ++++++++++++++++----- lib/Doctrine/Parser/sfYaml/sfYamlDumper.php | 2 - lib/Doctrine/Parser/sfYaml/sfYamlInline.php | 31 ++++++----- lib/Doctrine/Parser/sfYaml/sfYamlParser.php | 11 ++-- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/lib/Doctrine/Parser/sfYaml/sfYaml.php b/lib/Doctrine/Parser/sfYaml/sfYaml.php index 1d89ccc97..80085856c 100644 --- a/lib/Doctrine/Parser/sfYaml/sfYaml.php +++ b/lib/Doctrine/Parser/sfYaml/sfYaml.php @@ -2,7 +2,7 @@ /* * This file is part of the symfony package. - * (c) 2004-2006 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -64,7 +64,7 @@ static public function getSpecVersion() * * @throws InvalidArgumentException If the YAML is not valid */ - public static function load($input) + public static function load($input, $encoding = 'UTF-8') { $file = ''; @@ -87,7 +87,13 @@ public static function load($input) return $input; } - require_once dirname(__FILE__).'/sfYamlParser.php'; + $mbConvertEncoding = false; + $encoding = strtoupper($encoding); + if ('UTF-8' != $encoding && function_exists('mb_convert_encoding')) + { + $input = mb_convert_encoding($input, 'UTF-8', $encoding); + $mbConvertEncoding = true; + } $yaml = new sfYamlParser(); @@ -100,6 +106,11 @@ public static function load($input) throw new InvalidArgumentException(sprintf('Unable to parse %s: %s', $file ? sprintf('file "%s"', $file) : 'string', $e->getMessage())); } + if ($ret && $mbConvertEncoding) + { + $ret = self::arrayConvertEncoding($ret, $encoding); + } + return $ret; } @@ -116,20 +127,41 @@ public static function load($input) */ public static function dump($array, $inline = 2) { - require_once dirname(__FILE__).'/sfYamlDumper.php'; - $yaml = new sfYamlDumper(); return $yaml->dump($array, $inline); } -} -/** - * Wraps echo to automatically provide a newline. - * - * @param string $string The string to echo with new line - */ -function echoln($string) -{ - echo $string."\n"; + /** + * Converts all kayes and values from UTF-8 to given encoding + * + * @param array $result Original result + * @param string $encoding The expected encoding + * @return array + */ + protected static function arrayConvertEncoding(array $result, $encoding) + { + $convertedResult = array(); + foreach ($result as $key => $value) + { + if (is_string($key)) + { + $key = mb_convert_encoding($key, $encoding, 'UTF-8'); + } + if (is_array($value)) + { + $convertedResult[$key] = self::arrayConvertEncoding($value, $encoding); + } + else if (is_string($value)) + { + $convertedResult[$key] = mb_convert_encoding($value, $encoding, 'UTF-8'); + } + else + { + $convertedResult[$key] = $value; + } + } + + return $convertedResult; + } } diff --git a/lib/Doctrine/Parser/sfYaml/sfYamlDumper.php b/lib/Doctrine/Parser/sfYaml/sfYamlDumper.php index 0ada2b37d..130f2366d 100644 --- a/lib/Doctrine/Parser/sfYaml/sfYamlDumper.php +++ b/lib/Doctrine/Parser/sfYaml/sfYamlDumper.php @@ -8,8 +8,6 @@ * file that was distributed with this source code. */ -require_once(dirname(__FILE__).'/sfYamlInline.php'); - /** * sfYamlDumper dumps PHP variables to YAML strings. * diff --git a/lib/Doctrine/Parser/sfYaml/sfYamlInline.php b/lib/Doctrine/Parser/sfYaml/sfYamlInline.php index a88cbb3d9..ad9342099 100644 --- a/lib/Doctrine/Parser/sfYaml/sfYamlInline.php +++ b/lib/Doctrine/Parser/sfYaml/sfYamlInline.php @@ -8,8 +8,6 @@ * file that was distributed with this source code. */ -require_once dirname(__FILE__).'/sfYaml.php'; - /** * sfYamlInline implements a YAML parser/dumper for the YAML inline syntax. * @@ -33,7 +31,7 @@ static public function load($value) { $value = trim($value); - if (0 == strlen($value)) + if ('' === $value) { return ''; } @@ -87,7 +85,8 @@ static public function dump($value) switch (true) { case is_resource($value): - throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.'); + return stream_get_contents($value); + // throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.'); case is_object($value): return '!!php/object:'.serialize($value); case is_array($value): @@ -101,7 +100,7 @@ static public function dump($value) case ctype_digit($value): return is_string($value) ? "'$value'" : (int) $value; case is_numeric($value): - return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value); + return is_infinite($value) ? str_ireplace('INF', '.Inf', (string) $value) : (is_string($value) ? "'$value'" : $value); case false !== strpos($value, "\n") || false !== strpos($value, "\r"): return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value)); case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value): @@ -135,7 +134,7 @@ static protected function dumpArray($value) if ( (1 == count($keys) && '0' == $keys[0]) || - (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2)) + (count($keys) > 1 && array_sum(array_map('intval', $keys)) == count($keys) * (count($keys) - 1) / 2)) { $output = array(); foreach ($value as $val) @@ -249,7 +248,7 @@ static protected function parseSequence($sequence, &$i = 0) { $output = array(); $len = strlen($sequence); - $i += 1; + ++$i; // [foo, bar, ...] while ($i < $len) @@ -309,7 +308,7 @@ static protected function parseMapping($mapping, &$i = 0) { $output = array(); $len = strlen($mapping); - $i += 1; + ++$i; // {foo: bar, bar:foo, ...} while ($i < $len) @@ -395,26 +394,32 @@ static protected function evaluateScalar($scalar) case 0 === strpos($scalar, '!str'): return (string) substr($scalar, 5); case 0 === strpos($scalar, '! '): - return intval(self::parseScalar(substr($scalar, 2))); + return (int) self::parseScalar(substr($scalar, 2)); case 0 === strpos($scalar, '!!php/object:'): return unserialize(substr($scalar, 13)); case ctype_digit($scalar): $raw = $scalar; - $cast = intval($scalar); + $cast = (int) $scalar; return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); case in_array(strtolower($scalar), $trueValues): return true; case in_array(strtolower($scalar), $falseValues): return false; + case 0 === strpos($scalar, '0x'): + return hexdec($scalar); case is_numeric($scalar): - return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar); + return floatval($scalar); case 0 == strcasecmp($scalar, '.inf'): case 0 == strcasecmp($scalar, '.NaN'): return -log(0); case 0 == strcasecmp($scalar, '-.inf'): return log(0); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): - return floatval(str_replace(',', '', $scalar)); + case preg_match('/^(-|\+)?[0-9,]+(\.\d+)?$/', $scalar): + $replaced = str_replace(',', '', $scalar); + $replaced = str_replace('+', '', $replaced); + $floatval = floatval($replaced); + $intval = intval($replaced); + return $floatval == $intval ? $intval : $floatval; case preg_match(self::getTimestampRegex(), $scalar): return strtotime($scalar); default: diff --git a/lib/Doctrine/Parser/sfYaml/sfYamlParser.php b/lib/Doctrine/Parser/sfYaml/sfYamlParser.php index 91da2dcb1..69b9f2651 100644 --- a/lib/Doctrine/Parser/sfYaml/sfYamlParser.php +++ b/lib/Doctrine/Parser/sfYaml/sfYamlParser.php @@ -8,8 +8,6 @@ * file that was distributed with this source code. */ -require_once(dirname(__FILE__).'/sfYamlInline.php'); - if (!defined('PREG_BAD_UTF8_OFFSET_ERROR')) { define('PREG_BAD_UTF8_OFFSET_ERROR', 5); @@ -57,6 +55,11 @@ public function parse($value) $this->currentLine = ''; $this->lines = explode("\n", $this->cleanup($value)); + if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) + { + throw new InvalidArgumentException('The YAML value does not appear to be valid UTF-8.'); + } + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); @@ -168,7 +171,7 @@ public function parse($value) else { // Associative array, merge - $merged = array_merge($merge, $parsed); + $merged = array_merge($merged, $parsed); } $isProcessed = $merged; @@ -418,7 +421,7 @@ protected function parseValue($value) { $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers))); + return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); } else {