# PHP Integer Bug

- Thread: https://externals.io/message/56429
- Original archive: https://news-web.php.net/php.internals/56429
- Started by Paul Dragoonis on 2011-11-19T13:46:35+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #56429 — Paul Dragoonis — 2011-11-19T13:46:35+00:00

URL: https://externals.io/message/56429#56429

Hey guys,

I don't have a dev environment on my mac here so I can't upgrade to
TRUNK to test so I'm relying on someone on the internals list to test
this.

---- PHP INFO ----
5.3.1

------ ISSUE ----
Simple integer work, converting it from being wrapped in a zval.type of string,
into int. Same value would be expected but it's giving an arbitrary value.

I can't test on latest php 5.3.x as I don't have a dev environment
setup on this
machine. So i'm relying on some mac user to test using trunk and verify.

----- OS ----
MAC OSX 10.7.2
Darwin Paul-Dragooniss-MacBook-Pro.local 11.2.0 Darwin Kernel Version
11.2.0: Tue
Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64.


---- CODE ---
$s = "2433078805";
var_dump($s);
var_dump((int) $s); exit;

----- EXPECTED -----
string(10) "2433078805" int(2433078805)

----- ACTUAL -----
string(10) "2433078805" int(2147483647)


Random or what?

Regards,
Paul Dragoonis.

---

## #56430 — Anthony Ferrara — 2011-11-19T13:53:27+00:00

URL: https://externals.io/message/56429#56430 · In reply to: #56429

If I'm not mistaken, that is to be expected.  That's because you're on
a 32 bit system, so the maximum possible int (PHP_INT_MAX) is
2147483647.  Now, normally PHP could cast to a float to get the larger
number in, but you explicitly cast it to an integer, so it had to
truncate the value.

Try var_dump($s + 0); which correctly results in a float of the
correct value.  But the problem is that you asked for the int type,
which overflowed...

Anthony

PS: You can use http://codepad.viper-7.com/ to test 5.2, 5.3, 5.4 and
Trunk (I believe they do nightly builds of each)...



> Hey guys,
>
> I don't have a dev environment on my mac here so I can't upgrade to
> TRUNK to test so I'm relying on someone on the internals list to test
> this.
>
> ---- PHP INFO ----
> 5.3.1
>
> ------ ISSUE ----
> Simple integer work, converting it from being wrapped in a zval.type of string,
> into int. Same value would be expected but it's giving an arbitrary value.
>
> I can't test on latest php 5.3.x as I don't have a dev environment
> setup on this
> machine. So i'm relying on some mac user to test using trunk and verify.
>
> ----- OS ----
> MAC OSX 10.7.2
> Darwin Paul-Dragooniss-MacBook-Pro.local 11.2.0 Darwin Kernel Version
> 11.2.0: Tue
> Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64.
>
>
> ---- CODE ---
> $s = "2433078805";
> var_dump($s);
> var_dump((int) $s); exit;
>
> ----- EXPECTED -----
> string(10) "2433078805" int(2433078805)
>
> ----- ACTUAL -----
> string(10) "2433078805" int(2147483647)
>
>
> Random or what?
>
> Regards,
> Paul Dragoonis.

---

## #56431 — Paul Dragoonis — 2011-11-19T14:00:18+00:00

URL: https://externals.io/message/56429#56431 · In reply to: #56430

Thanks for the response guys.

It wasn't important that I casted my value I was just being pedantic
in the first place. Removing the cast stops be from being hit with
INT_MAX and INT_SIZE.

Cheers!
Paul Dragoonis.


> If I'm not mistaken, that is to be expected.  That's because you're on
> a 32 bit system, so the maximum possible int (PHP_INT_MAX) is
> 2147483647.  Now, normally PHP could cast to a float to get the larger
> number in, but you explicitly cast it to an integer, so it had to
> truncate the value.
>
> Try var_dump($s + 0); which correctly results in a float of the
> correct value.  But the problem is that you asked for the int type,
> which overflowed...
>
> Anthony
>
> PS: You can use http://codepad.viper-7.com/ to test 5.2, 5.3, 5.4 and
> Trunk (I believe they do nightly builds of each)...
>
>
> 
> > […]

---

## #56432 — Gustavo Lopes — 2011-11-19T14:46:30+00:00

URL: https://externals.io/message/56429#56432 · In reply to: #56429

On Sat, 19 Nov 2011 13:46:35 -0000, Paul Dragoonis <dragoonis@gmail.com>  
wrote:

> [...]
>
> ---- CODE ---
> $s = "2433078805";
> var_dump($s);
> var_dump((int) $s); exit;
>
> ----- EXPECTED -----
> string(10) "2433078805" int(2433078805)
>
> ----- ACTUAL -----
> string(10) "2433078805" int(2147483647)
>
>

Anthony has already explained the problem, but I can't find this  
documented anywhere. The manual says a conversion from a float outside the  
integer boundaries results in undefined behavior (  
http://php.net/manual/en/language.types.integer.php#language.types.integer.casting  
) and that "if the string does not contain any of the characters '.', 'e',  
or 'E' and the numeric value fits into integer type limits (as defined by  
PHP_INT_MAX), the string will be evaluated as an integer. In all other  
cases it will be evaluated as a float." (  
http://php.net/manual/en/language.types.string.php#language.types.string.conversion  
). None of these seems to apply here, though perhaps from combining the  
two we could conclude the behavior is undefined.

Internally, the behavior is also not explicitly laid out; it follows from  
the behavior of strol. This adds a notice:

Index: Zend/zend_operators.c
===================================================================
--- Zend/zend_operators.c       (revision 319548)
+++ Zend/zend_operators.c       (working copy)
@@ -353,7 +353,11 @@
                         {
                                 char *strval = Z_STRVAL_P(op);

+                               errno = 0;
                                 Z_LVAL_P(op) = strtol(strval, NULL, base);
+                               if (errno == ERANGE) {
+                                       zend_error(E_NOTICE, "Value  
outside integer bounds");
+                               }
                                 STR_FREE(strval);
                         }
                         break;



-- 
Gustavo Lopes
