php / php-src

The PHP Interpreter
https://www.php.net
Other
38.29k stars 7.76k forks source link

array_sum() with GMP can loose precision (LLP64) #16890

Closed cmb69 closed 21 hours ago

cmb69 commented 4 days ago

Description

The following code:

<?php
var_dump(array_sum([new GMP("9223372036854775806"), 1]));

Resulted in this output:

float(9.223372036854775E+18)

But I expected this output instead:

int(9223372036854775807)

This is caused by an erroneous assumption in gmp_cast_object() for _IS_NUMBER casts (as such it can affect other functions as well), namely that ZEND_LONG would be a signed long, but that is not true for LLP64 data models where it is signed long long. On such platforms, values outside of range [INT_MIN, INT_MAX] are converted to float.

PHP Version

PHP-8.2

Operating System

Windows 64bit

cmb69 commented 4 days ago

Oops. In the meantime I've noticed that array_sum() in PHP-8.2 is not affected by this (since objects are skipped); so the given reproducer does not apply. Still, the issue should be fixed in PHP-8.2, too, since it may affect external extensions. I don't think the bug could be triggered using SimpleXML, which is the only other extension using convert_scalar_to_number() in php-src.