Hi all,
I have some code where I need to grab the last 1-3 bytes from numbers
(bitwise AND), and a few weeks ago I was looking to see how I'd handle the
possible, though unlikely, scenario of numbers > LONG_MAX (still only care
about those last bytes). But I realized it worked just fine with the &
operator (because of how overflow worked converting a double operand), and
could rely on that without needing an additional check/workaround. That was
with PHP 5.2.
I remembered the DVAL_TO_LVAL() macro was changed in Dec. and checked things
just now with 5.3. Of course it's different with this code:
$num = PHP_INT_MAX
* 2 + 1;
echo
(int) ($num + 1), "\n",
$num++ & 255, "\n",
$num++ & 255, "\n",
$num++ & 255, "\n",
$num & 255, "\n";
$num = -PHP_INT_MAX;
echo
$num-- & 255, "\n",
$num-- & 255, "\n",
$num-- & 255, "\n",
$num & 255;
5.2 result:
0
255
0
1
2
1
0
255
254
5.3 result:
2147483647
255
255
255
255
1
0
0
0
No overflow now, except between LONG_MAX and ULONG_MAX.
It was changed for bug #42868, which is about a string function?! I see the
problem with overflow wrongly creating a negative start/offset param, etc.
but do people really have >2GB strings that they are passing values >
PHP_INT_MAX?? That bug refers to #30695, which resulted in a similar change
being reverted. The only difference is the earlier change caused a problem
at LONG_MAX, which this works around, only to move the same issue to
ULONG_MAX.
Looks like the overflow-no-matter-what behavior has always been there (with
just a small tweak in 2001 -- zend_operators.c v1.105). I think I've seen
some commits elsewhere similar to the strspn()
fix posted in the bug
report... That seems like a better way for these edge cases; or maybe a new
thing (conversion specifier?) for zend_parse_parameters() to limit longs to
LONG_MIN/LONG_MAX without overflow.
So can the traditional, legacy overflow behavior be restored?
Thanks,
Matt