Fixed quoting issues with Yaml Inline Parser
* Added test parse error in parseQuotedScalar * Expecting to throw tests, previously trimmed string * More details on issue: https://github.com/symfony/symfony/issues/4021 * Enforces single quote escaping when within string quotes * Shortens the scope of the validation match * Stricter matching rules * Ensures double quoted strings are not parsed incorrectly * Split quote matching into 2 types of quotes * Separates single and double quotes * Fixes intollerence for un escaped double quote
This commit is contained in:
parent
fae4523f3b
commit
478227d9ac
@ -21,6 +21,8 @@ use Symfony\Component\Yaml\Exception\DumpException;
|
||||
class Inline
|
||||
{
|
||||
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
|
||||
const REGEX_SINGLE_QUOTED_STRING = '(?:\'([^\']*(?:\'\'[^\']*)*)\')(?!.*\')';
|
||||
const REGEX_DOUBLE_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)")(?!.*")';
|
||||
|
||||
/**
|
||||
* Converts a YAML string to a PHP array.
|
||||
@ -196,7 +198,16 @@ class Inline
|
||||
*/
|
||||
static private function parseQuotedScalar($scalar, &$i)
|
||||
{
|
||||
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
|
||||
// Only check the current item we're dealing with (for sequences)
|
||||
$subject = substr($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))
|
||||
) {
|
||||
throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,34 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($value, Inline::parse(Inline::dump($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
||||
*/
|
||||
public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
|
||||
{
|
||||
$value = "'don't do somthin' like that'";
|
||||
Inline::parseScalar($value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
||||
*/
|
||||
public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
|
||||
{
|
||||
$value = '"don"t do somthin" like that"';
|
||||
Inline::parseScalar($value);
|
||||
}
|
||||
|
||||
public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
|
||||
{
|
||||
$value = "'don''t do somthin'' like that'";
|
||||
$expect = "don't do somthin' like that";
|
||||
|
||||
$this->assertSame($expect, Inline::parseScalar($value));
|
||||
}
|
||||
|
||||
protected function getTestsForParse()
|
||||
{
|
||||
return array(
|
||||
@ -124,6 +152,7 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
||||
'[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]' => array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo'))),
|
||||
|
||||
'[foo, bar: { foo: bar }]' => array('foo', '1' => array('bar' => array('foo' => 'bar'))),
|
||||
'[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']' => array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%',), true, '@service_container',),
|
||||
);
|
||||
}
|
||||
|
||||
@ -167,6 +196,8 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
||||
'[foo, { bar: foo }]' => array('foo', array('bar' => 'foo')),
|
||||
|
||||
'[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]' => array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo'))),
|
||||
|
||||
'[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']' => array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%',), true, '@service_container',),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user