Search code examples
phprangeyamllibyaml

Does yaml_emit() have ranges?


I saw this thread on a forum, which makes me relate the issue mentioned in the thread to integer ranges.

Basically, the thread is about storing a big integer and getting output as a negative number.

However I can't find any information about integer ranges from libyaml nor the PHP YAML extension. When calling yaml_emit() with a very large number, would it be casted/truncated?

For example, if you call yaml_emit() with a very large integer, but that integer is within the range allowed by the current PHP binaries, would the result be different?


Solution

  • These are the tests I have made locally:

    $ php -v; echo "==="; php --re yaml | head -n 1; echo "==="; php -r 'var_dump(PHP_INT_SIZE); echo yaml_emit([0x7FFFFFFF + 1, -0x80000000 - 1]);'
    PHP 7.0.0 (cli) (built: Dec  3 2015 09:31:42) ( ZTS )
    Copyright (c) 1997-2015 The PHP Group
    Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies
    ===
    Extension [ <persistent> extension #32 yaml version 2.0.0RC6 ] {
    ===
    int(8)
    ---
    - -2147483648
    - 2147483647
    ...
    

    This means that yaml_emit() would treat all content integers as 32-bit integers. If they are out of range, they would be truncated.

    Similarly, this is true even on 64-bit PHP binaries:

    yaml_emit(0xFFFFFFFF) === yaml_emit(-1)
    

    Furthermore, according to the PECL YAML source, it appears that PHP ints are handled as longs, which somehow ended up as 32-bit signed integers even on 64-bit systems and binaries.