Skip to content

Commit 5b74171

Browse files
committed
Fix bigint PHP_INT_MIN/PHP_INT_MAX string to int convert
1 parent 0b77350 commit 5b74171

File tree

2 files changed

+22
-45
lines changed

2 files changed

+22
-45
lines changed

src/Types/BigIntType.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): int
4747
return $value;
4848
}
4949

50-
if ($value > PHP_INT_MIN && $value < PHP_INT_MAX) {
50+
if (
51+
($value > PHP_INT_MIN && $value < PHP_INT_MAX)
52+
|| $value === (string) (int) $value
53+
) {
5154
return (int) $value;
5255
}
5356

tests/Functional/Types/BigIntTypeTest.php

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
use Doctrine\DBAL\Types\Types;
1111
use Generator;
1212
use PHPUnit\Framework\Attributes\DataProvider;
13-
use PHPUnit\Framework\Constraint\IsIdentical;
14-
use PHPUnit\Framework\Constraint\LogicalOr;
1513

1614
use const PHP_INT_MAX;
1715
use const PHP_INT_MIN;
@@ -30,13 +28,13 @@ public function testSelectBigInt(string $sqlLiteral, int|string|null $expectedVa
3028

3129
$this->connection->executeStatement(<<<SQL
3230
INSERT INTO bigint_type_test (id, my_integer)
33-
VALUES (42, $sqlLiteral)
31+
VALUES (1, $sqlLiteral)
3432
SQL);
3533

3634
self::assertSame(
3735
$expectedValue,
3836
$this->connection->convertToPHPValue(
39-
$this->connection->fetchOne('SELECT my_integer from bigint_type_test WHERE id = 42'),
37+
$this->connection->fetchOne('SELECT my_integer from bigint_type_test'),
4038
Types::BIGINT,
4139
),
4240
);
@@ -46,47 +44,23 @@ public function testSelectBigInt(string $sqlLiteral, int|string|null $expectedVa
4644
public static function provideBigIntLiterals(): Generator
4745
{
4846
yield 'zero' => ['0', 0];
47+
yield 'minus zero' => ['-0', 0];
48+
yield 'plus zero' => ['+0', 0];
4949
yield 'null' => ['null', null];
5050
yield 'positive number' => ['42', 42];
5151
yield 'negative number' => ['-42', -42];
52-
53-
if (PHP_INT_SIZE < 8) {
54-
// The following tests only work on 64bit systems.
55-
return;
56-
}
57-
58-
yield 'large positive number' => ['9223372036854775806', PHP_INT_MAX - 1];
59-
yield 'large negative number' => ['-9223372036854775807', PHP_INT_MIN + 1];
60-
}
61-
62-
#[DataProvider('provideBigIntEdgeLiterals')]
63-
public function testSelectBigIntEdge(int $value): void
64-
{
65-
$table = new Table('bigint_type_test');
66-
$table->addColumn('id', Types::SMALLINT, ['notnull' => true]);
67-
$table->addColumn('my_integer', Types::BIGINT, ['notnull' => false]);
68-
$table->setPrimaryKey(['id']);
69-
$this->dropAndCreateTable($table);
70-
71-
$this->connection->executeStatement(<<<SQL
72-
INSERT INTO bigint_type_test (id, my_integer)
73-
VALUES (42, $value)
74-
SQL);
75-
76-
self::assertThat(
77-
$this->connection->convertToPHPValue(
78-
$this->connection->fetchOne('SELECT my_integer from bigint_type_test WHERE id = 42'),
79-
Types::BIGINT,
80-
),
81-
LogicalOr::fromConstraints(new IsIdentical($value), new IsIdentical((string) $value)),
82-
);
83-
}
84-
85-
/** @return Generator<string, array{int}> */
86-
public static function provideBigIntEdgeLiterals(): Generator
87-
{
88-
yield 'max int' => [PHP_INT_MAX];
89-
yield 'min int' => [PHP_INT_MIN];
52+
yield 'large positive number' => [PHP_INT_SIZE === 4 ? '2147483646' : '9223372036854775806', PHP_INT_MAX - 1];
53+
yield 'large negative number' => [PHP_INT_SIZE === 4 ? '-2147483647' : '-9223372036854775807', PHP_INT_MIN + 1];
54+
yield 'largest positive number' => [PHP_INT_SIZE === 4 ? '2147483647' : '9223372036854775807', PHP_INT_MAX];
55+
yield 'largest negative number' => [PHP_INT_SIZE === 4 ? '-2147483648' : '-9223372036854775808', PHP_INT_MIN];
56+
yield 'too large positive number' => [
57+
PHP_INT_SIZE === 4 ? '2147483648' : '9223372036854775808',
58+
PHP_INT_SIZE === 4 ? '2147483648' : '9223372036854775808',
59+
];
60+
yield 'too large negative number' => [
61+
PHP_INT_SIZE === 4 ? '-2147483649' : '-9223372036854775809',
62+
PHP_INT_SIZE === 4 ? '-2147483649' : '-9223372036854775809',
63+
];
9064
}
9165

9266
public function testUnsignedBigIntOnMySQL(): void
@@ -104,13 +78,13 @@ public function testUnsignedBigIntOnMySQL(): void
10478
// Insert (2 ** 64) - 1
10579
$this->connection->executeStatement(<<<'SQL'
10680
INSERT INTO bigint_type_test (id, my_integer)
107-
VALUES (42, 0xFFFFFFFFFFFFFFFF)
81+
VALUES (1, 0xFFFFFFFFFFFFFFFF)
10882
SQL);
10983

11084
self::assertSame(
11185
'18446744073709551615',
11286
$this->connection->convertToPHPValue(
113-
$this->connection->fetchOne('SELECT my_integer from bigint_type_test WHERE id = 42'),
87+
$this->connection->fetchOne('SELECT my_integer from bigint_type_test'),
11488
Types::BIGINT,
11589
),
11690
);

0 commit comments

Comments
 (0)