Skip to content

Commit

Permalink
[Yaml] fixed string parsing (closes #4561)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Jun 13, 2012
1 parent c55ddb9 commit 3ab9a6e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
23 changes: 15 additions & 8 deletions src/Symfony/Component/Yaml/Inline.php
Expand Up @@ -21,8 +21,6 @@
class Inline
{
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
const REGEX_SINGLE_QUOTED_STRING = '(?:\'([^\']*(?:\'\'[^\']*)*)\')(?!.*\')';
const REGEX_DOUBLE_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)")(?!.*")';

/**
* Converts a YAML string to a PHP array.
Expand Down Expand Up @@ -52,7 +50,13 @@ static public function parse($value)
$result = self::parseMapping($value);
break;
default:
$result = self::parseScalar($value);
$i = 0;
$result = self::parseScalar($value, null, array('"', "'"), $i);

// some comment can end the scalar
if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
}
}

if (isset($mbEncoding)) {
Expand Down Expand Up @@ -163,6 +167,13 @@ static public function parseScalar($scalar, $delimiters = null, $stringDelimiter
if (in_array($scalar[$i], $stringDelimiters)) {
// 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)));
}
}
} else {
// "normal" string
if (!$delimiters) {
Expand Down Expand Up @@ -203,11 +214,7 @@ static private function parseQuotedScalar($scalar, &$i)
$items = preg_split('/[\'"]\s*(?:[,:]|[}\]]\s*,)/', $subject);
$subject = substr($subject, 0, strlen($items[0]) + 1);

if (($scalar[$i] == "'"
&& !preg_match('/'.self::REGEX_SINGLE_QUOTED_STRING.'/Au', $subject, $match))
|| ($scalar[$i] == '"'
&& !preg_match('/'.self::REGEX_DOUBLE_QUOTED_STRING.'/Au', $subject, $match))
) {
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
}

Expand Down
15 changes: 11 additions & 4 deletions src/Symfony/Component/Yaml/Tests/InlineTest.php
Expand Up @@ -66,23 +66,30 @@ public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedTo
}

/**
*
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
{
$value = "'don't do somthin' like that'";
Inline::parseScalar($value);
Inline::parse($value);
}

/**
*
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
{
$value = '"don"t do somthin" like that"';
Inline::parseScalar($value);
Inline::parse($value);
}

/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseInvalidMappingKeyShouldThrowException()
{
$value = '{ "foo " bar": "bar" }';
Inline::parse($value);
}

public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
Expand Down

0 comments on commit 3ab9a6e

Please sign in to comment.