From 73366d528157414c6d84b84cd9d2beea24f20c13 Mon Sep 17 00:00:00 2001 From: Teoh Han Hui Date: Fri, 7 Aug 2015 05:28:03 +0000 Subject: [PATCH] [Yaml] Improve newline handling in folded scalar blocks --- src/Symfony/Component/Yaml/Parser.php | 40 +++++++++++-------- .../Component/Yaml/Tests/Fixtures/sfTests.yml | 18 ++++++++- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 3c20c8662fb0..caf373e39613 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -20,7 +20,9 @@ */ class Parser { - const FOLDED_SCALAR_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; + const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; + // BC - wrongly named + const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN; private $offset = 0; private $lines = array(); @@ -332,8 +334,8 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false) $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine); - // Comments must not be removed inside a string block (ie. after a line ending with "|") - $removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~'; + // Comments must not be removed inside a block scalar + $removeCommentsPattern = '~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~'; $removeComments = !preg_match($removeCommentsPattern, $this->currentLine); while ($this->moveToNextLine()) { @@ -422,10 +424,10 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport) return $this->refs[$value]; } - if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) { + if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); + return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); } try { @@ -439,15 +441,15 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport) } /** - * Parses a folded scalar. + * Parses a block scalar. * - * @param string $separator The separator that was used to begin this folded scalar (| or >) - * @param string $indicator The indicator that was used to begin this folded scalar (+ or -) - * @param int $indentation The indentation that was used to begin this folded 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 parseFoldedScalar($separator, $indicator = '', $indentation = 0) + private function parseBlockScalar($style, $chomping = '', $indentation = 0) { $notEOF = $this->moveToNextLine(); if (!$notEOF) { @@ -502,17 +504,23 @@ private function parseFoldedScalar($separator, $indicator = '', $indentation = 0 $this->moveToPreviousLine(); } - // replace all non-trailing single newlines with spaces in folded blocks - if ('>' === $separator) { + // folded style + if ('>' === $style) { + // folded lines + // replace all non-leading/non-trailing single newlines with spaces preg_match('/(\n*)$/', $text, $matches); - $text = preg_replace('/(? - Empty lines in folded blocks + Empty lines in literal blocks yaml: | foo: bar: | @@ -65,6 +65,20 @@ yaml: | php: | array('foo' => array('bar' => "foo\n\n\n \nbar\n")) --- +test: Empty lines in folded blocks +brief: > + Empty lines in folded blocks +yaml: | + foo: + bar: > + + foo + + + bar +php: | + array('foo' => array('bar' => "\nfoo\n\nbar\n")) +--- test: IP addresses brief: > IP addresses