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
|
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.
|
||||||
@ -196,7 +198,16 @@ class Inline
|
|||||||
*/
|
*/
|
||||||
static private function parseQuotedScalar($scalar, &$i)
|
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)));
|
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)));
|
$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()
|
protected function getTestsForParse()
|
||||||
{
|
{
|
||||||
return array(
|
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, 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, 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 }]' => 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, { 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