Spade
Mini Shell
polyfill-ctype/bootstrap.php000064400000002756151166602240012263
0ustar00<?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.
*/
use Symfony\Polyfill\Ctype as p;
if (!function_exists('ctype_alnum')) {
function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
}
if (!function_exists('ctype_alpha')) {
function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
}
if (!function_exists('ctype_cntrl')) {
function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
}
if (!function_exists('ctype_digit')) {
function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
}
if (!function_exists('ctype_graph')) {
function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
}
if (!function_exists('ctype_lower')) {
function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
}
if (!function_exists('ctype_print')) {
function ctype_print($text) { return p\Ctype::ctype_print($text); }
}
if (!function_exists('ctype_punct')) {
function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
}
if (!function_exists('ctype_space')) {
function ctype_space($text) { return p\Ctype::ctype_space($text); }
}
if (!function_exists('ctype_upper')) {
function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
}
if (!function_exists('ctype_xdigit')) {
function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
}
polyfill-ctype/Ctype.php000064400000014175151166602240011330
0ustar00<?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\Polyfill\Ctype;
/**
* Ctype implementation through regex.
*
* @internal
*
* @author Gert de Pagter <BackEndTea@gmail.com>
*/
final class Ctype
{
/**
* Returns TRUE if every character in text is either a letter or a
digit, FALSE otherwise.
*
* @see https://php.net/ctype-alnum
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_alnum($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^A-Za-z0-9]/', $text);
}
/**
* Returns TRUE if every character in text is a letter, FALSE
otherwise.
*
* @see https://php.net/ctype-alpha
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_alpha($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^A-Za-z]/', $text);
}
/**
* Returns TRUE if every character in text is a control character from
the current locale, FALSE otherwise.
*
* @see https://php.net/ctype-cntrl
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_cntrl($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^\x00-\x1f\x7f]/', $text);
}
/**
* Returns TRUE if every character in the string text is a decimal
digit, FALSE otherwise.
*
* @see https://php.net/ctype-digit
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_digit($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^0-9]/', $text);
}
/**
* Returns TRUE if every character in text is printable and actually
creates visible output (no white space), FALSE otherwise.
*
* @see https://php.net/ctype-graph
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_graph($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^!-~]/', $text);
}
/**
* Returns TRUE if every character in text is a lowercase letter.
*
* @see https://php.net/ctype-lower
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_lower($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^a-z]/', $text);
}
/**
* Returns TRUE if every character in text will actually create output
(including blanks). Returns FALSE if text contains control characters or
characters that do not have any output or control function at all.
*
* @see https://php.net/ctype-print
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_print($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^ -~]/', $text);
}
/**
* Returns TRUE if every character in text is printable, but neither
letter, digit or blank, FALSE otherwise.
*
* @see https://php.net/ctype-punct
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_punct($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
}
/**
* Returns TRUE if every character in text creates some sort of white
space, FALSE otherwise. Besides the blank character this also includes tab,
vertical tab, line feed, carriage return and form feed characters.
*
* @see https://php.net/ctype-space
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_space($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^\s]/', $text);
}
/**
* Returns TRUE if every character in text is an uppercase letter.
*
* @see https://php.net/ctype-upper
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_upper($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^A-Z]/', $text);
}
/**
* Returns TRUE if every character in text is a hexadecimal
'digit', that is a decimal digit or a character from [A-Fa-f] ,
FALSE otherwise.
*
* @see https://php.net/ctype-xdigit
*
* @param string|int $text
*
* @return bool
*/
public static function ctype_xdigit($text)
{
$text = self::convert_int_to_char_for_ctype($text);
return \is_string($text) && '' !== $text
&& !preg_match('/[^A-Fa-f0-9]/', $text);
}
/**
* Converts integers to their char versions according to normal ctype
behaviour, if needed.
*
* If an integer between -128 and 255 inclusive is provided,
* it is interpreted as the ASCII value of a single character
* (negative values have 256 added in order to allow characters in the
Extended ASCII range).
* Any other integer is interpreted as a string containing the decimal
digits of the integer.
*
* @param string|int $int
*
* @return mixed
*/
private static function convert_int_to_char_for_ctype($int)
{
if (!\is_int($int)) {
return $int;
}
if ($int < -128 || $int > 255) {
return (string) $int;
}
if ($int < 0) {
$int += 256;
}
return \chr($int);
}
}
polyfill-ctype/LICENSE000064400000002051151166602240010526
0ustar00Copyright (c) 2018-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
polyfill-php55/bootstrap.php000064400000001705151166602240012071
0ustar00<?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.
*/
use Symfony\Polyfill\Php55 as p;
if (PHP_VERSION_ID >= 50500) {
return;
}
if (!function_exists('boolval')) {
function boolval($val) { return p\Php55::boolval($val); }
}
if (!function_exists('json_last_error_msg')) {
function json_last_error_msg() { return p\Php55::json_last_error_msg();
}
}
if (!function_exists('array_column')) {
function array_column($array, $columnKey, $indexKey = null) { return
p\Php55ArrayColumn::array_column($array, $columnKey, $indexKey); }
}
if (!function_exists('hash_pbkdf2')) {
function hash_pbkdf2($algorithm, $password, $salt, $iterations, $length
= 0, $rawOutput = false) { return p\Php55::hash_pbkdf2($algorithm,
$password, $salt, $iterations, $length, $rawOutput); }
}
polyfill-php55/LICENSE000064400000002051151166602240010343
0ustar00Copyright (c) 2015-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
polyfill-php55/Php55.php000064400000005127151166602240010757
0ustar00<?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\Polyfill\Php55;
/**
* @internal
*/
final class Php55
{
public static function boolval($val)
{
return (bool) $val;
}
public static function json_last_error_msg()
{
switch (json_last_error()) {
case JSON_ERROR_NONE: return 'No error';
case JSON_ERROR_DEPTH: return 'Maximum stack depth
exceeded';
case JSON_ERROR_STATE_MISMATCH: return 'State mismatch
(invalid or malformed JSON)';
case JSON_ERROR_CTRL_CHAR: return 'Control character
error, possibly incorrectly encoded';
case JSON_ERROR_SYNTAX: return 'Syntax error';
case JSON_ERROR_UTF8: return 'Malformed UTF-8 characters,
possibly incorrectly encoded';
default: return 'Unknown error';
}
}
/**
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
* @author Scott <scott@paragonie.com>
*/
public static function hash_pbkdf2($algorithm, $password, $salt,
$iterations, $length = 0, $rawOutput = false)
{
// Pre-hash for optimization if password length > hash length
$hashLength = \strlen(hash($algorithm, '', true));
switch ($algorithm) {
case 'sha1':
case 'sha224':
case 'sha256':
$blockSize = 64;
break;
case 'sha384':
case 'sha512':
$blockSize = 128;
break;
default:
$blockSize = $hashLength;
break;
}
if ($length < 1) {
$length = $hashLength;
if (!$rawOutput) {
$length <<= 1;
}
}
// Number of blocks needed to create the derived key
$blocks = ceil($length / $hashLength);
$digest = '';
if (\strlen($password) > $blockSize) {
$password = hash($algorithm, $password, true);
}
for ($i = 1; $i <= $blocks; ++$i) {
$ib = $block = hash_hmac($algorithm, $salt.pack('N',
$i), $password, true);
// Iterations
for ($j = 1; $j < $iterations; ++$j) {
$ib ^= ($block = hash_hmac($algorithm, $block, $password,
true));
}
$digest .= $ib;
}
if (!$rawOutput) {
$digest = bin2hex($digest);
}
return substr($digest, 0, $length);
}
}
polyfill-php55/Php55ArrayColumn.php000064400000004211151166602240013125
0ustar00<?php
/*
* Copyright (c) 2013 Ben Ramsey <http://benramsey.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
a
* copy of this software and associated documentation files (the
"Software"),
* to deal in the Software without restriction, including without
limitation
* the rights to use, copy, modify, merge, publish, distribute,
sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
namespace Symfony\Polyfill\Php55;
/**
* @internal
*/
final class Php55ArrayColumn
{
public static function array_column(array $input, $columnKey, $indexKey
= null)
{
$output = array();
foreach ($input as $row) {
$key = $value = null;
$keySet = $valueSet = false;
if (null !== $indexKey && array_key_exists($indexKey,
$row)) {
$keySet = true;
$key = (string) $row[$indexKey];
}
if (null === $columnKey) {
$valueSet = true;
$value = $row;
} elseif (\is_array($row) &&
\array_key_exists($columnKey, $row)) {
$valueSet = true;
$value = $row[$columnKey];
}
if ($valueSet) {
if ($keySet) {
$output[$key] = $value;
} else {
$output[] = $value;
}
}
}
return $output;
}
}
polyfill-php56/bootstrap.php000064400000003050151166602240012065
0ustar00<?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.
*/
use Symfony\Polyfill\Php56 as p;
if (PHP_VERSION_ID >= 50600) {
return;
}
if (!function_exists('hash_equals')) {
function hash_equals($knownString, $userInput) { return
p\Php56::hash_equals($knownString, $userInput); }
}
if (extension_loaded('ldap') &&
!defined('LDAP_ESCAPE_FILTER')) {
define('LDAP_ESCAPE_FILTER', 1);
}
if (extension_loaded('ldap') &&
!defined('LDAP_ESCAPE_DN')) {
define('LDAP_ESCAPE_DN', 2);
}
if (extension_loaded('ldap') &&
!function_exists('ldap_escape')) {
function ldap_escape($subject, $ignore = '', $flags = 0) {
return p\Php56::ldap_escape($subject, $ignore, $flags); }
}
if (50509 === PHP_VERSION_ID && 4 === PHP_INT_SIZE) {
// Missing functions in PHP 5.5.9 - affects 32 bit builds of Ubuntu
14.04LTS
// See https://bugs.launchpad.net/ubuntu/+source/php5/+bug/1315888
if (!function_exists('gzopen') &&
function_exists('gzopen64')) {
function gzopen($filename, $mode, $use_include_path = 0) { return
gzopen64($filename, $mode, $use_include_path); }
}
if (!function_exists('gzseek') &&
function_exists('gzseek64')) {
function gzseek($zp, $offset, $whence = SEEK_SET) { return
gzseek64($zp, $offset, $whence); }
}
if (!function_exists('gztell') &&
function_exists('gztell64')) {
function gztell($zp) { return gztell64($zp); }
}
}
polyfill-php56/LICENSE000064400000002051151166602240010344
0ustar00Copyright (c) 2015-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
polyfill-php56/Php56.php000064400000007467151166602240010772
0ustar00<?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\Polyfill\Php56;
use Symfony\Polyfill\Util\Binary;
/**
* @internal
*/
final class Php56
{
const LDAP_ESCAPE_FILTER = 1;
const LDAP_ESCAPE_DN = 2;
public static function hash_equals($knownString, $userInput)
{
if (!\is_string($knownString)) {
trigger_error('Expected known_string to be a string,
'.\gettype($knownString).' given', E_USER_WARNING);
return false;
}
if (!\is_string($userInput)) {
trigger_error('Expected user_input to be a string,
'.\gettype($userInput).' given', E_USER_WARNING);
return false;
}
$knownLen = Binary::strlen($knownString);
$userLen = Binary::strlen($userInput);
if ($knownLen !== $userLen) {
return false;
}
$result = 0;
for ($i = 0; $i < $knownLen; ++$i) {
$result |= \ord($knownString[$i]) ^ \ord($userInput[$i]);
}
return 0 === $result;
}
/**
* Stub implementation of the {@link ldap_escape()} function of the
ldap
* extension.
*
* Escape strings for safe use in LDAP filters and DNs.
*
* @author Chris Wright <ldapi@daverandom.com>
*
* @param string $subject
* @param string $ignore
* @param int $flags
*
* @return string
*
* @see http://stackoverflow.com/a/8561604
*/
public static function ldap_escape($subject, $ignore = '',
$flags = 0)
{
static $charMaps = null;
if (null === $charMaps) {
$charMaps = array(
self::LDAP_ESCAPE_FILTER => array('\\',
'*', '(', ')', "\x00"),
self::LDAP_ESCAPE_DN => array('\\',
',', '=', '+', '<',
'>', ';', '"', '#',
"\r"),
);
$charMaps[0] = array();
for ($i = 0; $i < 256; ++$i) {
$charMaps[0][\chr($i)] = sprintf('\\%02x', $i);
}
for ($i = 0, $l = \count($charMaps[self::LDAP_ESCAPE_FILTER]);
$i < $l; ++$i) {
$chr = $charMaps[self::LDAP_ESCAPE_FILTER][$i];
unset($charMaps[self::LDAP_ESCAPE_FILTER][$i]);
$charMaps[self::LDAP_ESCAPE_FILTER][$chr] =
$charMaps[0][$chr];
}
for ($i = 0, $l = \count($charMaps[self::LDAP_ESCAPE_DN]); $i
< $l; ++$i) {
$chr = $charMaps[self::LDAP_ESCAPE_DN][$i];
unset($charMaps[self::LDAP_ESCAPE_DN][$i]);
$charMaps[self::LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr];
}
}
// Create the base char map to escape
$flags = (int) $flags;
$charMap = array();
if ($flags & self::LDAP_ESCAPE_FILTER) {
$charMap += $charMaps[self::LDAP_ESCAPE_FILTER];
}
if ($flags & self::LDAP_ESCAPE_DN) {
$charMap += $charMaps[self::LDAP_ESCAPE_DN];
}
if (!$charMap) {
$charMap = $charMaps[0];
}
// Remove any chars to ignore from the list
$ignore = (string) $ignore;
for ($i = 0, $l = \strlen($ignore); $i < $l; ++$i) {
unset($charMap[$ignore[$i]]);
}
// Do the main replacement
$result = strtr($subject, $charMap);
// Encode leading/trailing spaces if self::LDAP_ESCAPE_DN is passed
if ($flags & self::LDAP_ESCAPE_DN) {
if (' ' === $result[0]) {
$result = '\\20'.substr($result, 1);
}
if (' ' === $result[\strlen($result) - 1]) {
$result = substr($result, 0, -1).'\\20';
}
}
return $result;
}
}
polyfill-php71/bootstrap.php000064400000000577151166602270012100
0ustar00<?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.
*/
use Symfony\Polyfill\Php71 as p;
if (!function_exists('is_iterable')) {
function is_iterable($var) { return p\Php71::is_iterable($var); }
}
polyfill-php71/LICENSE000064400000002051151166602270010344
0ustar00Copyright (c) 2015-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
polyfill-php71/Php71.php000064400000000762151166602270010756
0ustar00<?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\Polyfill\Php71;
/**
* @author Dariusz RumiĆski <dariusz.ruminski@gmail.com>
*
* @internal
*/
final class Php71
{
public static function is_iterable($var)
{
return \is_array($var) || $var instanceof \Traversable;
}
}
polyfill-php73/bootstrap.php000064400000001723151166602270012074
0ustar00<?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.
*/
use Symfony\Polyfill\Php73 as p;
if (PHP_VERSION_ID >= 70300) {
return;
}
if (!function_exists('is_countable')) {
function is_countable($var) { return is_array($var) || $var instanceof
Countable || $var instanceof ResourceBundle || $var instanceof
SimpleXmlElement; }
}
if (!function_exists('hrtime')) {
require_once __DIR__.'/Php73.php';
p\Php73::$startAt = (int) microtime(true);
function hrtime($asNum = false) { return p\Php73::hrtime($asNum); }
}
if (!function_exists('array_key_first')) {
function array_key_first(array $array) { foreach ($array as $key =>
$value) { return $key; } }
}
if (!function_exists('array_key_last')) {
function array_key_last(array $array) { end($array); return
key($array); }
}
polyfill-php73/LICENSE000064400000002051151166602270010346
0ustar00Copyright (c) 2018-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
polyfill-php73/Php73.php000064400000001547151166602270010764
0ustar00<?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\Polyfill\Php73;
/**
* @author Gabriel Caruso <carusogabriel34@gmail.com>
* @author Ion Bazan <ion.bazan@gmail.com>
*
* @internal
*/
final class Php73
{
public static $startAt = 1533462603;
/**
* @param bool $asNum
*
* @return array|float|int
*/
public static function hrtime($asNum = false)
{
$ns = microtime(false);
$s = substr($ns, 11) - self::$startAt;
$ns = 1E9 * (float) $ns;
if ($asNum) {
$ns += $s * 1E9;
return \PHP_INT_SIZE === 4 ? $ns : (int) $ns;
}
return array($s, (int) $ns);
}
}
polyfill-php73/Resources/stubs/JsonException.php000064400000000430151166602270015753
0ustar00<?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.
*/
class JsonException extends Exception
{
}
polyfill-util/Binary.php000064400000000664151166602270011322
0ustar00<?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\Polyfill\Util;
if (\extension_loaded('mbstring')) {
class Binary extends BinaryOnFuncOverload
{
}
} else {
class Binary extends BinaryNoFuncOverload
{
}
}
polyfill-util/BinaryNoFuncOverload.php000064400000002651151166602270014125
0ustar00<?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\Polyfill\Util;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class BinaryNoFuncOverload
{
public static function strlen($s)
{
return \strlen($s);
}
public static function strpos($haystack, $needle, $offset = 0)
{
return strpos($haystack, $needle, $offset);
}
public static function strrpos($haystack, $needle, $offset = 0)
{
return strrpos($haystack, $needle, $offset);
}
public static function substr($string, $start, $length = PHP_INT_MAX)
{
return substr($string, $start, $length);
}
public static function stripos($s, $needle, $offset = 0)
{
return stripos($s, $needle, $offset);
}
public static function stristr($s, $needle, $part = false)
{
return stristr($s, $needle, $part);
}
public static function strrchr($s, $needle, $part = false)
{
return strrchr($s, $needle, $part);
}
public static function strripos($s, $needle, $offset = 0)
{
return strripos($s, $needle, $offset);
}
public static function strstr($s, $needle, $part = false)
{
return strstr($s, $needle, $part);
}
}
polyfill-util/BinaryOnFuncOverload.php000064400000003147151166602270014126
0ustar00<?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\Polyfill\Util;
/**
* Binary safe version of string functions overloaded when
MB_OVERLOAD_STRING is enabled.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class BinaryOnFuncOverload
{
public static function strlen($s)
{
return mb_strlen($s, '8bit');
}
public static function strpos($haystack, $needle, $offset = 0)
{
return mb_strpos($haystack, $needle, $offset, '8bit');
}
public static function strrpos($haystack, $needle, $offset = 0)
{
return mb_strrpos($haystack, $needle, $offset, '8bit');
}
public static function substr($string, $start, $length = 2147483647)
{
return mb_substr($string, $start, $length, '8bit');
}
public static function stripos($s, $needle, $offset = 0)
{
return mb_stripos($s, $needle, $offset, '8bit');
}
public static function stristr($s, $needle, $part = false)
{
return mb_stristr($s, $needle, $part, '8bit');
}
public static function strrchr($s, $needle, $part = false)
{
return mb_strrchr($s, $needle, $part, '8bit');
}
public static function strripos($s, $needle, $offset = 0)
{
return mb_strripos($s, $needle, $offset, '8bit');
}
public static function strstr($s, $needle, $part = false)
{
return mb_strstr($s, $needle, $part, '8bit');
}
}
polyfill-util/LICENSE000064400000002051151166602270010362 0ustar00Copyright
(c) 2015-2019 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
yaml/Dumper.php000064400000004750151166602270007467 0ustar00<?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;
/**
* Dumper dumps PHP variables to YAML strings.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Dumper
{
/**
* The amount of spaces to use for indentation of nested nodes.
*
* @var int
*/
protected $indentation = 4;
/**
* Sets the indentation.
*
* @param int $num The amount of spaces to use for indentation of
nested nodes
*/
public function setIndentation($num)
{
if ($num < 1) {
throw new \InvalidArgumentException('The indentation must
be greater than zero.');
}
$this->indentation = (int) $num;
}
/**
* Dumps a PHP value to YAML.
*
* @param mixed $input The PHP value
* @param int $inline The level where you switch to
inline YAML
* @param int $indent The level of indentation (used
internally)
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
*
* @return string The YAML representation of the PHP value
*/
public function dump($input, $inline = 0, $indent = 0,
$exceptionOnInvalidType = false, $objectSupport = false)
{
$output = '';
$prefix = $indent ? str_repeat(' ', $indent) :
'';
if ($inline <= 0 || !\is_array($input) || empty($input)) {
$output .= $prefix.Inline::dump($input,
$exceptionOnInvalidType, $objectSupport);
} else {
$isAHash = Inline::isHash($input);
foreach ($input as $key => $value) {
$willBeInlined = $inline - 1 <= 0 || !\is_array($value)
|| empty($value);
$output .= sprintf('%s%s%s%s',
$prefix,
$isAHash ? Inline::dump($key, $exceptionOnInvalidType,
$objectSupport).':' : '-',
$willBeInlined ? ' ' : "\n",
$this->dump($value, $inline - 1, $willBeInlined ? 0
: $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
).($willBeInlined ? "\n" : '');
}
}
return $output;
}
}
yaml/Escaper.php000064400000007550151166602270007616 0ustar00<?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;
/**
* Escaper encapsulates escaping rules for single and double-quoted
* YAML strings.
*
* @author Matthew Lewinski <matthew@lewinski.org>
*
* @internal
*/
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.
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",
);
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
*
* @return bool True if the value would require double quotes
*/
public static function requiresDoubleQuoting($value)
{
return 0 <
preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u',
$value);
}
/**
* Escapes and surrounds a PHP value with double quotes.
*
* @param string $value A PHP value
*
* @return string The quoted, escaped string
*/
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
*
* @return bool True if the value would require single quotes
*/
public static function requiresSingleQuoting($value)
{
// Determines if a PHP value is entirely composed of a value that
would
// require single quoting in YAML.
if (\in_array(strtolower($value), array('null',
'~', 'true', 'false', 'y',
'n', 'yes', 'no', 'on',
'off'))) {
return true;
}
// Determines if the PHP value contains any single characters that
would
// cause it to require single quoting in YAML.
return 0 < 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
*/
public static function escapeWithSingleQuotes($value)
{
return sprintf("'%s'",
str_replace('\'', '\'\'', $value));
}
}
yaml/Exception/DumpException.php000064400000000707151166602270012753
0ustar00<?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\Exception;
/**
* Exception class thrown when an error occurs during dumping.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DumpException extends RuntimeException
{
}
yaml/Exception/ExceptionInterface.php000064400000000673151166602270013750
0ustar00<?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\Exception;
/**
* Exception interface for all exceptions thrown by the component.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ExceptionInterface
{
}
yaml/Exception/ParseException.php000064400000006771151166602300013121
0ustar00<?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\Exception;
/**
* Exception class thrown when an error occurs during parsing.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ParseException extends RuntimeException
{
private $parsedFile;
private $parsedLine;
private $snippet;
private $rawMessage;
/**
* @param string $message The error message
* @param int $parsedLine The line where the error occurred
* @param string|null $snippet The snippet of code near the
problem
* @param string|null $parsedFile The file name where the error
occurred
* @param \Exception|null $previous The previous exception
*/
public function __construct($message, $parsedLine = -1, $snippet =
null, $parsedFile = null, \Exception $previous = null)
{
$this->parsedFile = $parsedFile;
$this->parsedLine = $parsedLine;
$this->snippet = $snippet;
$this->rawMessage = $message;
$this->updateRepr();
parent::__construct($this->message, 0, $previous);
}
/**
* Gets the snippet of code near the error.
*
* @return string The snippet of code
*/
public function getSnippet()
{
return $this->snippet;
}
/**
* Sets the snippet of code near the error.
*
* @param string $snippet The code snippet
*/
public function setSnippet($snippet)
{
$this->snippet = $snippet;
$this->updateRepr();
}
/**
* Gets the filename where the error occurred.
*
* This method returns null if a string is parsed.
*
* @return string The filename
*/
public function getParsedFile()
{
return $this->parsedFile;
}
/**
* Sets the filename where the error occurred.
*
* @param string $parsedFile The filename
*/
public function setParsedFile($parsedFile)
{
$this->parsedFile = $parsedFile;
$this->updateRepr();
}
/**
* Gets the line where the error occurred.
*
* @return int The file line
*/
public function getParsedLine()
{
return $this->parsedLine;
}
/**
* Sets the line where the error occurred.
*
* @param int $parsedLine The file line
*/
public function setParsedLine($parsedLine)
{
$this->parsedLine = $parsedLine;
$this->updateRepr();
}
private function updateRepr()
{
$this->message = $this->rawMessage;
$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}
if (null !== $this->parsedFile) {
if (\PHP_VERSION_ID >= 50400) {
$jsonOptions = JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE;
} else {
$jsonOptions = 0;
}
$this->message .= sprintf(' in %s',
json_encode($this->parsedFile, $jsonOptions));
}
if ($this->parsedLine >= 0) {
$this->message .= sprintf(' at line %d',
$this->parsedLine);
}
if ($this->snippet) {
$this->message .= sprintf(' (near
"%s")', $this->snippet);
}
if ($dot) {
$this->message .= '.';
}
}
}
yaml/Exception/RuntimeException.php000064400000000745151166602300013465
0ustar00<?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\Exception;
/**
* Exception class thrown when an error occurs during parsing.
*
* @author Romain Neutron <imprec@gmail.com>
*/
class RuntimeException extends \RuntimeException implements
ExceptionInterface
{
}
yaml/Inline.php000064400000053711151166602300007444 0ustar00<?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\DumpException;
use Symfony\Component\Yaml\Exception\ParseException;
/**
* Inline implements a YAML parser/dumper for the YAML inline syntax.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Inline
{
const REGEX_QUOTED_STRING =
'(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';
private static $exceptionOnInvalidType = false;
private static $objectSupport = false;
private static $objectForMap = false;
/**
* Converts a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
* @param bool $objectForMap True if maps should return a
stdClass instead of array()
* @param array $references Mapping of variable names to
values
*
* @return mixed A PHP value
*
* @throws ParseException
*/
public static function parse($value, $exceptionOnInvalidType = false,
$objectSupport = false, $objectForMap = false, $references = array())
{
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
self::$objectSupport = $objectSupport;
self::$objectForMap = $objectForMap;
$value = trim($value);
if ('' === $value) {
return '';
}
if (2 /* MB_OVERLOAD_STRING */ & (int)
ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}
$i = 0;
switch ($value[0]) {
case '[':
$result = self::parseSequence($value, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $i, $references);
++$i;
break;
default:
$result = self::parseScalar($value, null,
array('"', "'"), $i, true, $references);
}
// some comments are allowed at the end
if (preg_replace('/\s+#.*$/A', '',
substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters
near "%s".', substr($value, $i)));
}
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return $result;
}
/**
* Dumps a given PHP variable to a YAML string.
*
* @param mixed $value The PHP variable to convert
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
*
* @return string The YAML string representing the PHP value
*
* @throws DumpException When trying to dump PHP resource
*/
public static function dump($value, $exceptionOnInvalidType = false,
$objectSupport = false)
{
switch (true) {
case \is_resource($value):
if ($exceptionOnInvalidType) {
throw new DumpException(sprintf('Unable to dump
PHP resources in a YAML file ("%s").',
get_resource_type($value)));
}
return 'null';
case \is_object($value):
if ($objectSupport) {
return '!php/object:'.serialize($value);
}
if ($exceptionOnInvalidType) {
throw new DumpException('Object support when
dumping a YAML file has been disabled.');
}
return 'null';
case \is_array($value):
return self::dumpArray($value, $exceptionOnInvalidType,
$objectSupport);
case null === $value:
return 'null';
case true === $value:
return 'true';
case false === $value:
return 'false';
case ctype_digit($value):
return \is_string($value) ? "'$value'"
: (int) $value;
case is_numeric($value):
$locale = setlocale(LC_NUMERIC, 0);
if (false !== $locale) {
setlocale(LC_NUMERIC, 'C');
}
if (\is_float($value)) {
$repr = (string) $value;
if (is_infinite($value)) {
$repr = str_ireplace('INF',
'.Inf', $repr);
} elseif (floor($value) == $value && $repr ==
$value) {
// Preserve float data type since storing a whole
number will result in integer value.
$repr = '!!float '.$repr;
}
} else {
$repr = \is_string($value) ?
"'$value'" : (string) $value;
}
if (false !== $locale) {
setlocale(LC_NUMERIC, $locale);
}
return $repr;
case '' == $value:
return "''";
case Escaper::requiresDoubleQuoting($value):
return Escaper::escapeWithDoubleQuotes($value);
case Escaper::requiresSingleQuoting($value):
case Parser::preg_match(self::getHexRegex(), $value):
case Parser::preg_match(self::getTimestampRegex(), $value):
return Escaper::escapeWithSingleQuotes($value);
default:
return $value;
}
}
/**
* Check if given array is hash or just normal indexed array.
*
* @internal
*
* @param array $value The PHP array to check
*
* @return bool true if value is hash array, false otherwise
*/
public static function isHash(array $value)
{
$expectedKey = 0;
foreach ($value as $key => $val) {
if ($key !== $expectedKey++) {
return true;
}
}
return false;
}
/**
* Dumps a PHP array to a YAML string.
*
* @param array $value The PHP array to dump
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
*
* @return string The YAML string representing the PHP array
*/
private static function dumpArray($value, $exceptionOnInvalidType,
$objectSupport)
{
// array
if ($value && !self::isHash($value)) {
$output = array();
foreach ($value as $val) {
$output[] = self::dump($val, $exceptionOnInvalidType,
$objectSupport);
}
return sprintf('[%s]', implode(', ',
$output));
}
// hash
$output = array();
foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key,
$exceptionOnInvalidType, $objectSupport), self::dump($val,
$exceptionOnInvalidType, $objectSupport));
}
return sprintf('{ %s }', implode(', ',
$output));
}
/**
* Parses a YAML scalar.
*
* @param string $scalar
* @param string[] $delimiters
* @param string[] $stringDelimiters
* @param int &$i
* @param bool $evaluate
* @param array $references
*
* @return string
*
* @throws ParseException When malformed inline YAML string is parsed
*
* @internal
*/
public static function parseScalar($scalar, $delimiters = null,
$stringDelimiters = array('"', "'"), &$i
= 0, $evaluate = true, $references = array())
{
if (\in_array($scalar[$i], $stringDelimiters)) {
// quoted scalar
$output = self::parseQuotedScalar($scalar, $i);
if (null !== $delimiters) {
$tmp = ltrim(substr($scalar, $i), ' ');
if ('' === $tmp) {
throw new ParseException(sprintf('Unexpected end
of line, expected one of "%s".', implode('',
$delimiters)));
}
if (!\in_array($tmp[0], $delimiters)) {
throw new ParseException(sprintf('Unexpected
characters (%s).', substr($scalar, $i)));
}
}
} else {
// "normal" string
if (!$delimiters) {
$output = substr($scalar, $i);
$i += \strlen($output);
// remove comments
if (Parser::preg_match('/[ \t]+#/', $output,
$match, PREG_OFFSET_CAPTURE)) {
$output = substr($output, 0, $match[0][1]);
}
} elseif
(Parser::preg_match('/^(.+?)('.implode('|',
$delimiters).')/', substr($scalar, $i), $match)) {
$output = $match[1];
$i += \strlen($output);
} else {
throw new ParseException(sprintf('Malformed inline
YAML string: %s.', $scalar));
}
// a non-quoted string cannot start with @ or ` (reserved) nor
with a scalar indicator (| or >)
if ($output && ('@' === $output[0] ||
'`' === $output[0] || '|' === $output[0] ||
'>' === $output[0])) {
@trigger_error(sprintf('Not quoting the scalar
"%s" starting with "%s" is deprecated since Symfony 2.8
and will throw a ParseException in 3.0.', $output, $output[0]),
E_USER_DEPRECATED);
// to be thrown in 3.0
// throw new ParseException(sprintf('The reserved
indicator "%s" cannot start a plain scalar; you need to quote the
scalar.', $output[0]));
}
if ($evaluate) {
$output = self::evaluateScalar($output, $references);
}
}
return $output;
}
/**
* Parses a YAML quoted scalar.
*
* @param string $scalar
* @param int &$i
*
* @return string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseQuotedScalar($scalar, &$i)
{
if
(!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au',
substr($scalar, $i), $match)) {
throw new ParseException(sprintf('Malformed inline YAML
string: %s.', substr($scalar, $i)));
}
$output = substr($match[0], 1, \strlen($match[0]) - 2);
$unescaper = new Unescaper();
if ('"' == $scalar[$i]) {
$output = $unescaper->unescapeDoubleQuotedString($output);
} else {
$output = $unescaper->unescapeSingleQuotedString($output);
}
$i += \strlen($match[0]);
return $output;
}
/**
* Parses a YAML sequence.
*
* @param string $sequence
* @param int &$i
* @param array $references
*
* @return array
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseSequence($sequence, &$i = 0,
$references = array())
{
$output = array();
$len = \strlen($sequence);
++$i;
// [foo, bar, ...]
while ($i < $len) {
switch ($sequence[$i]) {
case '[':
// nested sequence
$output[] = self::parseSequence($sequence, $i,
$references);
break;
case '{':
// nested mapping
$output[] = self::parseMapping($sequence, $i,
$references);
break;
case ']':
return $output;
case ',':
case ' ':
break;
default:
$isQuoted = \in_array($sequence[$i],
array('"', "'"));
$value = self::parseScalar($sequence,
array(',', ']'), array('"',
"'"), $i, true, $references);
// the value can be an array if a reference has been
resolved to an array var
if (!\is_array($value) && !$isQuoted &&
false !== strpos($value, ': ')) {
// embedded mapping?
try {
$pos = 0;
$value =
self::parseMapping('{'.$value.'}', $pos, $references);
} catch (\InvalidArgumentException $e) {
// no, it's not
}
}
$output[] = $value;
--$i;
}
++$i;
}
throw new ParseException(sprintf('Malformed inline YAML
string: %s.', $sequence));
}
/**
* Parses a YAML mapping.
*
* @param string $mapping
* @param int &$i
* @param array $references
*
* @return array|\stdClass
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseMapping($mapping, &$i = 0, $references
= array())
{
$output = array();
$len = \strlen($mapping);
++$i;
$allowOverwrite = false;
// {foo: bar, bar:foo, ...}
while ($i < $len) {
switch ($mapping[$i]) {
case ' ':
case ',':
++$i;
continue 2;
case '}':
if (self::$objectForMap) {
return (object) $output;
}
return $output;
}
// key
$key = self::parseScalar($mapping, array(':', '
'), array('"', "'"), $i, false);
if ('<<' === $key) {
$allowOverwrite = true;
}
// value
$done = false;
while ($i < $len) {
switch ($mapping[$i]) {
case '[':
// nested sequence
$value = self::parseSequence($mapping, $i,
$references);
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since
lines
// are processed sequentially.
// But overwriting is allowed when a merge node is
used in current block.
if ('<<' === $key) {
foreach ($value as $parsedValue) {
$output += $parsedValue;
}
} elseif ($allowOverwrite || !isset($output[$key]))
{
$output[$key] = $value;
}
$done = true;
break;
case '{':
// nested mapping
$value = self::parseMapping($mapping, $i,
$references);
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since
lines
// are processed sequentially.
// But overwriting is allowed when a merge node is
used in current block.
if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key]))
{
$output[$key] = $value;
}
$done = true;
break;
case ':':
case ' ':
break;
default:
$value = self::parseScalar($mapping,
array(',', '}'), array('"',
"'"), $i, true, $references);
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since
lines
// are processed sequentially.
// But overwriting is allowed when a merge node is
used in current block.
if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key]))
{
$output[$key] = $value;
}
$done = true;
--$i;
}
++$i;
if ($done) {
continue 2;
}
}
}
throw new ParseException(sprintf('Malformed inline YAML
string: %s.', $mapping));
}
/**
* Evaluates scalars and replaces magic values.
*
* @param string $scalar
* @param array $references
*
* @return mixed The evaluated YAML string
*
* @throws ParseException when object parsing support was disabled and
the parser detected a PHP object or when a reference could not be resolved
*/
private static function evaluateScalar($scalar, $references = array())
{
$scalar = trim($scalar);
$scalarLower = strtolower($scalar);
if (0 === strpos($scalar, '*')) {
if (false !== $pos = strpos($scalar, '#')) {
$value = substr($scalar, 1, $pos - 2);
} else {
$value = substr($scalar, 1);
}
// an unquoted *
if (false === $value || '' === $value) {
throw new ParseException('A reference must contain at
least one character.');
}
if (!array_key_exists($value, $references)) {
throw new ParseException(sprintf('Reference
"%s" does not exist.', $value));
}
return $references[$value];
}
switch (true) {
case 'null' === $scalarLower:
case '' === $scalar:
case '~' === $scalar:
return;
case 'true' === $scalarLower:
return true;
case 'false' === $scalarLower:
return false;
// Optimise for returning strings.
case '+' === $scalar[0] || '-' ===
$scalar[0] || '.' === $scalar[0] || '!' === $scalar[0]
|| is_numeric($scalar[0]):
switch (true) {
case 0 === strpos($scalar, '!str'):
return (string) substr($scalar, 5);
case 0 === strpos($scalar, '! '):
return (int) self::parseScalar(substr($scalar, 2));
case 0 === strpos($scalar, '!php/object:'):
if (self::$objectSupport) {
return unserialize(substr($scalar, 12));
}
if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support
when parsing a YAML file has been disabled.');
}
return;
case 0 === strpos($scalar, '!!php/object:'):
if (self::$objectSupport) {
return unserialize(substr($scalar, 13));
}
if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support
when parsing a YAML file has been disabled.');
}
return;
case 0 === strpos($scalar, '!!float '):
return (float) substr($scalar, 8);
case ctype_digit($scalar):
$raw = $scalar;
$cast = (int) $scalar;
return '0' == $scalar[0] ?
octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case '-' === $scalar[0] &&
ctype_digit(substr($scalar, 1)):
$raw = $scalar;
$cast = (int) $scalar;
return '0' == $scalar[1] ?
octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
case is_numeric($scalar):
case Parser::preg_match(self::getHexRegex(), $scalar):
return '0x' === $scalar[0].$scalar[1] ?
hexdec($scalar) : (float) $scalar;
case '.inf' === $scalarLower:
case '.nan' === $scalarLower:
return -log(0);
case '-.inf' === $scalarLower:
return log(0);
case
Parser::preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
return (float) str_replace(',',
'', $scalar);
case Parser::preg_match(self::getTimestampRegex(),
$scalar):
$timeZone = date_default_timezone_get();
date_default_timezone_set('UTC');
$time = strtotime($scalar);
date_default_timezone_set($timeZone);
return $time;
}
// no break
default:
return (string) $scalar;
}
}
/**
* Gets a regex that matches a YAML date.
*
* @return string The regular expression
*
* @see http://www.yaml.org/spec/1.2/spec.html#id2761573
*/
private static function getTimestampRegex()
{
return <<<EOF
~^
(?P<year>[0-9][0-9][0-9][0-9])
-(?P<month>[0-9][0-9]?)
-(?P<day>[0-9][0-9]?)
(?:(?:[Tt]|[ \t]+)
(?P<hour>[0-9][0-9]?)
:(?P<minute>[0-9][0-9])
:(?P<second>[0-9][0-9])
(?:\.(?P<fraction>[0-9]*))?
(?:[
\t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
(?::(?P<tz_minute>[0-9][0-9]))?))?)?
$~x
EOF;
}
/**
* Gets a regex that matches a YAML number in hexadecimal notation.
*
* @return string
*/
private static function getHexRegex()
{
return '~^0x[0-9a-f]++$~i';
}
}
yaml/LICENSE000064400000002051151166602300006511 0ustar00Copyright (c)
2004-2018 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
in the Software without restriction, including without limitation the
rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
yaml/Parser.php000064400000100467151166602300007463 0ustar00<?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;
/**
* Parser parses YAML strings to convert them to PHP arrays.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Parser
{
const BLOCK_SCALAR_HEADER_PATTERN =
'(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments>
+#.*)?';
// BC - wrongly named
const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;
private $offset = 0;
private $totalNumberOfLines;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
private $refs = array();
private $skippedLineNumbers = array();
private $locallySkippedLineNumbers = array();
/**
* @param int $offset The offset of YAML document
(used for line numbers in error messages)
* @param int|null $totalNumberOfLines The overall number of lines
being parsed
* @param int[] $skippedLineNumbers Number of comment lines that
have been skipped by the parser
*/
public function __construct($offset = 0, $totalNumberOfLines = null,
array $skippedLineNumbers = array())
{
$this->offset = $offset;
$this->totalNumberOfLines = $totalNumberOfLines;
$this->skippedLineNumbers = $skippedLineNumbers;
}
/**
* Parses a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
* @param bool $objectForMap True if maps should return a
stdClass instead of array()
*
* @return mixed A PHP value
*
* @throws ParseException If the YAML is not valid
*/
public function parse($value, $exceptionOnInvalidType = false,
$objectSupport = false, $objectForMap = false)
{
if (false === preg_match('//u', $value)) {
throw new ParseException('The YAML value does not appear
to be valid UTF-8.');
}
$this->refs = array();
$mbEncoding = null;
$e = null;
$data = null;
if (2 /* MB_OVERLOAD_STRING */ & (int)
ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}
try {
$data = $this->doParse($value, $exceptionOnInvalidType,
$objectSupport, $objectForMap);
} catch (\Exception $e) {
} catch (\Throwable $e) {
}
if (null !== $mbEncoding) {
mb_internal_encoding($mbEncoding);
}
$this->lines = array();
$this->currentLine = '';
$this->refs = array();
$this->skippedLineNumbers = array();
$this->locallySkippedLineNumbers = array();
if (null !== $e) {
throw $e;
}
return $data;
}
private function doParse($value, $exceptionOnInvalidType = false,
$objectSupport = false, $objectForMap = false)
{
$this->currentLineNb = -1;
$this->currentLine = '';
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
$this->locallySkippedLineNumbers = array();
if (null === $this->totalNumberOfLines) {
$this->totalNumberOfLines = \count($this->lines);
}
$data = array();
$context = null;
$allowOverwrite = false;
while ($this->moveToNextLine()) {
if ($this->isCurrentLineEmpty()) {
continue;
}
// tab?
if ("\t" === $this->currentLine[0]) {
throw new ParseException('A YAML file cannot contain
tabs as indentation.', $this->getRealCurrentLineNb() + 1,
$this->currentLine);
}
$isRef = $mergeNode = false;
if
(self::preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+))?$#u',
rtrim($this->currentLine), $values)) {
if ($context && 'mapping' == $context) {
throw new ParseException('You cannot define a
sequence item when in a mapping', $this->getRealCurrentLineNb() +
1, $this->currentLine);
}
$context = 'sequence';
if (isset($values['value']) &&
self::preg_match('#^&(?P<ref>[^ ]+)
*(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] =
$matches['value'];
}
// array
if (!isset($values['value']) || '' ==
trim($values['value'], ' ') || 0 ===
strpos(ltrim($values['value'], ' '), '#')) {
$data[] =
$this->parseBlock($this->getRealCurrentLineNb() + 1,
$this->getNextEmbedBlock(null, true), $exceptionOnInvalidType,
$objectSupport, $objectForMap);
} else {
if (isset($values['leadspaces'])
&&
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^
\'"\{\[].*?) *\:(\s+(?P<value>.+))?$#u',
rtrim($values['value']), $matches)
) {
// this is a compact notation element, add to next
block and parse
$block = $values['value'];
if ($this->isNextLineIndented()) {
$block .=
"\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation()
+ \strlen($values['leadspaces']) + 1);
}
$data[] =
$this->parseBlock($this->getRealCurrentLineNb(), $block,
$exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
$data[] =
$this->parseValue($values['value'], $exceptionOnInvalidType,
$objectSupport, $objectForMap, $context);
}
}
if ($isRef) {
$this->refs[$isRef] = end($data);
}
} elseif (
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^
\'"\[\{].*?) *\:(\s+(?P<value>.+))?$#u',
rtrim($this->currentLine), $values)
&& (false === strpos($values['key'],
' #') || \in_array($values['key'][0],
array('"', "'")))
) {
if ($context && 'sequence' == $context) {
throw new ParseException('You cannot define a
mapping item when in a sequence', $this->currentLineNb + 1,
$this->currentLine);
}
$context = 'mapping';
// force correct settings
Inline::parse(null, $exceptionOnInvalidType,
$objectSupport, $objectForMap, $this->refs);
try {
$key = Inline::parseScalar($values['key']);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() +
1);
$e->setSnippet($this->currentLine);
throw $e;
}
// Convert float keys to strings, to avoid being converted
to integers by PHP
if (\is_float($key)) {
$key = (string) $key;
}
if ('<<' === $key &&
(!isset($values['value']) ||
!self::preg_match('#^&(?P<ref>[^ ]+)#u',
$values['value'], $refMatches))) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 ===
strpos($values['value'], '*')) {
$refName = substr($values['value'], 1);
if (!array_key_exists($refName, $this->refs)) {
throw new
ParseException(sprintf('Reference "%s" does not
exist.', $refName), $this->getRealCurrentLineNb() + 1,
$this->currentLine);
}
$refValue = $this->refs[$refName];
if (!\is_array($refValue)) {
throw new ParseException('YAML merge keys
used with a scalar value instead of an array.',
$this->getRealCurrentLineNb() + 1, $this->currentLine);
}
$data += $refValue; // array union
} else {
if (isset($values['value']) &&
'' !== $values['value']) {
$value = $values['value'];
} else {
$value = $this->getNextEmbedBlock();
}
$parsed =
$this->parseBlock($this->getRealCurrentLineNb() + 1, $value,
$exceptionOnInvalidType, $objectSupport, $objectForMap);
if (!\is_array($parsed)) {
throw new ParseException('YAML merge keys
used with a scalar value instead of an array.',
$this->getRealCurrentLineNb() + 1, $this->currentLine);
}
if (isset($parsed[0])) {
// If the value associated with the merge key
is a sequence, then this sequence is expected to contain mapping nodes
// and each of these nodes is merged in turn
according to its order in the sequence. Keys in mapping nodes earlier
// in the sequence override keys specified in
later mapping nodes.
foreach ($parsed as $parsedItem) {
if (!\is_array($parsedItem)) {
throw new ParseException('Merge
items must be arrays.', $this->getRealCurrentLineNb() + 1,
$parsedItem);
}
$data += $parsedItem; // array union
}
} else {
// If the value associated with the key is a
single mapping node, each of its key/value pairs is inserted into the
// current mapping, unless the key already
exists in it.
$data += $parsed; // array union
}
}
} elseif ('<<' !== $key &&
isset($values['value']) &&
self::preg_match('#^&(?P<ref>[^ ]+)
*(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] =
$matches['value'];
}
if ($mergeNode) {
// Merge keys
} elseif (!isset($values['value']) ||
'' == trim($values['value'], ' ') || 0 ===
strpos(ltrim($values['value'], ' '), '#') ||
'<<' === $key) {
// hash
// if next line is less indented or equal, then it
means that the current value is null
if (!$this->isNextLineIndented() &&
!$this->isNextLineUnIndentedCollection()) {
// Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node is
used in current block.
if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = null;
}
} else {
$value =
$this->parseBlock($this->getRealCurrentLineNb() + 1,
$this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport,
$objectForMap);
if ('<<' === $key) {
$this->refs[$refMatches['ref']] =
$value;
$data += $value;
} elseif ($allowOverwrite || !isset($data[$key])) {
// Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node
is used in current block.
$data[$key] = $value;
}
}
} else {
$value =
$this->parseValue($values['value'], $exceptionOnInvalidType,
$objectSupport, $objectForMap, $context);
// Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node is used
in current block.
if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
}
}
if ($isRef) {
$this->refs[$isRef] = $data[$key];
}
} else {
// multiple documents are not supported
if ('---' === $this->currentLine) {
throw new ParseException('Multiple documents are
not supported.', $this->currentLineNb + 1, $this->currentLine);
}
// 1-liner optionally followed by newline(s)
if (\is_string($value) && $this->lines[0] ===
trim($value)) {
try {
$value = Inline::parse($this->lines[0],
$exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
return $value;
}
throw new ParseException('Unable to parse.',
$this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}
if ($objectForMap && !\is_object($data) &&
'mapping' === $context) {
$object = new \stdClass();
foreach ($data as $key => $value) {
$object->$key = $value;
}
$data = $object;
}
return empty($data) ? null : $data;
}
private function parseBlock($offset, $yaml, $exceptionOnInvalidType,
$objectSupport, $objectForMap)
{
$skippedLineNumbers = $this->skippedLineNumbers;
foreach ($this->locallySkippedLineNumbers as $lineNumber) {
if ($lineNumber < $offset) {
continue;
}
$skippedLineNumbers[] = $lineNumber;
}
$parser = new self($offset, $this->totalNumberOfLines,
$skippedLineNumbers);
$parser->refs = &$this->refs;
return $parser->doParse($yaml, $exceptionOnInvalidType,
$objectSupport, $objectForMap);
}
/**
* Returns the current line number (takes the offset into account).
*
* @return int The current line number
*/
private function getRealCurrentLineNb()
{
$realCurrentLineNumber = $this->currentLineNb +
$this->offset;
foreach ($this->skippedLineNumbers as $skippedLineNumber) {
if ($skippedLineNumber > $realCurrentLineNumber) {
break;
}
++$realCurrentLineNumber;
}
return $realCurrentLineNumber;
}
/**
* Returns the current line indentation.
*
* @return int The current line indentation
*/
private function getCurrentLineIndentation()
{
return \strlen($this->currentLine) -
\strlen(ltrim($this->currentLine, ' '));
}
/**
* Returns the next embed block of YAML.
*
* @param int $indentation The indent level at which the block is to
be read, or null for default
* @param bool $inSequence True if the enclosing data structure is a
sequence
*
* @return string A YAML string
*
* @throws ParseException When indentation problem are detected
*/
private function getNextEmbedBlock($indentation = null, $inSequence =
false)
{
$oldLineIndentation = $this->getCurrentLineIndentation();
$blockScalarIndentations = array();
if ($this->isBlockScalarHeader()) {
$blockScalarIndentations[] =
$this->getCurrentLineIndentation();
}
if (!$this->moveToNextLine()) {
return;
}
if (null === $indentation) {
$newIndent = $this->getCurrentLineIndentation();
$unindentedEmbedBlock =
$this->isStringUnIndentedCollectionItem();
if (!$this->isCurrentLineEmpty() && 0 === $newIndent
&& !$unindentedEmbedBlock) {
throw new ParseException('Indentation problem.',
$this->getRealCurrentLineNb() + 1, $this->currentLine);
}
} else {
$newIndent = $indentation;
}
$data = array();
if ($this->getCurrentLineIndentation() >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} else {
$this->moveToPreviousLine();
return;
}
if ($inSequence && $oldLineIndentation === $newIndent
&& isset($data[0][0]) && '-' === $data[0][0]) {
// the previous line contained a dash but no item content, this
line is a sequence item with the same indentation
// and therefore no nested list or mapping
$this->moveToPreviousLine();
return;
}
$isItUnindentedCollection =
$this->isStringUnIndentedCollectionItem();
if (empty($blockScalarIndentations) &&
$this->isBlockScalarHeader()) {
$blockScalarIndentations[] =
$this->getCurrentLineIndentation();
}
$previousLineIndentation = $this->getCurrentLineIndentation();
while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation();
// terminate all block scalars that are more indented than the
current line
if (!empty($blockScalarIndentations) && $indent <
$previousLineIndentation && '' !==
trim($this->currentLine)) {
foreach ($blockScalarIndentations as $key =>
$blockScalarIndentation) {
if ($blockScalarIndentation >=
$this->getCurrentLineIndentation()) {
unset($blockScalarIndentations[$key]);
}
}
}
if (empty($blockScalarIndentations) &&
!$this->isCurrentLineComment() &&
$this->isBlockScalarHeader()) {
$blockScalarIndentations[] =
$this->getCurrentLineIndentation();
}
$previousLineIndentation = $indent;
if ($isItUnindentedCollection &&
!$this->isCurrentLineEmpty() &&
!$this->isStringUnIndentedCollectionItem() && $newIndent ===
$indent) {
$this->moveToPreviousLine();
break;
}
if ($this->isCurrentLineBlank()) {
$data[] = substr($this->currentLine, $newIndent);
continue;
}
// we ignore "comment" lines only when we are not
inside a scalar block
if (empty($blockScalarIndentations) &&
$this->isCurrentLineComment()) {
// remember ignored comment lines (they are used later in
nested
// parser calls to determine real line numbers)
//
// CAUTION: beware to not populate the global property here
as it
// will otherwise influence the getRealCurrentLineNb() call
here
// for consecutive comment lines and subsequent embedded
blocks
$this->locallySkippedLineNumbers[] =
$this->getRealCurrentLineNb();
continue;
}
if ($indent >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} elseif (0 == $indent) {
$this->moveToPreviousLine();
break;
} else {
throw new ParseException('Indentation problem.',
$this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}
return implode("\n", $data);
}
/**
* Moves the parser to the next line.
*
* @return bool
*/
private function moveToNextLine()
{
if ($this->currentLineNb >= \count($this->lines) - 1) {
return false;
}
$this->currentLine = $this->lines[++$this->currentLineNb];
return true;
}
/**
* Moves the parser to the previous line.
*
* @return bool
*/
private function moveToPreviousLine()
{
if ($this->currentLineNb < 1) {
return false;
}
$this->currentLine = $this->lines[--$this->currentLineNb];
return true;
}
/**
* Parses a YAML value.
*
* @param string $value A YAML value
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
* @param bool $objectForMap True if maps should return a
stdClass instead of array()
* @param string $context The parser context (either
sequence or mapping)
*
* @return mixed A PHP value
*
* @throws ParseException When reference does not exist
*/
private function parseValue($value, $exceptionOnInvalidType,
$objectSupport, $objectForMap, $context)
{
if (0 === strpos($value, '*')) {
if (false !== $pos = strpos($value, '#')) {
$value = substr($value, 1, $pos - 2);
} else {
$value = substr($value, 1);
}
if (!array_key_exists($value, $this->refs)) {
throw new ParseException(sprintf('Reference
"%s" does not exist.', $value), $this->currentLineNb + 1,
$this->currentLine);
}
return $this->refs[$value];
}
if
(self::preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/',
$value, $matches)) {
$modifiers = isset($matches['modifiers']) ?
$matches['modifiers'] : '';
return
$this->parseBlockScalar($matches['separator'],
preg_replace('#\d+#', '', $modifiers), (int)
abs($modifiers));
}
try {
$parsedValue = Inline::parse($value, $exceptionOnInvalidType,
$objectSupport, $objectForMap, $this->refs);
if ('mapping' === $context &&
'"' !== $value[0] && "'" !==
$value[0] && '[' !== $value[0] && '{'
!== $value[0] && '!' !== $value[0] && false !==
strpos($parsedValue, ': ')) {
@trigger_error(sprintf('Using a colon in the unquoted
mapping value "%s" in line %d is deprecated since Symfony 2.8 and
will throw a ParseException in 3.0.', $value,
$this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
// to be thrown in 3.0
// throw new ParseException('A colon cannot be used in
an unquoted mapping value.');
}
return $parsedValue;
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
}
/**
* Parses a block scalar.
*
* @param string $style The style indicator that was used to
begin this block scalar (| or >)
* @param string $chomping The chomping indicator that was used to
begin this block scalar (+ or -)
* @param int $indentation The indentation indicator that was used
to begin this block scalar
*
* @return string The text value
*/
private function parseBlockScalar($style, $chomping = '',
$indentation = 0)
{
$notEOF = $this->moveToNextLine();
if (!$notEOF) {
return '';
}
$isCurrentLineBlank = $this->isCurrentLineBlank();
$blockLines = array();
// leading blank lines are consumed before determining indentation
while ($notEOF && $isCurrentLineBlank) {
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$blockLines[] = '';
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
// determine indentation if not specified
if (0 === $indentation) {
if (self::preg_match('/^ +/', $this->currentLine,
$matches)) {
$indentation = \strlen($matches[0]);
}
}
if ($indentation > 0) {
$pattern = sprintf('/^ {%d}(.*)$/', $indentation);
while (
$notEOF && (
$isCurrentLineBlank ||
self::preg_match($pattern, $this->currentLine,
$matches)
)
) {
if ($isCurrentLineBlank &&
\strlen($this->currentLine) > $indentation) {
$blockLines[] = substr($this->currentLine,
$indentation);
} elseif ($isCurrentLineBlank) {
$blockLines[] = '';
} else {
$blockLines[] = $matches[1];
}
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
} elseif ($notEOF) {
$blockLines[] = '';
}
if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
} elseif (!$notEOF &&
!$this->isCurrentLineLastLineInDocument()) {
$blockLines[] = '';
}
// folded style
if ('>' === $style) {
$text = '';
$previousLineIndented = false;
$previousLineBlank = false;
for ($i = 0, $blockLinesCount = \count($blockLines); $i <
$blockLinesCount; ++$i) {
if ('' === $blockLines[$i]) {
$text .= "\n";
$previousLineIndented = false;
$previousLineBlank = true;
} elseif (' ' === $blockLines[$i][0]) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = true;
$previousLineBlank = false;
} elseif ($previousLineIndented) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} elseif ($previousLineBlank || 0 === $i) {
$text .= $blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} else {
$text .= ' '.$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
}
}
} else {
$text = implode("\n", $blockLines);
}
// deal with trailing newlines
if ('' === $chomping) {
$text = preg_replace('/\n+$/', "\n",
$text);
} elseif ('-' === $chomping) {
$text = preg_replace('/\n+$/', '', $text);
}
return $text;
}
/**
* Returns true if the next line is indented.
*
* @return bool Returns true if the next line is indented, false
otherwise
*/
private function isNextLineIndented()
{
$currentIndentation = $this->getCurrentLineIndentation();
$EOF = !$this->moveToNextLine();
while (!$EOF && $this->isCurrentLineEmpty()) {
$EOF = !$this->moveToNextLine();
}
if ($EOF) {
return false;
}
$ret = $this->getCurrentLineIndentation() >
$currentIndentation;
$this->moveToPreviousLine();
return $ret;
}
/**
* Returns true if the current line is blank or if it is a comment
line.
*
* @return bool Returns true if the current line is empty or if it is a
comment line, false otherwise
*/
private function isCurrentLineEmpty()
{
return $this->isCurrentLineBlank() ||
$this->isCurrentLineComment();
}
/**
* Returns true if the current line is blank.
*
* @return bool Returns true if the current line is blank, false
otherwise
*/
private function isCurrentLineBlank()
{
return '' == trim($this->currentLine, ' ');
}
/**
* Returns true if the current line is a comment line.
*
* @return bool Returns true if the current line is a comment line,
false otherwise
*/
private function isCurrentLineComment()
{
//checking explicitly the first char of the trim is faster than
loops or strpos
$ltrimmedLine = ltrim($this->currentLine, ' ');
return '' !== $ltrimmedLine && '#' ===
$ltrimmedLine[0];
}
private function isCurrentLineLastLineInDocument()
{
return ($this->offset + $this->currentLineNb) >=
($this->totalNumberOfLines - 1);
}
/**
* Cleanups a YAML string to be parsed.
*
* @param string $value The input YAML string
*
* @return string A cleaned up YAML string
*/
private function cleanup($value)
{
$value = str_replace(array("\r\n", "\r"),
"\n", $value);
// strip YAML header
$count = 0;
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u',
'', $value, -1, $count);
$this->offset += $count;
// remove leading comments
$trimmedValue = preg_replace('#^(\#.*?\n)+#s',
'', $value, -1, $count);
if (1 == $count) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") -
substr_count($trimmedValue, "\n");
$value = $trimmedValue;
}
// remove start of the document marker (---)
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s',
'', $value, -1, $count);
if (1 == $count) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") -
substr_count($trimmedValue, "\n");
$value = $trimmedValue;
// remove end of the document marker (...)
$value = preg_replace('#\.\.\.\s*$#', '',
$value);
}
return $value;
}
/**
* Returns true if the next line starts unindented collection.
*
* @return bool Returns true if the next line starts unindented
collection, false otherwise
*/
private function isNextLineUnIndentedCollection()
{
$currentIndentation = $this->getCurrentLineIndentation();
$notEOF = $this->moveToNextLine();
while ($notEOF && $this->isCurrentLineEmpty()) {
$notEOF = $this->moveToNextLine();
}
if (false === $notEOF) {
return false;
}
$ret = $this->getCurrentLineIndentation() ===
$currentIndentation &&
$this->isStringUnIndentedCollectionItem();
$this->moveToPreviousLine();
return $ret;
}
/**
* Returns true if the string is un-indented collection item.
*
* @return bool Returns true if the string is un-indented collection
item, false otherwise
*/
private function isStringUnIndentedCollectionItem()
{
return '-' === rtrim($this->currentLine) || 0 ===
strpos($this->currentLine, '- ');
}
/**
* Tests whether or not the current line is the header of a block
scalar.
*
* @return bool
*/
private function isBlockScalarHeader()
{
return (bool)
self::preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~',
$this->currentLine);
}
/**
* A local wrapper for `preg_match` which will throw a ParseException
if there
* is an internal error in the PCRE engine.
*
* This avoids us needing to check for "false" every time
PCRE is used
* in the YAML engine
*
* @throws ParseException on a PCRE internal error
*
* @see preg_last_error()
*
* @internal
*/
public static function preg_match($pattern, $subject, &$matches =
null, $flags = 0, $offset = 0)
{
if (false === $ret = preg_match($pattern, $subject, $matches,
$flags, $offset)) {
switch (preg_last_error()) {
case PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error.';
break;
case PREG_BACKTRACK_LIMIT_ERROR:
$error = 'pcre.backtrack_limit reached.';
break;
case PREG_RECURSION_LIMIT_ERROR:
$error = 'pcre.recursion_limit reached.';
break;
case PREG_BAD_UTF8_ERROR:
$error = 'Malformed UTF-8 data.';
break;
case PREG_BAD_UTF8_OFFSET_ERROR:
$error = 'Offset doesn\'t correspond to the
begin of a valid UTF-8 code point.';
break;
default:
$error = 'Error.';
}
throw new ParseException($error);
}
return $ret;
}
}
yaml/Unescaper.php000064400000010516151166602300010147 0ustar00<?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;
/**
* Unescaper encapsulates unescaping rules for single and double-quoted
* YAML strings.
*
* @author Matthew Lewinski <matthew@lewinski.org>
*
* @internal
*/
class Unescaper
{
/**
* Parser and Inline assume UTF-8 encoding, so escaped Unicode
characters
* must be converted to that encoding.
*
* @deprecated since version 2.5, to be removed in 3.0
*
* @internal
*/
const ENCODING = 'UTF-8';
/**
* 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($value)
{
return str_replace('\'\'', '\'',
$value);
}
/**
* Unescapes a double quoted string.
*
* @param string $value A double quoted string
*
* @return string The unescaped string
*/
public function unescapeDoubleQuotedString($value)
{
$self = $this;
$callback = function ($match) use ($self) {
return $self->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
*
* @internal This method is public to be usable as callback. It should
not
* be used in user code. Should be changed in 3.0.
*/
public function unescapeCharacter($value)
{
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:
@trigger_error('Not escaping a backslash in a
double-quoted string is deprecated since Symfony 2.8 and will throw a
ParseException in 3.0.', E_USER_DEPRECATED);
return $value;
}
}
/**
* Get the UTF-8 character for the given code point.
*
* @param int $c The unicode code point
*
* @return string The corresponding UTF-8 character
*/
private static function utf8chr($c)
{
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);
}
}
yaml/Yaml.php000064400000007327151166602300007132 0ustar00<?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;
/**
* Yaml offers convenience methods to load and dump YAML.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Yaml
{
/**
* Parses YAML into a PHP value.
*
* Usage:
*
* $array = Yaml::parse(file_get_contents('config.yml'));
* print_r($array);
*
* As this method accepts both plain strings and file names as an
input,
* you must validate the input before calling this method. Passing a
file
* as an input is a deprecated feature and will be removed in 3.0.
*
* Note: the ability to pass file names to the Yaml::parse method is
deprecated since Symfony 2.2 and will be removed in 3.0. Pass the YAML
contents of the file instead.
*
* @param string $input Path to a YAML file or a
string containing YAML
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
* @param bool $objectForMap True if maps should return a
stdClass instead of array()
*
* @return mixed The YAML converted to a PHP value
*
* @throws ParseException If the YAML is not valid
*/
public static function parse($input, $exceptionOnInvalidType = false,
$objectSupport = false, $objectForMap = false)
{
// if input is a file, process it
$file = '';
if (false === strpos($input, "\n") &&
is_file($input)) {
@trigger_error('The ability to pass file names to the
'.__METHOD__.' method is deprecated since Symfony 2.2 and will be
removed in 3.0. Pass the YAML contents of the file instead.',
E_USER_DEPRECATED);
if (false === is_readable($input)) {
throw new ParseException(sprintf('Unable to parse
"%s" as the file is not readable.', $input));
}
$file = $input;
$input = file_get_contents($file);
}
$yaml = new Parser();
try {
return $yaml->parse($input, $exceptionOnInvalidType,
$objectSupport, $objectForMap);
} catch (ParseException $e) {
if ($file) {
$e->setParsedFile($file);
}
throw $e;
}
}
/**
* Dumps a PHP value to a YAML string.
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML.
*
* @param mixed $input The PHP value
* @param int $inline The level where you switch to
inline YAML
* @param int $indent The amount of spaces to use for
indentation of nested nodes
* @param bool $exceptionOnInvalidType True if an exception must be
thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is
enabled, false otherwise
*
* @return string A YAML string representing the original PHP value
*/
public static function dump($input, $inline = 2, $indent = 4,
$exceptionOnInvalidType = false, $objectSupport = false)
{
if ($indent < 1) {
throw new \InvalidArgumentException('The indentation must
be greater than zero.');
}
$yaml = new Dumper();
$yaml->setIndentation($indent);
return $yaml->dump($input, $inline, 0, $exceptionOnInvalidType,
$objectSupport);
}
}