diff options
author | Darek Slusarczyk <dariusz.slusarczyk@oracle.com> | 2019-02-11 18:18:57 +0100 |
---|---|---|
committer | Darek Slusarczyk <dariusz.slusarczyk@oracle.com> | 2019-02-11 18:18:57 +0100 |
commit | 6f7a47db5dc5a11333e131a071f20c0be19183a9 (patch) | |
tree | 0a238c5f00bdb62829c788fdf2c89ff13d9a3271 | |
parent | 4da67537c1bb5909e2f32c81534e316bff1af2f8 (diff) | |
parent | 83d2bc9b6df2f827217f1bc3298fb83cfe2ac210 (diff) | |
download | php-git-6f7a47db5dc5a11333e131a071f20c0be19183a9.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
-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
@@ -37,6 +37,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.3.2 - Core: diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index a25bc096ce..73511b2639 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -516,7 +516,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() /* }}} */ @@ -541,7 +541,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 8c5b6aa23c..1f68a1fe6e 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 f9fb962e77..639603aa50 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 6f1cd5faa7..1994a5ec96 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 21851d6b30..56ee2cce05 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 dcc7ad5715..5e4b56173b 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 9f8e1fb5b9..5cb416e5ce 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -480,7 +480,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 eb3473f11e..b7b6770327 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -484,6 +484,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: @@ -770,6 +776,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! |