Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

intval() with negative base prefixed string does not detect base #13243

Open
Girgias opened this issue Jan 25, 2024 · 2 comments
Open

intval() with negative base prefixed string does not detect base #13243

Girgias opened this issue Jan 25, 2024 · 2 comments

Comments

@Girgias
Copy link
Member

Girgias commented Jan 25, 2024

Description

The following code:

<?php
$s = "-0b11111111111111111111111111111111111111111111111111111111111111111111111111111";
$v1 = intval($s, 2);
var_dump($v1);
$v2 = intval($s);
var_dump($v2);
var_dump((int) $s);

Resulted in this output:

int(-9223372036854775808)
int(0)
int(0)

But I expected this output instead:

int(-9223372036854775808)
int(-9223372036854775808)
int(0)

Similarly, if we use $base = 16

Note the 0o prefix is not supported (which is what initially led me down this rabbit hole).

PHP Version

PHP 8.3

Operating System

No response

@Girgias
Copy link
Member Author

Girgias commented Jan 25, 2024

What is strange is that this works for positive prefixed integers, even with an (int) cast.

Not totally sure what the behaviour is/was meant to be for overflows of negative numbers.

Edit: it turns out this has never worked for negative integers, which is a behaviour: https://3v4l.org/o8inp

@hormus
Copy link

hormus commented Jan 27, 2024

Hi @Girgias.

<?php

$i_max = '115792089237316195423570985008687907853269984665640564039457584007913129639936';
$i_max = (int) $i_max;
$i_min = -$i_max - 1;
$s = decbin($i_max);
$v = intval('0b'.$s);
//$v = intval('0b'.$s, 0); // === $i_max
var_dump($s, $v, $i_min);

?>

Actual result:

string(63) "111111111111111111111111111111111111111111111111111111111111111"
int(0)
int(-9223372036854775808)

Expected result:

string(63) "111111111111111111111111111111111111111111111111111111111111111"
int(0)
int(-9223372036854775808)

intval(mixed $value, int $base = 10): int

If base is 0, the base used is determined by the format of value:
If string binary integer > decbin($i_max) overflow to decbin($i_max), if with - sign and < decbin($i_min) underflow to decbin($i_min)

Example 1 string Integer overflow on a 64-bit system

<?php
$i_max = (int) '9223372036854775808';
var_dump($i_max); // 9223372036854775807
?>

Example 2 binary Integer overflow on a 64-bit system

<?php
$a = 0b1000000000000000000000000000000000000000000000000000000000000000;
ini_set('serialize_precision', 19);
var_dump($a);
?>

Actual result:

float(9223372036854774784)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants