Skip to content

Commit b390351

Browse files
NathanFreemancmb69
authored andcommitted
Fix bug where large bigints may be truncated
Unless stringified results are requested, we need to parse large bigints as unsigned, to avoid wrap-around behavior. Co-authored-by: Christoph M. Becker <[email protected]> Closes GH-7837.
1 parent 206bcff commit b390351

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ PHP NEWS
1616
. Fixed bug GH-7826 (Inconsistent argument name in hash_hmac_file and
1717
hash_file). (cmb)
1818

19+
- MySQLnd:
20+
. Fixed bug where large bigints may be truncated. (Nathan Freeman, cmb)
21+
1922
- OCI8:
2023
. Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second
2124
call). (cmb)

ext/mysqli/tests/gh7837.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Bug GH-7837 (large bigints may be truncated)
3+
--SKIPIF--
4+
<?php
5+
require_once("skipif.inc");
6+
if (strpos(mysqli_get_client_info(), "mysqlnd") === false) {
7+
die("skip requires mysqlnd");
8+
}
9+
require_once("skipifconnectfailure.inc");
10+
?>
11+
--FILE--
12+
<?php
13+
require_once("connect.inc");
14+
15+
$mysql = new mysqli($host, $user, $passwd, $db, $port, $socket);
16+
$mysql->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
17+
$mysql->query("DROP TABLE IF EXISTS test");
18+
$mysql->query("CREATE TABLE test (`ubigint` bigint unsigned NOT NULL) ENGINE=InnoDB");
19+
$mysql->query("INSERT INTO test (`ubigint`) VALUES (18446744073709551615)");
20+
$mysql->query("INSERT INTO test (`ubigint`) VALUES (9223372036854775808)");
21+
$mysql->query("INSERT INTO test (`ubigint`) VALUES (1)");
22+
$result = $mysql->query("SELECT ubigint FROM test");
23+
var_dump($result->fetch_all());
24+
?>
25+
--EXPECT--
26+
array(3) {
27+
[0]=>
28+
array(1) {
29+
[0]=>
30+
string(20) "18446744073709551615"
31+
}
32+
[1]=>
33+
array(1) {
34+
[0]=>
35+
string(19) "9223372036854775808"
36+
}
37+
[2]=>
38+
array(1) {
39+
[0]=>
40+
int(1)
41+
}
42+
}

ext/mysqlnd/mysqlnd_wireprotocol.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,9 +1634,9 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_ROW_BUFFER * row_buffer, zval *
16341634
} else {
16351635
uint64_t v =
16361636
#ifndef PHP_WIN32
1637-
(uint64_t) atoll((char *) p);
1637+
strtoull((char *) p, NULL, 10);
16381638
#else
1639-
(uint64_t) _atoi64((char *) p);
1639+
_strtoui64((char *) p, NULL, 10);
16401640
#endif
16411641
zend_bool uns = fields_metadata[i].flags & UNSIGNED_FLAG? TRUE:FALSE;
16421642
/* We have to make it ASCIIZ temporarily */

0 commit comments

Comments
 (0)