Mercurial > hg > isophonics-drupal-site
diff vendor/symfony/yaml/Inline.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 7a779792577d |
children | c2387f117808 |
line wrap: on
line diff
--- a/vendor/symfony/yaml/Inline.php Mon Apr 23 09:33:26 2018 +0100 +++ b/vendor/symfony/yaml/Inline.php Mon Apr 23 09:46:53 2018 +0100 @@ -13,6 +13,7 @@ use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Exception\DumpException; +use Symfony\Component\Yaml\Tag\TaggedValue; /** * Inline implements a YAML parser/dumper for the YAML inline syntax. @@ -25,7 +26,8 @@ { const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; - public static $parsedLineNumber; + public static $parsedLineNumber = -1; + public static $parsedFilename; private static $exceptionOnInvalidType = false; private static $objectSupport = false; @@ -33,6 +35,24 @@ private static $constantSupport = false; /** + * @param int $flags + * @param int|null $parsedLineNumber + * @param string|null $parsedFilename + */ + public static function initialize($flags, $parsedLineNumber = null, $parsedFilename = null) + { + self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); + self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); + self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); + self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); + self::$parsedFilename = $parsedFilename; + + if (null !== $parsedLineNumber) { + self::$parsedLineNumber = $parsedLineNumber; + } + } + + /** * Converts a YAML string to a PHP value. * * @param string $value A YAML string @@ -46,7 +66,7 @@ public static function parse($value, $flags = 0, $references = array()) { if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); if ($flags) { $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; @@ -56,14 +76,14 @@ } if (func_num_args() >= 3 && !is_array($references)) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); if ($references) { $flags |= Yaml::PARSE_OBJECT; } if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); if (func_get_arg(3)) { $flags |= Yaml::PARSE_OBJECT_FOR_MAP; @@ -77,10 +97,7 @@ } } - self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); - self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); - self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); - self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); + self::initialize($flags); $value = trim($value); @@ -94,7 +111,8 @@ } $i = 0; - switch ($value[0]) { + $tag = self::parseTag($value, $i, $flags); + switch ($value[$i]) { case '[': $result = self::parseSequence($value, $flags, $i, $references); ++$i; @@ -104,12 +122,16 @@ ++$i; break; default: - $result = self::parseScalar($value, $flags, null, array('"', "'"), $i, true, $references); + $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); + } + + if (null !== $tag) { + return new TaggedValue($tag, $result); } // 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))); + throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename); } if (isset($mbEncoding)) { @@ -132,7 +154,7 @@ public static function dump($value, $flags = 0) { if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); if ($flags) { $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; @@ -142,7 +164,7 @@ } if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); if (func_get_arg(2)) { $flags |= Yaml::DUMP_OBJECT; @@ -159,12 +181,16 @@ case $value instanceof \DateTimeInterface: return $value->format('c'); case is_object($value): + if ($value instanceof TaggedValue) { + return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags); + } + if (Yaml::DUMP_OBJECT & $flags) { - return '!php/object:'.serialize($value); + return '!php/object '.self::dump(serialize($value)); } if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { - return self::dumpArray($value, $flags); + return self::dumpArray($value, $flags & ~Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE); } if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { @@ -256,7 +282,7 @@ private static function dumpArray($value, $flags) { // array - if ($value && !self::isHash($value)) { + if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) { $output = array(); foreach ($value as $val) { $output[] = self::dump($val, $flags); @@ -280,7 +306,6 @@ * @param string $scalar * @param int $flags * @param string[] $delimiters - * @param string[] $stringDelimiters * @param int &$i * @param bool $evaluate * @param array $references @@ -291,16 +316,16 @@ * * @internal */ - public static function parseScalar($scalar, $flags = 0, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array()) + public static function parseScalar($scalar, $flags = 0, $delimiters = null, &$i = 0, $evaluate = true, $references = array(), $legacyOmittedKeySupport = false) { - if (in_array($scalar[$i], $stringDelimiters)) { + if (in_array($scalar[$i], array('"', "'"))) { // quoted scalar $output = self::parseQuotedScalar($scalar, $i); if (null !== $delimiters) { $tmp = ltrim(substr($scalar, $i), ' '); if (!in_array($tmp[0], $delimiters)) { - throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); + throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } } } else { @@ -313,20 +338,20 @@ 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)) { + } elseif (Parser::preg_match('/^(.'.($legacyOmittedKeySupport ? '+' : '*').'?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { $output = $match[1]; $i += strlen($output); } else { - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar)); + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename); } // 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])) { - throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); + throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename); } if ($output && '%' === $output[0]) { - @trigger_error(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', $output), E_USER_DEPRECATED); + @trigger_error(self::getDeprecationMessage(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', $output)), E_USER_DEPRECATED); } if ($evaluate) { @@ -350,7 +375,7 @@ 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))); + throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } $output = substr($match[0], 1, strlen($match[0]) - 2); @@ -387,23 +412,28 @@ // [foo, bar, ...] while ($i < $len) { + if (']' === $sequence[$i]) { + return $output; + } + if (',' === $sequence[$i] || ' ' === $sequence[$i]) { + ++$i; + + continue; + } + + $tag = self::parseTag($sequence, $i, $flags); switch ($sequence[$i]) { case '[': // nested sequence - $output[] = self::parseSequence($sequence, $flags, $i, $references); + $value = self::parseSequence($sequence, $flags, $i, $references); break; case '{': // nested mapping - $output[] = self::parseMapping($sequence, $flags, $i, $references); - break; - case ']': - return $output; - case ',': - case ' ': + $value = self::parseMapping($sequence, $flags, $i, $references); break; default: $isQuoted = in_array($sequence[$i], array('"', "'")); - $value = self::parseScalar($sequence, $flags, array(',', ']'), array('"', "'"), $i, true, $references); + $value = self::parseScalar($sequence, $flags, array(',', ']'), $i, null === $tag, $references); // the value can be an array if a reference has been resolved to an array var if (is_string($value) && !$isQuoted && false !== strpos($value, ': ')) { @@ -416,15 +446,19 @@ } } - $output[] = $value; - --$i; } + if (null !== $tag) { + $value = new TaggedValue($tag, $value); + } + + $output[] = $value; + ++$i; } - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence)); + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename); } /** @@ -444,6 +478,7 @@ $output = array(); $len = strlen($mapping); ++$i; + $allowOverwrite = false; // {foo: bar, bar:foo, ...} while ($i < $len) { @@ -462,20 +497,40 @@ // key $isKeyQuoted = in_array($mapping[$i], array('"', "'"), true); - $key = self::parseScalar($mapping, $flags, array(':', ' '), array('"', "'"), $i, false); + $key = self::parseScalar($mapping, $flags, array(':', ' '), $i, false, array(), true); if (':' !== $key && false === $i = strpos($mapping, ':', $i)) { break; } - if (':' !== $key && !$isKeyQuoted && (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) { - @trigger_error('Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since version 3.2 and will throw a ParseException in 4.0.', E_USER_DEPRECATED); + if (':' === $key) { + @trigger_error(self::getDeprecationMessage('Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0.'), E_USER_DEPRECATED); } - // value - $done = false; + if (!$isKeyQuoted) { + $evaluatedKey = self::evaluateScalar($key, $flags, $references); + + if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey) && !is_int($evaluatedKey)) { + @trigger_error(self::getDeprecationMessage('Implicit casting of incompatible mapping keys to strings is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead.'), E_USER_DEPRECATED); + } + } + + if (':' !== $key && !$isKeyQuoted && (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) { + @trigger_error(self::getDeprecationMessage('Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since Symfony 3.2 and will throw a ParseException in 4.0.'), E_USER_DEPRECATED); + } + + if ('<<' === $key) { + $allowOverwrite = true; + } while ($i < $len) { + if (':' === $mapping[$i] || ' ' === $mapping[$i]) { + ++$i; + + continue; + } + + $tag = self::parseTag($mapping, $i, $flags); switch ($mapping[$i]) { case '[': // nested sequence @@ -483,12 +538,20 @@ // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. - if (!isset($output[$key])) { - $output[$key] = $value; - } else { - @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); + // 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])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED); } - $done = true; break; case '{': // nested mapping @@ -496,39 +559,45 @@ // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. - if (!isset($output[$key])) { - $output[$key] = $value; - } else { - @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED); } - $done = true; - break; - case ':': - case ' ': break; default: - $value = self::parseScalar($mapping, $flags, array(',', '}'), array('"', "'"), $i, true, $references); + $value = self::parseScalar($mapping, $flags, array(',', '}'), $i, null === $tag, $references); // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. - if (!isset($output[$key])) { - $output[$key] = $value; - } else { - @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED); } - $done = true; --$i; } - ++$i; - if ($done) { - continue 2; - } + continue 2; } } - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping)); + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename); } /** @@ -556,11 +625,11 @@ // an unquoted * if (false === $value || '' === $value) { - throw new ParseException('A reference must contain at least one character.'); + throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename); } if (!array_key_exists($value, $references)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value)); + throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename); } return $references[$value]; @@ -575,53 +644,97 @@ return true; case 'false' === $scalarLower: return false; - // Optimise for returning strings. - case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]): + case '!' === $scalar[0]: switch (true) { case 0 === strpos($scalar, '!str'): + @trigger_error(self::getDeprecationMessage('Support for the !str tag is deprecated since Symfony 3.4. Use the !!str tag instead.'), E_USER_DEPRECATED); + return (string) substr($scalar, 5); + case 0 === strpos($scalar, '!!str '): + return (string) substr($scalar, 6); case 0 === strpos($scalar, '! '): + @trigger_error(self::getDeprecationMessage('Using the non-specific tag "!" is deprecated since Symfony 3.4 as its behavior will change in 4.0. It will force non-evaluating your values in 4.0. Use plain integers or !!float instead.'), E_USER_DEPRECATED); + return (int) self::parseScalar(substr($scalar, 2), $flags); case 0 === strpos($scalar, '!php/object:'): if (self::$objectSupport) { + @trigger_error(self::getDeprecationMessage('The !php/object: tag to indicate dumped PHP objects is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.'), E_USER_DEPRECATED); + return unserialize(substr($scalar, 12)); } if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return; case 0 === strpos($scalar, '!!php/object:'): if (self::$objectSupport) { - @trigger_error('The !!php/object tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object tag instead.', E_USER_DEPRECATED); + @trigger_error(self::getDeprecationMessage('The !!php/object: tag to indicate dumped PHP objects is deprecated since Symfony 3.1 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.'), E_USER_DEPRECATED); return unserialize(substr($scalar, 13)); } if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return; + case 0 === strpos($scalar, '!php/object'): + if (self::$objectSupport) { + return unserialize(self::parseScalar(substr($scalar, 12))); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return; case 0 === strpos($scalar, '!php/const:'): if (self::$constantSupport) { + @trigger_error(self::getDeprecationMessage('The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead.'), E_USER_DEPRECATED); + if (defined($const = substr($scalar, 11))) { return constant($const); } - throw new ParseException(sprintf('The constant "%s" is not defined.', $const)); + throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } if (self::$exceptionOnInvalidType) { - throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar)); + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return; + case 0 === strpos($scalar, '!php/const'): + if (self::$constantSupport) { + $i = 0; + if (defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) { + return constant($const); + } + + throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + if (self::$exceptionOnInvalidType) { + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return; case 0 === strpos($scalar, '!!float '): return (float) substr($scalar, 8); + case 0 === strpos($scalar, '!!binary '): + return self::evaluateBinaryScalar(substr($scalar, 9)); + default: + @trigger_error(self::getDeprecationMessage(sprintf('Using the unquoted scalar value "%s" is deprecated since Symfony 3.3 and will be considered as a tagged value in 4.0. You must quote it.', $scalar)), E_USER_DEPRECATED); + } + + // Optimize for returning strings. + // no break + case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]): + switch (true) { case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar): $scalar = str_replace('_', '', (string) $scalar); // omitting the break / return as integers are handled in the next case + // no break case ctype_digit($scalar): $raw = $scalar; $cast = (int) $scalar; @@ -642,12 +755,10 @@ return -log(0); case '-.inf' === $scalarLower: return log(0); - case 0 === strpos($scalar, '!!binary '): - return self::evaluateBinaryScalar(substr($scalar, 9)); case Parser::preg_match('/^(-|\+)?[0-9][0-9,]*(\.[0-9_]+)?$/', $scalar): case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): if (false !== strpos($scalar, ',')) { - @trigger_error('Using the comma as a group separator for floats is deprecated since version 3.2 and will be removed in 4.0.', E_USER_DEPRECATED); + @trigger_error(self::getDeprecationMessage('Using the comma as a group separator for floats is deprecated since Symfony 3.2 and will be removed in 4.0.'), E_USER_DEPRECATED); } return (float) str_replace(array(',', '_'), '', $scalar); @@ -664,9 +775,48 @@ return $time; } - default: - return (string) $scalar; } + + return (string) $scalar; + } + + /** + * @param string $value + * @param int &$i + * @param int $flags + * + * @return null|string + */ + private static function parseTag($value, &$i, $flags) + { + if ('!' !== $value[$i]) { + return; + } + + $tagLength = strcspn($value, " \t\n", $i + 1); + $tag = substr($value, $i + 1, $tagLength); + + $nextOffset = $i + $tagLength + 1; + $nextOffset += strspn($value, ' ', $nextOffset); + + // Is followed by a scalar + if ((!isset($value[$nextOffset]) || !in_array($value[$nextOffset], array('[', '{'), true)) && 'tagged' !== $tag) { + // Manage non-whitelisted scalars in {@link self::evaluateScalar()} + return; + } + + // Built-in tags + if ($tag && '!' === $tag[0]) { + throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + if (Yaml::PARSE_CUSTOM_TAGS & $flags) { + $i = $nextOffset; + + return $tag; + } + + throw new ParseException(sprintf('Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); } /** @@ -681,11 +831,11 @@ $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar)); if (0 !== (strlen($parsedBinaryData) % 4)) { - throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', strlen($parsedBinaryData))); + throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { - throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData)); + throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return base64_decode($parsedBinaryData, true); @@ -730,4 +880,19 @@ { return '~^0x[0-9a-f_]++$~i'; } + + private static function getDeprecationMessage($message) + { + $message = rtrim($message, '.'); + + if (null !== self::$parsedFilename) { + $message .= ' in '.self::$parsedFilename; + } + + if (-1 !== self::$parsedLineNumber) { + $message .= ' on line '.(self::$parsedLineNumber + 1); + } + + return $message.'.'; + } }