diff options
Diffstat (limited to 'vendor/symfony/yaml/Unescaper.php')
-rw-r--r-- | vendor/symfony/yaml/Unescaper.php | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php new file mode 100644 index 0000000..9c3a19e --- /dev/null +++ b/vendor/symfony/yaml/Unescaper.php @@ -0,0 +1,138 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (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; + +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Unescaper encapsulates unescaping rules for single and double-quoted + * YAML strings. + * + * @author Matthew Lewinski <matthew@lewinski.org> + * + * @internal + */ +class Unescaper +{ + /** + * Regex fragment that matches an escaped character in a double quoted string. + */ + const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)'; + + /** + * Unescapes a single quoted string. + * + * @param string $value A single quoted string + * + * @return string The unescaped string + */ + public function unescapeSingleQuotedString(string $value): string + { + return str_replace('\'\'', '\'', $value); + } + + /** + * Unescapes a double quoted string. + * + * @param string $value A double quoted string + * + * @return string The unescaped string + */ + public function unescapeDoubleQuotedString(string $value): string + { + $callback = function ($match) { + return $this->unescapeCharacter($match[0]); + }; + + // evaluate the string + return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); + } + + /** + * Unescapes a character that was found in a double-quoted string. + * + * @param string $value An escaped character + * + * @return string The unescaped character + */ + private function unescapeCharacter(string $value): string + { + switch ($value[1]) { + case '0': + return "\x0"; + case 'a': + return "\x7"; + case 'b': + return "\x8"; + case 't': + return "\t"; + case "\t": + return "\t"; + case 'n': + return "\n"; + case 'v': + return "\xB"; + case 'f': + return "\xC"; + case 'r': + return "\r"; + case 'e': + return "\x1B"; + case ' ': + return ' '; + case '"': + return '"'; + case '/': + return '/'; + case '\\': + return '\\'; + case 'N': + // U+0085 NEXT LINE + return "\xC2\x85"; + case '_': + // U+00A0 NO-BREAK SPACE + return "\xC2\xA0"; + case 'L': + // U+2028 LINE SEPARATOR + return "\xE2\x80\xA8"; + case 'P': + // U+2029 PARAGRAPH SEPARATOR + return "\xE2\x80\xA9"; + case 'x': + return self::utf8chr(hexdec(substr($value, 2, 2))); + case 'u': + return self::utf8chr(hexdec(substr($value, 2, 4))); + case 'U': + return self::utf8chr(hexdec(substr($value, 2, 8))); + default: + throw new ParseException(sprintf('Found unknown escape character "%s".', $value)); + } + } + + /** + * Get the UTF-8 character for the given code point. + */ + private static function utf8chr(int $c): string + { + if (0x80 > $c %= 0x200000) { + return \chr($c); + } + if (0x800 > $c) { + return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F); + } + if (0x10000 > $c) { + return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } + + return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } +} |