Skip to content

Commit 6f7a47d

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
2 parents 4da6753 + 83d2bc9 commit 6f7a47d

18 files changed

+149
-6
lines changed

NEWS

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ PHP NEWS
3737
. Fixed bug #77552 (Unintialized php_stream_statbuf in stat functions).
3838
(John Stevenson)
3939

40+
- MySQL
41+
. Disabled LOCAL INFILE by default, can be enabled using php.ini directive
42+
mysqli.allow_local_infile for mysqli, or PDO::MYSQL_ATTR_LOCAL_INFILE
43+
attribute for pdo_mysql. (Darek Slusarczyk)
44+
4045
07 Feb 2019, PHP 7.3.2
4146

4247
- Core:

ext/mysqli/mysqli.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ PHP_INI_BEGIN()
516516
STD_PHP_INI_ENTRY("mysqli.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals)
517517
#endif
518518
STD_PHP_INI_BOOLEAN("mysqli.reconnect", "0", PHP_INI_SYSTEM, OnUpdateLong, reconnect, zend_mysqli_globals, mysqli_globals)
519-
STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals)
519+
STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "0", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals)
520520
PHP_INI_END()
521521
/* }}} */
522522

@@ -541,7 +541,7 @@ static PHP_GINIT_FUNCTION(mysqli)
541541
mysqli_globals->reconnect = 0;
542542
mysqli_globals->report_mode = 0;
543543
mysqli_globals->report_ht = 0;
544-
mysqli_globals->allow_local_infile = 1;
544+
mysqli_globals->allow_local_infile = 0;
545545
#ifdef HAVE_EMBEDDED_MYSQLI
546546
mysqli_globals->embedded = 1;
547547
#else

ext/mysqli/tests/061.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ if ($msg = check_local_infile_support($link, $engine))
1717

1818
mysqli_close($link);
1919
?>
20+
--INI--
21+
mysqli.allow_local_infile=1
2022
--FILE--
2123
<?php
2224
require_once("connect.inc");

ext/mysqli/tests/bug36745.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Bug #36745 (LOAD DATA LOCAL INFILE doesn't return correct error message)
55
require_once('skipif.inc');
66
require_once('skipifconnectfailure.inc');
77
?>
8+
--INI--
9+
mysqli.allow_local_infile=1
810
--FILE--
911
<?php
1012
require_once("connect.inc");

ext/mysqli/tests/bug53503.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ if ($msg = check_local_infile_support($link, $engine))
1515
mysqli_close($link);
1616

1717
?>
18+
--INI--
19+
mysqli.allow_local_infile=1
1820
--FILE--
1921
<?php
2022
require_once("connect.inc");

ext/mysqli/tests/bug68077.phpt

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ if ($msg = check_local_infile_support($link, $engine))
1717
mysqli_close($link);
1818
?>
1919
--INI--
20+
mysqli.allow_local_infile=1
21+
mysqli.allow_persistent=1
22+
mysqli.max_persistent=1
2023
open_basedir=
2124
--FILE--
2225
<?php

ext/mysqli/tests/mysqli_constants.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ require_once('skipif.inc');
66
require_once('skipifemb.inc');
77
require_once('skipifconnectfailure.inc');
88
?>
9+
--INI--
10+
mysqli.allow_local_infile=1
911
--FILE--
1012
<?php
1113
require("connect.inc");

ext/mysqli/tests/mysqli_get_client_stats.phpt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ if (!function_exists('mysqli_get_client_stats')) {
1212
--INI--
1313
mysqlnd.collect_statistics=1
1414
mysqlnd.collect_memory_statistics=1
15+
mysqli.allow_local_infile=1
1516
--FILE--
1617
<?php
1718
/*

ext/mysqli/tests/mysqli_info.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ require_once('skipif.inc');
66
require_once('skipifemb.inc');
77
require_once('skipifconnectfailure.inc');
88
?>
9+
--INI--
10+
mysqli.allow_local_infile=1
911
--FILE--
1012
<?php
1113
require_once("connect.inc");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
ensure default for local infile is off
3+
--SKIPIF--
4+
<?php
5+
require_once('skipif.inc');
6+
require_once('skipifconnectfailure.inc');
7+
?>
8+
--FILE--
9+
<?php
10+
require_once("connect.inc");
11+
12+
$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
13+
$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"');
14+
$row = mysqli_fetch_assoc($res);
15+
echo "server: ", $row['Value'], "\n";
16+
mysqli_free_result($res);
17+
mysqli_close($link);
18+
19+
echo "connector: ", ini_get("mysqli.allow_local_infile"), "\n";
20+
21+
print "done!\n";
22+
?>
23+
--EXPECTF--
24+
server: %s
25+
connector: 0
26+
done!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
enable local infile
3+
--SKIPIF--
4+
<?php
5+
require_once('skipif.inc');
6+
require_once('skipifconnectfailure.inc');
7+
?>
8+
--INI--
9+
mysqli.allow_local_infile=1
10+
--FILE--
11+
<?php
12+
require_once("connect.inc");
13+
14+
$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
15+
$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"');
16+
$row = mysqli_fetch_assoc($res);
17+
echo "server: ", $row['Value'], "\n";
18+
mysqli_free_result($res);
19+
mysqli_close($link);
20+
21+
echo "connector: ", ini_get("mysqli.allow_local_infile"), "\n";
22+
23+
print "done!\n";
24+
?>
25+
--EXPECTF--
26+
server: %s
27+
connector: 1
28+
done!

ext/mysqli/tests/mysqli_real_connect.phpt

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ require_once('skipif.inc');
66
require_once('skipifemb.inc');
77
require_once('skipifconnectfailure.inc');
88
?>
9+
--INI--
10+
mysqli.allow_local_infile=1
911
--FILE--
1012
<?php
1113
include("connect.inc");

ext/mysqli/tests/mysqli_real_connect_pconn.phpt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ if (!$IS_MYSQLND)
1010
die("skip mysqlnd only test");
1111
?>
1212
--INI--
13+
mysqli.allow_local_infile=1
1314
mysqli.allow_persistent=1
1415
mysqli.max_persistent=10
1516
--FILE--

ext/mysqlnd/mysqlnd_connection.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA *
480480
MYSQLND_VIO * vio = conn->vio;
481481

482482
DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags");
483-
/* we allow load data local infile by default */
483+
/* allow CLIENT_LOCAL_FILES capability, although extensions basing on mysqlnd
484+
shouldn't allow 'load data local infile' by default due to security issues */
484485
mysql_flags |= MYSQLND_CAPABILITIES;
485486

486487
mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */

ext/pdo_mysql/mysql_driver.c

+15
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_
484484
case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE:
485485
ZVAL_LONG(return_value, H->max_buffer_size);
486486
break;
487+
#else
488+
case PDO_MYSQL_ATTR_LOCAL_INFILE:
489+
ZVAL_BOOL(
490+
return_value,
491+
(H->server->data->options->flags & CLIENT_LOCAL_FILES) == CLIENT_LOCAL_FILES);
492+
break;
487493
#endif
488494

489495
default:
@@ -769,6 +775,15 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
769775
CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
770776
}
771777
}
778+
#endif
779+
} else {
780+
#if defined(MYSQL_OPT_LOCAL_INFILE) || defined(PDO_USE_MYSQLND)
781+
// in case there are no driver options disable 'local infile' explicitly
782+
zend_long local_infile = 0;
783+
if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) {
784+
pdo_mysql_error(dbh);
785+
goto cleanup;
786+
}
772787
#endif
773788
}
774789

ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ MySQLPDOTest::skip();
1919
try {
2020
$db = new PDO($dsn, $user, $pass, array($option => $value));
2121
if (!is_object($db) || ($value !== ($tmp = @$db->getAttribute($option))))
22-
printf("[%03d] Execting '%s'/%s got '%s'/%s' for options '%s'\n",
22+
printf("[%03d] Expecting '%s'/%s got '%s'/%s' for options '%s'\n",
2323
$offset,
2424
$value, gettype($value),
2525
$tmp, gettype($tmp),
@@ -172,8 +172,7 @@ MySQLPDOTest::skip();
172172
[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on
173173
[017] PDO::ATTR_EMULATE_PREPARES should be off
174174
[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off
175-
[021] Execting '1'/boolean got ''/boolean' for options 'PDO::MYSQL_ATTR_LOCAL_INFILE'
176-
[023] Execting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND'
175+
[023] Expecting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND'
177176
[024] SQLSTATE[42000] [1065] Query was empty
178177
[025] SQLSTATE[42S02] [1146] Table '%s.nonexistent' doesn't exist
179178
done!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
ensure default for local infile is off
3+
--SKIPIF--
4+
<?php
5+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
6+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
7+
MySQLPDOTest::skip();
8+
if (!MYSQLPDOTest::isPDOMySQLnd())
9+
die("skip mysqlnd only test");
10+
?>
11+
--FILE--
12+
<?php
13+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc');
14+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
15+
16+
$dsn = MySQLPDOTest::getDSN();
17+
$user = PDO_MYSQL_TEST_USER;
18+
$pass = PDO_MYSQL_TEST_PASS;
19+
20+
$db = new PDO($dsn, $user, $pass);
21+
echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n";
22+
echo "done!\n";
23+
?>
24+
--EXPECTF--
25+
false
26+
done!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
enable local infile
3+
--SKIPIF--
4+
<?php
5+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
6+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
7+
MySQLPDOTest::skip();
8+
if (!MYSQLPDOTest::isPDOMySQLnd())
9+
die("skip mysqlnd only test");
10+
?>
11+
--FILE--
12+
<?php
13+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc');
14+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
15+
16+
$dsn = MySQLPDOTest::getDSN();
17+
$user = PDO_MYSQL_TEST_USER;
18+
$pass = PDO_MYSQL_TEST_PASS;
19+
20+
$db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_LOCAL_INFILE => true));
21+
echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n";
22+
echo "done!\n";
23+
?>
24+
--EXPECTF--
25+
true
26+
done!

0 commit comments

Comments
 (0)