Skip to content

[YAML] Parsing octal numbers: unexpected value conversion and PHP 7.4 notice #34807

Closed
@cebe

Description

@cebe

Symfony version(s) affected: probably all (tried 4.3 and 4.4)

Description

Parsing YAML values that start with 0 may result in a deprecation warning in PHP 7.4:

Invalid characters passed for attempted conversion, these have been ignored

Related note in PHP 7.4 migration guide: https://www.php.net/manual/en/migration74.deprecated.php#migration74.deprecated.core.invalid-base-characters

Also unsure if the parsing happens correctly according to the YAML spec.

Having something like OwnerId: 0123456789 in YAML, it is being interpreted as an octal number and results in [OwnerId] => 342391 when parsed.

How to reproduce

<?php

require __DIR__ . '/vendor/autoload.php';

$yaml = \Symfony\Component\Yaml\Yaml::parse(<<<YAML
OwnerId: 0123456789
YAML
);

print_r($yaml);

results in:

Array
(
    [OwnerId] => 342391
)

342391 decimal, when converted back to ocal however is 1234567 in octal, not 0123456789, which is obvious, because 0123456789 is not a valid octal number.

Possible Solution

As far as I see, the yaml spec is not clear about how to handle this case. Many users might be unaware of this conversion and actually expect a string '0123456789' as the parseing result. So we should probably add a check and only convert octal numbers that are valid.

I also found that YAML 1.1 is showing octal number examples like 013 but YAML 1.2 they are 0o14...

Additional context

related code:

case ctype_digit($scalar):
$raw = $scalar;
$cast = (int) $scalar;
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
$raw = $scalar;
$cast = (int) $scalar;
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);

Metadata

Metadata

Assignees

No one assigned

    Labels

    DXDX = Developer eXperience (anything that improves the experience of using Symfony)Yaml

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions