Edit report at https://bugs.php.net/bug.php?id=69906&edit=1
ID: 69906
Comment by: jan dot slabon at setasign dot com
Reported by: ab@php.net
Summary: chr() behavior difference between 32- and 64-bit
bulids
Status: Re-Opened
Type: Documentation Problem
Package: *General Issues
Operating System: any
PHP Version: 7.0.0alpha1
Block user comment: N
Private report: N
New Comment:
Anatol,
Do you have some other functions which are also affected by this behavior change?
Thanks!
Jan
Previous Comments:
------------------------------------------------------------------------
[2015-06-24 09:10:09] ab@php.net
Jan,
ok, doc bug sounds appropriate. Thanks for more extended info.
Actually it's not a local BC, but might be found somewhere else and is a general behavior
change. In PHP5 on 32-bit it would happily allow the internal integer argument to be overflown by
that big integral constant, while in PHP7 it'll be always truncated to zero.
Thanks.
------------------------------------------------------------------------
[2015-06-24 07:06:16] jan dot slabon at setasign dot com
Hi Bob, hi Anatol,
I reported that problem while talking to Anatol about another bug by email. We really had such code
which got broken by this change.
So technically it is a BC break but I'm not sure if we are the only one trapping into that
issue?
We encountered the problem in an Ascii85 encoder which we fixed now by casting to int explicity. So
I don't have a problem with this BC break as we've a fix for it:
$r = 0;
for ($j = 0; $j < 5; ++$j) {
$r = (int)($r * 85 + $chn[$j]);
}
$out .= chr($r >> 24)
. chr($r >> 16)
. chr($r >> 8)
. chr($r);
Anyhow this problem will only arise in special situations and will not be recognized until it
happens (in our case PDF documents that uses an Ascii85 filter - very rare), which may lead people
to think that the code is fine with PHP 7 while it is not...
Here are some os projects/packages which current versions are affected:
https://packagist.org/search/?q=fpdi
https://packagist.org/search/?q=mpdf
https://packagist.org/search/?q=pdfparser
(depends on https://packagist.org/search/?q=tcpdf which seems
to use such structure in its filter class/method, too - which is actually only used by the
pdfparser)
Additionally there are some hundreds packages depending on these packages, too.
If you want to stay with this BC break this have to be documentated.
At our end this would force people to update not only to PHP 7 but to the latest library version. So
I'm fine with this BC break.
Anyhow it could end in some trouble around these packages and users.
Cheers,
Jan
------------------------------------------------------------------------
[2015-06-23 21:30:01] ab@php.net
Hi Bob,
yeah, i was investigating on this but didn't come to update the ticket. You're right,
while it's an issue :)
I first thought it's an issue on 64-bit, now it looks the issue is on 32-bit (expected should
deliver int(173)). Namely - on 32-bit the argument that overflows PHP_INT_MAX will be just truncated
to zero (read as 'l' by ZPP or alike). While I saw that there could be a way to fix this
on 32-bit, it would be too expensive to be justified. Thus, probably best is to leave it as is, a
cast to int should do more or less correct job on this.
So kinda marking this as no bug.
Thanks.
------------------------------------------------------------------------
[2015-06-23 20:15:04] bwoebi@php.net
May I request to not have that changed?
That's technically a BC break, because there's code out there relying on chr() implicitly
doing & 0xFF on the passed param.
I think that's rather a doc bug?
------------------------------------------------------------------------
[2015-06-23 07:22:19] ab@php.net
Description:
------------
When passing an integer that overflows PHP_INT_MAX in 32-bit, the behavior of chr() differs. The
documentation currently doesn't define what should happen in this situation, the only statement
is that chr() expects an ASCII code. chr() should ensure the input is in the valid range, thus
making the behavior consistent between 32- and 64-bit.
Test script:
---------------
Debug\php.exe -r "$a = chr(2632627629); var_dump($a, ord($a));"
string(1) " "
int(0)
x64\Debug\php.exe -r "$a = chr(2632627629); var_dump($a, ord($a));"
string(1) "¡"
int(173)
Expected result:
----------------
string(1) " "
int(0)
Actual result:
--------------
Different behavior depending on 32- or 64-bit build.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=69906&edit=1