diff options
author | Darek Slusarczyk <dariusz.slusarczyk@oracle.com> | 2019-02-11 18:08:21 +0100 |
---|---|---|
committer | Darek Slusarczyk <dariusz.slusarczyk@oracle.com> | 2019-02-11 18:08:21 +0100 |
commit | 83d2bc9b6df2f827217f1bc3298fb83cfe2ac210 (patch) | |
tree | d511c4d57e63ff0d0de4e8f17783d62e6deb224b | |
parent | ec28d4c247ef3c7ab9af41ff6e26b802694492b2 (diff) | |
parent | 2eaabf06fc5a62104ecb597830b2852d71b0a111 (diff) | |
download | php-git-83d2bc9b6df2f827217f1bc3298fb83cfe2ac210.tar.gz |
Merge branch 'PHP-7.1' into PHP-7.2
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | ext/mysqli/mysqli.c | 4 | ||||
-rw-r--r-- | ext/mysqli/tests/061.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/bug36745.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/bug53503.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/bug68077.phpt | 3 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_constants.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_get_client_stats.phpt | 1 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_info.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_local_infile_default_off.phpt | 26 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_local_infile_set_on.phpt | 28 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_real_connect.phpt | 2 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_real_connect_pconn.phpt | 1 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_connection.c | 3 | ||||
-rw-r--r-- | ext/pdo_mysql/mysql_driver.c | 15 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt | 5 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt | 26 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt | 26 |
18 files changed, 149 insertions, 6 deletions
@@ -18,6 +18,11 @@ PHP NEWS . Fixed bug #77552 (Unintialized php_stream_statbuf in stat functions). (John Stevenson) +- MySQL + . Disabled LOCAL INFILE by default, can be enabled using php.ini directive + mysqli.allow_local_infile for mysqli, or PDO::MYSQL_ATTR_LOCAL_INFILE + attribute for pdo_mysql. (Darek Slusarczyk) + 07 Feb 2019, PHP 7.2.15 - Core: diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 2d3b08bcb5..9e9f45fef9 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -524,7 +524,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("mysqli.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals) #endif STD_PHP_INI_BOOLEAN("mysqli.reconnect", "0", PHP_INI_SYSTEM, OnUpdateLong, reconnect, zend_mysqli_globals, mysqli_globals) - STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "0", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals) PHP_INI_END() /* }}} */ @@ -549,7 +549,7 @@ static PHP_GINIT_FUNCTION(mysqli) mysqli_globals->reconnect = 0; mysqli_globals->report_mode = 0; mysqli_globals->report_ht = 0; - mysqli_globals->allow_local_infile = 1; + mysqli_globals->allow_local_infile = 0; #ifdef HAVE_EMBEDDED_MYSQLI mysqli_globals->embedded = 1; #else diff --git a/ext/mysqli/tests/061.phpt b/ext/mysqli/tests/061.phpt index a6a0c4f205..12efe39c3f 100644 --- a/ext/mysqli/tests/061.phpt +++ b/ext/mysqli/tests/061.phpt @@ -17,6 +17,8 @@ if ($msg = check_local_infile_support($link, $engine)) mysqli_close($link); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php require_once("connect.inc"); diff --git a/ext/mysqli/tests/bug36745.phpt b/ext/mysqli/tests/bug36745.phpt index 5e203e14eb..7a630afdc5 100644 --- a/ext/mysqli/tests/bug36745.phpt +++ b/ext/mysqli/tests/bug36745.phpt @@ -5,6 +5,8 @@ Bug #36745 (LOAD DATA LOCAL INFILE doesn't return correct error message) require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php require_once("connect.inc"); diff --git a/ext/mysqli/tests/bug53503.phpt b/ext/mysqli/tests/bug53503.phpt index bb8d00109f..fea62fde79 100644 --- a/ext/mysqli/tests/bug53503.phpt +++ b/ext/mysqli/tests/bug53503.phpt @@ -15,6 +15,8 @@ if ($msg = check_local_infile_support($link, $engine)) mysqli_close($link); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php require_once("connect.inc"); diff --git a/ext/mysqli/tests/bug68077.phpt b/ext/mysqli/tests/bug68077.phpt index 0652e68c9b..174599ab48 100644 --- a/ext/mysqli/tests/bug68077.phpt +++ b/ext/mysqli/tests/bug68077.phpt @@ -17,6 +17,9 @@ if ($msg = check_local_infile_support($link, $engine)) mysqli_close($link); ?> --INI-- +mysqli.allow_local_infile=1 +mysqli.allow_persistent=1 +mysqli.max_persistent=1 open_basedir= --FILE-- <?php diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 42113aef2b..64bd3a319b 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -6,6 +6,8 @@ require_once('skipif.inc'); require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php require("connect.inc"); diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt index 29f8b430de..07ef78f296 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -12,6 +12,7 @@ if (!function_exists('mysqli_get_client_stats')) { --INI-- mysqlnd.collect_statistics=1 mysqlnd.collect_memory_statistics=1 +mysqli.allow_local_infile=1 --FILE-- <?php /* diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt index d60ffd9fbe..9326a9c52a 100644 --- a/ext/mysqli/tests/mysqli_info.phpt +++ b/ext/mysqli/tests/mysqli_info.phpt @@ -6,6 +6,8 @@ require_once('skipif.inc'); require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php require_once("connect.inc"); diff --git a/ext/mysqli/tests/mysqli_local_infile_default_off.phpt b/ext/mysqli/tests/mysqli_local_infile_default_off.phpt new file mode 100644 index 0000000000..c2e8aa2dc8 --- /dev/null +++ b/ext/mysqli/tests/mysqli_local_infile_default_off.phpt @@ -0,0 +1,26 @@ +--TEST-- +ensure default for local infile is off +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once("connect.inc"); + +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); +$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"'); +$row = mysqli_fetch_assoc($res); +echo "server: ", $row['Value'], "\n"; +mysqli_free_result($res); +mysqli_close($link); + +echo "connector: ", ini_get("mysqli.allow_local_infile"), "\n"; + +print "done!\n"; +?> +--EXPECTF-- +server: %s +connector: 0 +done! diff --git a/ext/mysqli/tests/mysqli_local_infile_set_on.phpt b/ext/mysqli/tests/mysqli_local_infile_set_on.phpt new file mode 100644 index 0000000000..172d6dcb9b --- /dev/null +++ b/ext/mysqli/tests/mysqli_local_infile_set_on.phpt @@ -0,0 +1,28 @@ +--TEST-- +enable local infile +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php +require_once("connect.inc"); + +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); +$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"'); +$row = mysqli_fetch_assoc($res); +echo "server: ", $row['Value'], "\n"; +mysqli_free_result($res); +mysqli_close($link); + +echo "connector: ", ini_get("mysqli.allow_local_infile"), "\n"; + +print "done!\n"; +?> +--EXPECTF-- +server: %s +connector: 1 +done! diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt index a678399838..f68b51947b 100644 --- a/ext/mysqli/tests/mysqli_real_connect.phpt +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -6,6 +6,8 @@ require_once('skipif.inc'); require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); ?> +--INI-- +mysqli.allow_local_infile=1 --FILE-- <?php include("connect.inc"); diff --git a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt index 4cc18198c6..0d1c4985f2 100644 --- a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt +++ b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt @@ -10,6 +10,7 @@ if (!$IS_MYSQLND) die("skip mysqlnd only test"); ?> --INI-- +mysqli.allow_local_infile=1 mysqli.allow_persistent=1 mysqli.max_persistent=10 --FILE-- diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index ea3d1cb0b7..dc42a16b6d 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -489,7 +489,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * MYSQLND_VIO * vio = conn->vio; DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags"); - /* we allow load data local infile by default */ + /* allow CLIENT_LOCAL_FILES capability, although extensions basing on mysqlnd + shouldn't allow 'load data local infile' by default due to security issues */ mysql_flags |= MYSQLND_CAPABILITIES; mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */ diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 07aaa6f6c1..c0708ceb12 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -502,6 +502,12 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_ case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE: ZVAL_LONG(return_value, H->max_buffer_size); break; +#else + case PDO_MYSQL_ATTR_LOCAL_INFILE: + ZVAL_BOOL( + return_value, + (H->server->data->options->flags & CLIENT_LOCAL_FILES) == CLIENT_LOCAL_FILES); + break; #endif default: @@ -786,6 +792,15 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) } } #endif + } else { +#if defined(MYSQL_OPT_LOCAL_INFILE) || defined(PDO_USE_MYSQLND) + // in case there are no driver options disable 'local infile' explicitly + zend_long local_infile = 0; + if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { + pdo_mysql_error(dbh); + goto cleanup; + } +#endif } #ifdef PDO_MYSQL_HAS_CHARSET diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt index 62051d7ae2..08cd8eb942 100644 --- a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt @@ -19,7 +19,7 @@ MySQLPDOTest::skip(); try { $db = new PDO($dsn, $user, $pass, array($option => $value)); if (!is_object($db) || ($value !== ($tmp = @$db->getAttribute($option)))) - printf("[%03d] Execting '%s'/%s got '%s'/%s' for options '%s'\n", + printf("[%03d] Expecting '%s'/%s got '%s'/%s' for options '%s'\n", $offset, $value, gettype($value), $tmp, gettype($tmp), @@ -172,8 +172,7 @@ MySQLPDOTest::skip(); [016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on [017] PDO::ATTR_EMULATE_PREPARES should be off [018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off -[021] Execting '1'/boolean got ''/boolean' for options 'PDO::MYSQL_ATTR_LOCAL_INFILE' -[023] Execting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND' +[023] Expecting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND' [024] SQLSTATE[42000] [1065] Query was empty [025] SQLSTATE[42S02] [1146] Table '%s.nonexistent' doesn't exist done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt new file mode 100644 index 0000000000..5a0b5f67e0 --- /dev/null +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt @@ -0,0 +1,26 @@ +--TEST-- +ensure default for local infile is off +--SKIPIF-- +<?php +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); +MySQLPDOTest::skip(); +if (!MYSQLPDOTest::isPDOMySQLnd()) + die("skip mysqlnd only test"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc'); +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); + +$dsn = MySQLPDOTest::getDSN(); +$user = PDO_MYSQL_TEST_USER; +$pass = PDO_MYSQL_TEST_PASS; + +$db = new PDO($dsn, $user, $pass); +echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n"; +echo "done!\n"; +?> +--EXPECTF-- +false +done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt new file mode 100644 index 0000000000..4394bc0576 --- /dev/null +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt @@ -0,0 +1,26 @@ +--TEST-- +enable local infile +--SKIPIF-- +<?php +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); +MySQLPDOTest::skip(); +if (!MYSQLPDOTest::isPDOMySQLnd()) + die("skip mysqlnd only test"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc'); +require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); + +$dsn = MySQLPDOTest::getDSN(); +$user = PDO_MYSQL_TEST_USER; +$pass = PDO_MYSQL_TEST_PASS; + +$db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_LOCAL_INFILE => true)); +echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n"; +echo "done!\n"; +?> +--EXPECTF-- +true +done! |