Skip to content

Commit

Permalink
fix handling of empty sequence items
Browse files Browse the repository at this point in the history
When a line contains only a dash it cannot safely be assumed that
it contains a nested list or an embedded mapping. If the next line
starts with a dash at the same indentation, the current line's item
is to be treated as `null`.
  • Loading branch information
xabbuh committed Aug 29, 2014
1 parent 71ceeca commit 33dc401
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
21 changes: 17 additions & 4 deletions Parser.php
Expand Up @@ -93,7 +93,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
$c = $this->getRealCurrentLineNb() + 1;
$parser = new Parser($c);
$parser->refs =& $this->refs;
$data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport);
} else {
if (isset($values['leadspaces'])
&& ' ' == $values['leadspaces']
Expand Down Expand Up @@ -281,15 +281,20 @@ private function getCurrentLineIndentation()
/**
* 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 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)
private function getNextEmbedBlock($indentation = null, $inSequence = false)
{
$this->moveToNextLine();
$oldLineIndentation = $this->getCurrentLineIndentation();

if (!$this->moveToNextLine()) {
return;
}

if (null === $indentation) {
$newIndent = $this->getCurrentLineIndentation();
Expand All @@ -305,6 +310,14 @@ private function getNextEmbedBlock($indentation = null)

$data = array(substr($this->currentLine, $newIndent));

if ($inSequence && $oldLineIndentation === $newIndent && '-' === $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($this->currentLine);

// Comments must not be removed inside a string block (ie. after a line ending with "|")
Expand Down
24 changes: 24 additions & 0 deletions Tests/Fixtures/YtsBasicTests.yml
Expand Up @@ -11,6 +11,30 @@ yaml: |
php: |
array('apple', 'banana', 'carrot')
---
test: Sequence With Item Being Null In The Middle
brief: |
You can specify a list in YAML by placing each
member of the list on a new line with an opening
dash. These lists are called sequences.
yaml: |
- apple
-
- carrot
php: |
array('apple', null, 'carrot')
---
test: Sequence With Last Item Being Null
brief: |
You can specify a list in YAML by placing each
member of the list on a new line with an opening
dash. These lists are called sequences.
yaml: |
- apple
- banana
-
php: |
array('apple', 'banana', null)
---
test: Nested Sequences
brief: |
You can include a sequence within another
Expand Down

0 comments on commit 33dc401

Please sign in to comment.