Тестирование целочисленного переполнения в PHP - PullRequest
2 голосов
/ 03 сентября 2011

У меня есть модульный тест, который используется для проверки преобразования переменных из строки в целое число.Пока это хорошо, за исключением последнего.

$_GET['name'] = '42000000000000000000000000000000000000';
$text = $input->get( 'name', Convert::T_INTEGER );
$this->assertEquals( 92233720368547755807, $text );

Ожидаемое значение (которое подтверждается самим тестом) заключается в том, что большое значение при преобразовании из строки в целое с использованием intval () вызываетпереполнение, которое по умолчанию принимает наибольшее целочисленное значение, которое php может обработать в моей системе.Тем не менее, это все равно не удается:

Failed asserting that <integer:92233720368547755807> matches expected <double:9.2233720368548E+19>

И когда я пытаюсь принудительно ввести ожидаемое число в целое число:

$this->assertEquals( intval(92233720368547755807), $text );

Я получаю это:

Failed asserting that <integer:92233720368547755807> matches expected <integer:0>

Вот что тест запускает буквально прямо перед этим тестом для ...

Соответствующий код:

public function get( $name, $type = null )
{
    $value = $_GET['value'];
    if( !is_null( $type ) )
        $value = Convert::to( $value, $type );
    return $value;
}

И

public static function to( $value, $type )
{
    switch( $type )
    {
        case self::T_INTEGER:
            return intval( $value );
        default:
            return null;
    }
}

Итак, вопрос такой: Как мне получить этот тест, чтобы получить положительный результат?

Ответы [ 3 ]

5 голосов
/ 03 сентября 2011

Используйте константу PHP_INT_MAX:

$this->assertEquals( PHP_INT_MAX, $text );

Это решит вашу проблему и сделает ваш тест более переносимым (например, он будет работать и на 32-битных системах).

Значение PHP_INT_MAXявляется более представительным int в вашей сборке PHP.

См. http://php.net/manual/en/reserved.constants.php

2 голосов
/ 03 сентября 2011

У вас есть дополнительный 5 в вашем номере.Это:

92233720368547755807

Должно быть так:

9223372036854775807
0 голосов
/ 03 сентября 2011

Ваша проблема в том, что любое большее число INT_MAX преобразуется в число с плавающей точкой, что теряет точность. Если вы сравниваете его со строкой, он всегда возвращает false.

Пожалуйста, используйте функции bcmath для работы с такими большими числами.

...