[Yaml] fixed string parsing (closes #4561)

This commit is contained in:
Fabien Potencier 2012-06-13 14:57:32 +02:00
parent c55ddb9276
commit 3ab9a6eec5
2 changed files with 26 additions and 12 deletions

View File

@ -21,8 +21,6 @@ use Symfony\Component\Yaml\Exception\DumpException;
class Inline class Inline
{ {
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
const REGEX_SINGLE_QUOTED_STRING = '(?:\'([^\']*(?:\'\'[^\']*)*)\')(?!.*\')';
const REGEX_DOUBLE_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)")(?!.*")';
/** /**
* Converts a YAML string to a PHP array. * Converts a YAML string to a PHP array.
@ -52,7 +50,13 @@ class Inline
$result = self::parseMapping($value); $result = self::parseMapping($value);
break; break;
default: 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)) { if (isset($mbEncoding)) {
@ -163,6 +167,13 @@ class Inline
if (in_array($scalar[$i], $stringDelimiters)) { if (in_array($scalar[$i], $stringDelimiters)) {
// quoted scalar // quoted scalar
$output = self::parseQuotedScalar($scalar, $i); $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 { } else {
// "normal" string // "normal" string
if (!$delimiters) { if (!$delimiters) {
@ -203,11 +214,7 @@ class Inline
$items = preg_split('/[\'"]\s*(?:[,:]|[}\]]\s*,)/', $subject); $items = preg_split('/[\'"]\s*(?:[,:]|[}\]]\s*,)/', $subject);
$subject = substr($subject, 0, strlen($items[0]) + 1); $subject = substr($subject, 0, strlen($items[0]) + 1);
if (($scalar[$i] == "'" if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
&& !preg_match('/'.self::REGEX_SINGLE_QUOTED_STRING.'/Au', $subject, $match))
|| ($scalar[$i] == '"'
&& !preg_match('/'.self::REGEX_DOUBLE_QUOTED_STRING.'/Au', $subject, $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)));
} }

View File

@ -66,23 +66,30 @@ class InlineTest extends \PHPUnit_Framework_TestCase
} }
/** /**
*
* @expectedException \Symfony\Component\Yaml\Exception\ParseException * @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/ */
public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException() public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
{ {
$value = "'don't do somthin' like that'"; $value = "'don't do somthin' like that'";
Inline::parseScalar($value); Inline::parse($value);
} }
/** /**
*
* @expectedException \Symfony\Component\Yaml\Exception\ParseException * @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/ */
public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException() public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
{ {
$value = '"don"t do somthin" like that"'; $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() public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()