Hi Nikita,
that's exactly the subject I've tripped over trying to fix (apparently
wrong) the issue #62477. The ticket is about LimitIterator accepting only
long for start and offset, but being able to accept an Iterator from
userland accepting floats for positions.
For instance, the snippet like this looks also not very well
$a = array(); $a[4000000000] = 42; print_r($a);
Array
(
[-294967296] => 42
)
So the mess is a bit bigger then and the way to solve this should include
more consistent APIs as well, IMO. Again :). At the moment internal
operations (like array having uint for positions) are a possible subset of
userland. However internal APIs should be always the superset.
Regards
Anatoliy
Am Do, 19.07.2012, 00:39 schrieb Nikita Popov:
Hi internals!
When a large floating point number is cast to an integer we currently
have very low-level C behavior (integer overflow and wraparound):$ /c/php-5.4.1/php -r 'var_dump((int) 4000000000);'
int(-294967296)$ /c/php-5.4.1/php -r 'var_dump((int) 6000000000);'
int(1705032704)As a fun fact, if you do the same thing with a string float the number
if clipped instead of wrapped:$ /c/php-5.4.1/php -r 'var_dump((int) "4000000000");'
int(2147483647)This also applies to zend_parse_parameters. l arguments are wrapped, L
arguments are clipped.In my eyes this kind of behavior has nothing to do in PHP. PHP is a
high-level language, it shouldn't exhibit low-level stuff like integer
overflows and wraparound.I think that at least for zend_parse_parameters this should be
changed. Overflowing float parameters should not be accepted. Instead
throw the usualE_WARNING
and return FAILURE.I'm not sure though what one should do about the explicit (int) cast. My
preference would be to throw a notice and use the clipping
behavior.Thoughts?
Nikita