+
+ return (string) $scalar;
+ }
+
+ /**
+ * @param string $value
+ * @param int &$i
+ * @param int $flags
+ *
+ * @return string|null
+ */
+ 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);
+ }
+
+ /**
+ * @param string $scalar
+ *
+ * @return string
+ *
+ * @internal
+ */
+ public static function evaluateBinaryScalar($scalar)
+ {
+ $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)), 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), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ return base64_decode($parsedBinaryData, true);
+ }
+
+ private static function isBinaryString($value)
+ {
+ return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value);