MYSQLND + PDO MySQL requires #define MYSQL_OPT_LOCAL_INFILE
| Bug #54158 | MYSQLND + PDO MySQL requires #define MYSQL_OPT_LOCAL_INFILE | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Submitted: | 2011-03-04 01:18 UTC | Modified: | 2011-09-09 07:03 UTC |
|
||||||||||
| From: | tamas at ideaweb dot hu | Assigned: | mysql (profile) | |||||||||||
| Status: | Closed | Package: | PDO related | |||||||||||
| PHP Version: | 5.3.5 | OS: | Linux | |||||||||||
| Private report: | No | CVE-ID: | None | |||||||||||
[2011-03-04 01:18 UTC] tamas at ideaweb dot hu
Description:
------------
Hi,
On php 5.3.x PDO LOAD DATA LOCAL INFILE support seems broken. Running the code below issues a warning:
Warning: PDOStatement::execute(): LOAD DATA LOCAL INFILE forbidden in /home/tamas/percona/load3.php on line 17
This is coming from mysqlnd when CLIENT_LOCAL_FILES option is disabled. Looking at the trace file, PDO doesn't call mysql_options (set_client_option) to enable local infile support. I tracked down this is caused by the following ifdef in ext/pdo_mysql/mysql_driver.c:
#ifdef MYSQL_OPT_LOCAL_INFILE
if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) {
pdo_mysql_error(dbh);
goto cleanup;
}
#endif
MYSQL_OPT_LOCAL_INFILE is undefined hence the whole block which would enable local infile support is disabled. When the ifdef/endif line is commented out everything works. I also tested with mysqli, that is unaffected and works as expected.
And a related bug to this one: http://bugs.php.net/46964
Configure Command => './configure' '--prefix=/home/tamas/percona/php53dbg' '--disable-all' '--with-pdo-mysql=mysqlnd' '--enable-debug' '--enable-pdo' '--with-mysqli=mysqlnd' '--with-mysql=mysqlnd'
Thanks,
Tamas
Test script:
---------------
define('MYSQL_ALL_DSN','mysql:host=10.8.0.1;dbname=c');
define('MYSQL_ALL_USER','a');
define('MYSQL_ALL_PASS','b');
$sql = 'LOAD DATA LOCAL INFILE \'/home/tamas/percona/testLoad.data\' INTO TABLE mail_message '.
'FIELDS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'"\' LINES TERMINATED BY \'\n\' '.
'(priority, user_id, `to`, template_id, data, custom_text_hash, spam)';
$con = new PDO(MYSQL_ALL_DSN, MYSQL_ALL_USER, MYSQL_ALL_PASS,
array(
PDO::MYSQL_ATTR_LOCAL_INFILE => 1,
));
$stmt = $con->prepare($sql);
$stmt->execute();
Patches
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2011-03-04 10:21 UTC] andrey@php.net
-Status: Open +Status: Analyzed -Assigned To: +Assigned To: mysql
[2011-03-04 10:21 UTC] andrey@php.net
[2011-04-03 01:08 UTC] anthon dot pang at gmail dot com
[2011-04-03 03:57 UTC] anthon dot pang at gmail dot com
[2011-09-09 07:03 UTC] andrey@php.net
-Status: Analyzed +Status: Closed
[2012-01-15 00:31 UTC] denis_truffaut at hotmail dot com
[2012-01-15 03:20 UTC] denis_truffaut at hotmail dot com
ext/pdo_mysql/mysql_driver.c, line 635 : if (mysql_options(H->sergedit ver, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { Should be local_infile = 1; if (mysql_options(H->sergedit ver, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { You can achieve this dirty and quickly in doing : sudo sed -ie 's/if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE/local_infile = 1;if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE/g' ext/pdo_mysql/mysql_driver.c[2013-08-02 13:49 UTC] chris dot de dot kok at gmail dot com