php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #60882 PDO crashes PHP FastCGI daemon when querying Sphinx server
Submitted: 2012-01-25 14:01 UTC Modified: 2017-10-24 08:07 UTC
Votes:7
Avg. Score:4.6 ± 0.7
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:2 (50.0%)
From: balshoy dot tone at gmail dot com Assigned:
Status: Open Package: PDO MySQL
PHP Version: 5.4.0RC6 OS: Ubuntu 11.10
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-01-25 14:01 UTC] balshoy dot tone at gmail dot com
Description:
------------
I have a sphinx server with real time indexes and I'm trying to query them using 
PDO via sphinx MySQL protocol.

Every time a script runs into `$pdo->execute(array(1))` part the whole PHP 
FastCGI daemon crashes, no errors displayed in php error log.

Everything works normally when I query ordinary MySQL database this way.
Also provided code works fine in PHP 5.3

Test script:
---------------
$dsn = "mysql:host=127.0.0.1;port=9306;dbname=index";
$pdo = new PDO($dsn, '<user>', '<password>'); 
    		
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
$stmt = $pdo->prepare("SELECT * FROM user WHERE id = ?"); 
$rslt = $stmt->execute(array(1)); // crash

var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));

Expected result:
----------------
Either result set or PDO exception should be displayed.

Actual result:
--------------
Script fails silently without any records in error.log
Also PHP FastCGI daemon gets terminated.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-07-05 14:57 UTC] vitalif at yourcmc dot ru
I've discovered what's the error is using gdb - MysqlND can't determine the charset when connecting to Sphinx, because it skips authentication.

So the workaround is very simple - add ";charset=utf8" to your DSN.
Like the following:
$dsn = "mysql:host=127.0.0.1;port=9306;dbname=index;charset=utf8";

+ just for the information, stack trace of php crash:
Program received signal SIGSEGV, Segmentation fault.
mysqlnd_cset_escape_slashes (cset=0x0, newstr=0x7f5521562ce1 "", escapestr=0x7f552146d438 "майка", escapestr_len=<value optimized out>)
    at /home/pspesivt/setup/php-5.4.4/ext/mysqlnd/mysqlnd_charset.c:719
719                     if (cset->char_maxlen > 1 && (len = cset->mb_valid(escapestr, end))) {
(gdb) bt
#0  mysqlnd_cset_escape_slashes (cset=0x0, newstr=0x7f5521562ce1 "", escapestr=0x7f552146d438 "майка", escapestr_len=<value optimized out>)
    at /home/pspesivt/setup/php-5.4.4/ext/mysqlnd/mysqlnd_charset.c:719
#1  0x0000000000765e41 in php_mysqlnd_conn_data_escape_string_pub (conn=0x7f5521562238, newstr=0x7f5521562ce1 "", escapestr=0x7f552146d438 "майка", escapestr_len=10)
    at /home/pspesivt/setup/php-5.4.4/ext/mysqlnd/mysqlnd.c:1470
#2  0x00000000005fe5dd in mysql_handle_quoter (dbh=<value optimized out>, unquoted=0x7f552146d438 "майка", unquotedlen=10, quoted=0x2aa2368, quotedlen=0x2aa2360, 
    paramtype=<value optimized out>) at /home/pspesivt/setup/php-5.4.4/ext/pdo_mysql/mysql_driver.c:309
#3  0x00000000005fdb08 in pdo_parse_params (stmt=0x7f55215628d8, 
    inquery=0x7f552155f278 "SELECT id, WEIGHT() rank FROM sportmaster_catalog WHERE MATCH(:query) LIMIT 1000", inquery_len=44704592, outquery=0x7f5521562968, 
    outquery_len=0x7f5521562970) at /home/pspesivt/setup/php-5.4.4/ext/pdo/pdo_sql_parser.c:584
#4  0x00000000005fb2bb in zim_PDOStatement_execute (ht=<value optimized out>, return_value=0x2aa2298, return_value_ptr=<value optimized out>, 
    this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /home/pspesivt/setup/php-5.4.4/ext/pdo/pdo_stmt.c:497
#5  0x00007f5510e9e58f in xdebug_execute_internal (current_execute_data=0x7f55215265d8, return_value_used=0) at /home/pspesivt/setup/xdebug-2.2.0/xdebug.c:1482
#6  0x000000000085ee56 in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>) at /home/pspesivt/setup/php-5.4.4/Zend/zend_vm_execute.h:644
#7  0x000000000084c280 in execute (op_array=0x7f552155d518) at /home/pspesivt/setup/php-5.4.4/Zend/zend_vm_execute.h:410
#8  0x00007f5510e9eaa9 in xdebug_execute (op_array=0x7f552155d518) at /home/pspesivt/setup/xdebug-2.2.0/xdebug.c:1390
#9  0x00000000007e33ff in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/pspesivt/setup/php-5.4.4/Zend/zend.c:1279
#10 0x0000000000786b47 in php_execute_script (primary_file=0x7fff91c803f0) at /home/pspesivt/setup/php-5.4.4/main/main.c:2473
#11 0x0000000000896159 in main (argc=559047608, argv=0x7f55215264e0) at /home/pspesivt/setup/php-5.4.4/sapi/fpm/fpm/fpm_main.c:1856
 [2012-07-28 20:29 UTC] felipe@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: mysql
 [2012-07-30 11:03 UTC] johannes@php.net
If no charset is provided functions like "mysql_real_escape_string" (php_mysqlnd_conn_data_escape_string_pub in mysqlnd) can't work reliably. In my opinion it is a bug of Sphinx to send charset "0". Nonetheless PHP shouldn't crash but the escape routine should terminate (fatal error / exception) to prevent mistakes from happening (wrong escaping leading to security issues or truncation of data). Please also note that mysqlnd follows the MySQL protocol. If other daemons use the MySQL protocol it is primarily their responsibility to be compatible.

The mentioned work-around of setting the charset is suggested.

Unfortunately the code was recently changed to catch invalid charsets during connect. mysqlnd will now throw a warning. PDO will notice this and convert it to an exception even if a custom charset was set, making Sphinx unusable with PDO as sphinx's behavior was unknown. We'll look for a safe fix, while I'd suggest talking to Sphinx, too, for having them set a proper charset.

Current behavior:
   <?php
   $p = new PDO("mysql:host=127.0.0.1;port=9306;dbname=index;charset=utf8", "", "");
   ?>

   Warning: PDO::__construct(): Server sent charset (0) unknown to the client. Please, report to the developers in test.php on line 2

   Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2054] Server sent charset unknown to the client. Please, report to the developers' in test.php:2
 [2014-01-01 12:40 UTC] felipe@php.net
-Package: PDO related +Package: PDO MySQL
 [2017-10-24 08:07 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: mysql +Assigned To:
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 10:01:30 2024 UTC