Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Yaml][Inline] Fail properly on empty object tag and empty const tag #35332

Merged
merged 1 commit into from Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/Symfony/Component/Yaml/Inline.php
Expand Up @@ -506,7 +506,12 @@ private static function parseMapping($mapping, $flags, &$i = 0, $references = []

if ('!php/const' === $key) {
$key .= self::parseScalar($mapping, $flags, [':', ' '], $i, false, [], true);
$key = self::evaluateScalar($key, $flags);
if ('!php/const:' === $key && ':' !== $mapping[$i]) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug fix. {!php/const: foo} is currently interpreted as legacy php/const: tag + '' as the const value while it should end up as ['' => 'foo'].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this must be removed once merged to 4.3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref #35318 btw

$key = '';
Copy link
Contributor Author

@fancyweb fancyweb Jan 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to evaluate because we know it's gonna end up as the empty string (the key === !php/const).

--$i;
} else {
$key = self::evaluateScalar($key, $flags);
}
}

if (':' !== $key && false === $i = strpos($mapping, ':', $i)) {
Expand Down Expand Up @@ -692,6 +697,10 @@ private static function evaluateScalar($scalar, $flags, $references = [])
return null;
case 0 === strpos($scalar, '!php/object'):
if (self::$objectSupport) {
if (!isset($scalar[12])) {
return false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unserialize('') === false

}

return unserialize(self::parseScalar(substr($scalar, 12)));
}

Expand All @@ -717,6 +726,10 @@ private static function evaluateScalar($scalar, $flags, $references = [])
return null;
case 0 === strpos($scalar, '!php/const'):
if (self::$constantSupport) {
if (!isset($scalar[11])) {
return '';
}

$i = 0;
if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) {
return \constant($const);
Expand Down
43 changes: 43 additions & 0 deletions src/Symfony/Component/Yaml/Tests/InlineTest.php
Expand Up @@ -799,4 +799,47 @@ public function getTestsForOctalNumbers()
'negative octal number' => [-28, '-034'],
];
}

/**
* @dataProvider phpObjectTagWithEmptyValueProvider
*/
public function testPhpObjectWithEmptyValue($expected, $value)
{
$this->assertSame($expected, Inline::parse($value, Yaml::PARSE_OBJECT));
}

public function phpObjectTagWithEmptyValueProvider()
{
return [
[false, '!php/object'],
[false, '!php/object '],
[false, '!php/object '],
[[false], '[!php/object]'],
[[false], '[!php/object ]'],
[[false, 'foo'], '[!php/object , foo]'],
];
}

/**
* @dataProvider phpConstTagWithEmptyValueProvider
*/
public function testPhpConstTagWithEmptyValue($expected, $value)
{
$this->assertSame($expected, Inline::parse($value, Yaml::PARSE_CONSTANT));
}

public function phpConstTagWithEmptyValueProvider()
{
return [
['', '!php/const'],
['', '!php/const '],
['', '!php/const '],

This comment was marked as outdated.

Copy link
Contributor

@ro0NL ro0NL Jan 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean, if constant(' ') were to be defined, the value would be "some"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never mind :D it's still OK if it would be defined.

Copy link
Contributor Author

@fancyweb fancyweb Jan 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would work but only with no error reporting on notices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway that's such a weird case. I think it doesn't matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never mind :D it's still OK if it would be defined.

No. My previous replies were to your first message. If the '' constant is defined, it is never resolved now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return defined('') ? constant('') : '';? 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we can stay backward compatible by checking it. But do we want to? 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, but that's for 5.x. It would make the feature removal/deprecation more explicit.

[[''], '[!php/const]'],
[[''], '[!php/const ]'],
[['', 'foo'], '[!php/const , foo]'],
[['' => 'foo'], '{!php/const: foo}'],
[['' => 'foo'], '{!php/const : foo}'],
[['' => 'foo', 'bar' => 'ccc'], '{!php/const : foo, bar: ccc}'],
];
}
}