php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51670 getColumnMeta causes segfault when re-executing query after calling nextRowset
Submitted: 2010-04-27 04:57 UTC Modified: 2010-04-27 07:57 UTC
From: ww dot galen at gmail dot com Assigned: pierrick (profile)
Status: Closed Package: PDO related
PHP Version: 5.3.2 OS: OS X 10.6.3
Private report: No CVE-ID: None
 [2010-04-27 04:57 UTC] ww dot galen at gmail dot com
Description:
------------
After executing a prepared statement and calling PDOStatement::nextRowset (whether 
or not there is more than one result set), then calling PDOStatement::execute a 
second time, PDOStatement::getColumnMeta causes a segfault. I guess it really is 
an experimental feature. 

  Platform info:
OS X 10.6.3
Apache 2.2.14
PHP 5.3.2 (also tested under 5.3.1 with same result)
MySQL 5.1.45


Test script:
---------------
$db = new PDO('mysql:...', ...);
$query = $db->prepare('SELECT 1 AS num;');
$query->execute();
$query->nextRowset();
$query->execute();
$query->getColumnMeta(0);

Expected result:
----------------
PDOStatement::getColumnMeta should return an array describing a column. For the 
test script, something like:

<code>
  array (
    'native_type' => 'LONGLONG',
    'pdo_type' => 2,
    'flags' => 
    array (
      0 => 'not_null',
    ),
    'table' => '',
    'name' => 'num',
    'len' => 1,
    'precision' => 0,
  )
</code>

Actual result:
--------------
Segfault. For example, on my machine I get:

Process:         httpd [31734]
Path:            /usr/sbin/httpd
Identifier:      httpd
Version:         ??? (???)
Code Type:       X86-64 (Native)
Parent Process:  httpd [31718]

Date/Time:       2010-04-26 19:02:55.650 -0700
OS Version:      Mac OS X 10.6.3 (10D573)
Report Version:  6

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libphp5.so                    	0x0000000101163923 
zim_PDOStatement_getColumnMeta + 262
1   libphp5.so                    	0x0000000101334704 
zend_do_fcall_common_helper_SPEC + 2409
2   libphp5.so                    	0x0000000101330fd9 execute + 585
3   libphp5.so                    	0x000000010130fe18 zend_execute_scripts 
+ 376
4   libphp5.so                    	0x00000001012c2b3a php_execute_script + 
705
5   libphp5.so                    	0x000000010138baf3 php_handler + 1237
6   httpd                         	0x00000001000012af ap_run_handler + 90
7   httpd                         	0x0000000100001b8e ap_invoke_handler + 
346
8   httpd                         	0x000000010002e784 ap_process_request + 
103
9   httpd                         	0x000000010002aff7 
ap_process_http_connection + 116
10  httpd                         	0x000000010001280b 
ap_run_process_connection + 90
11  httpd                         	0x0000000100012ca5 ap_process_connection 
+ 91
12  httpd                         	0x00000001000353f2 child_main + 1257
13  httpd                         	0x00000001000355a8 make_child + 329
14  httpd                         	0x000000010003582e 
perform_idle_server_maintenance + 498
15  httpd                         	0x0000000100035d58 ap_mpm_run + 1246
16  httpd                         	0x00000001000098f5 main + 2854
17  httpd                         	0x0000000100000914 start + 52

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000001  rbx: 0x0000000000000000  rcx: 0x00007fff5fbfef48  
rdx: 0x0000000000000028
  rdi: 0x00000001007412be  rsi: 0x00000001013dbdde  rbp: 0x00007fff5fbfeff0  
rsp: 0x00007fff5fbfefc0
   r8: 0x0000000000000001   r9: 0x0000000000000006  r10: 0x00000001013cf158  
r11: 0x00000001007412b8
  r12: 0x000000010073d000  r13: 0x000000010073c4a0  r14: 0x0000000000000001  
r15: 0x0000000000000000
  rip: 0x0000000101163923  rfl: 0x0000000000000246  cr2: 0x0000000000000000

Patches

fix-nextRowset.getColumnMeta-segfault (last revision 2010-04-27 03:35 UTC by ww dot galen at gmail dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-04-27 05:11 UTC] ww dot galen at gmail dot com
In particular, it's failing on line 1864 of pdo_stmt.c:

    add_assoc_string(return_value, "name", col->name, 1);

'col' is null because 'stmt->columns' is null.
 [2010-04-27 05:22 UTC] ww dot galen at gmail dot com
The cause seems to be lines 513-523 of pdo_stmt.c:

    if (!stmt->executed) {
        /* this is the first execute */

        if (stmt->dbh->alloc_own_columns && !stmt->columns) {
            /* for "big boy" drivers, we need to allocate memory to fetch
             * the results into, so lets do that now */
            ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
        }

        stmt->executed = 1;
    }

Columns are only described if the statement hasn't been executed.
 [2010-04-27 05:40 UTC] ww dot galen at gmail dot com
Moving the inner test to just after the outer test so that columns are described 
whenever "stmt->columns" is null seems to fix the segfault. This is what the patch 
does, reproduced here:

    if (!stmt->executed) {
        /* this is the first execute */

        stmt->executed = 1;
    }
    // if nextRowset was called, we need to redescribe 
    if (stmt->dbh->alloc_own_columns && !stmt->columns) {
        /* for "big boy" drivers, we need to allocate memory to fetch
         * the results into, so lets do that now */
        ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
    }

Whether this is appropriate and won't cause other bugs or even if it fixes all cases, 
I couldn't tell you.
 [2010-04-27 07:56 UTC] pierrick@php.net
Automatic comment from SVN on behalf of pierrick
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=298637
Log: Fixed bug #51670 getColumnMeta causes segfault when re-executing query after calling nextRowset
 [2010-04-27 07:57 UTC] pierrick@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: pierrick
 [2010-04-27 07:57 UTC] pierrick@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC