Skip to content

Commit 4496322

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix bug #67563: mysqli compiled with mysqlnd does not take ipv6 adress as parameter
2 parents 7e47226 + 6db12e7 commit 4496322

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ PHP NEWS
3535
- GD:
3636
. FIxed GH-19955 (imagefttext() memory leak). (David Carlier)
3737

38+
- MySQLnd:
39+
. Fixed bug #67563 (mysqli compiled with mysqlnd does not take ipv6 adress
40+
as parameter). (nielsdos)
41+
3842
- SimpleXML:
3943
. Fixed bug GH-19988 (zend_string_init with NULL pointer in simplexml (UB)).
4044
(nielsdos)

ext/mysqli/tests/bug67563.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Fix bug #67563 (mysqli compiled with mysqlnd does not take ipv6 adress as parameter)
3+
--EXTENSIONS--
4+
mysqli
5+
--SKIPIF--
6+
<?php
7+
require_once 'connect.inc';
8+
9+
if ($host !== '127.0.0.1')
10+
die('skip local test');
11+
12+
if (@stream_socket_client('udp://[::1]:8888') === false)
13+
die('skip no IPv6 support 2');
14+
15+
if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
16+
die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
17+
$host, $user, $db, $port, $socket));
18+
}
19+
?>
20+
--INI--
21+
max_execution_time=240
22+
--FILE--
23+
<?php
24+
require_once 'connect.inc';
25+
26+
$hosts = ['::1', "[::1]:$port"];
27+
28+
foreach ($hosts as $host) {
29+
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
30+
printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=%s dbname=%s, port=%s, socket=%s\n",
31+
$host, $user, $passwd, $db, $port, $socket);
32+
} else {
33+
$link->close();
34+
}
35+
}
36+
37+
print "done!";
38+
?>
39+
--EXPECT--
40+
done!

ext/mysqlnd/mysqlnd_connection.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
513513
}
514514
/* }}} */
515515

516+
/* ipv6 addresses have at least two colons, which is how we can differentiate between domain names and addresses */
517+
static bool mysqlnd_fast_is_ipv6_address(const char *s)
518+
{
519+
const char *first_colon = strchr(s, ':');
520+
if (!first_colon) {
521+
return false;
522+
}
523+
return strchr(first_colon + 1, ':') != NULL;
524+
}
525+
516526
/* {{{ mysqlnd_conn_data::get_scheme */
517527
static MYSQLND_STRING
518528
MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_CSTRING hostname, MYSQLND_CSTRING *socket_or_pipe, unsigned int port, bool * unix_socket, bool * named_pipe)
@@ -542,7 +552,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_
542552
if (!port) {
543553
port = 3306;
544554
}
545-
transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port);
555+
556+
/* ipv6 addresses are in the format [address]:port */
557+
if (hostname.s[0] != '[' && mysqlnd_fast_is_ipv6_address(hostname.s)) {
558+
transport.l = mnd_sprintf(&transport.s, 0, "tcp://[%s]:%u", hostname.s, port);
559+
} else {
560+
transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port);
561+
}
546562
}
547563
DBG_INF_FMT("transport=%s", transport.s? transport.s:"OOM");
548564
DBG_RETURN(transport);

0 commit comments

Comments
 (0)