rfc:zpp_fail_on_overflow

This is an old revision of the document!


PHP RFC: ZPP Failure on Overflow

Introduction

PHP is a weakly-typed language, and so implicitly converts between integers and floats when passed to internal functions. Currently, when a float that is beyond the range of an integer (outside [PHP_INT_MIN, PHP_INT_MAX]) is passed to an internal function expecting an integer argument, it will silently truncate (e.g. 3221225470.5 becomes -1073741826 on 32-bit platforms), causing a loss of magnitude and sign information, though technically preserving the “lower bits”. This happens without warning, is unintuitive, and can lead to subtle bugs.

Proposal

zend_parse_parameters and its fast macro counterparts are modified to fail (usually causing the function to bail out with an E_WARNING and return NULL) if a float that is outside of the range of an integer, or is NaN, is passed for the l (Z_PARAM_LONG) parameter type. Functions which use the L type or the strict mode in the macros, which caps at PHP_INT_MIN or PHP_INT_MAX depending on sign (also known as saturation), will continue to simply cap and not fail where the float is out of bounds, but will now fail if NaN is passed. Note that Infinity is considered to be outside the range of an integer, as it compares much like a normal floating-point value.

This proposal would complement the draft Big Integer Support RFC, as it would be desirable to have functions which only accept platform-native integers (32-bit or 64-bit) error instead of silently truncate when a bigint is passed.

Backward Incompatible Changes

This is an inherently backwards-incompatible change. However, it is behaviour that is dangerous, and this will only affect edge cases. In the unusual case where the truncation/NaN-tolerant behaviour is desired, an explicit (int) cast can be used.

Proposed PHP Version(s)

As this is a backwards-compatibility break, it is targeted to the next major release of PHP, currently PHP 7.

Unaffected PHP Functionality

This does not affect other implicit integer casts, such as those done with array keys or by the bitwise operators.

Proposed Voting Choices

This is arguably not a language change. However, as it breaks backwards-compatibility, and because some may argue it is a language change, a 2/3 majority will be required. The vote will be a straight Yes/No vote.

Patches and Tests

There is a work-in-progress patch/pull request here: https://github.com/php/php-src/pull/835

As far as I am concerned, the implementation itself is done. However there are numerous tests broken by the change which need updating, and hence the patch must be considered work-in-progress.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

  • v0.1 - Initial version
rfc/zpp_fail_on_overflow.1411432685.txt.gz · Last modified: 2017/09/22 13:28 (external edit)