|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2011-04-21 08:28 UTC] an0nym at narod dot ru
Description:
------------
PHP segfaults when prepared statement that threw an exception is reexecuted. pdo_mysql, libmysql. Haven't tested with mysqlnd yet.
Test script:
---------------
<?php
$DB = new PDO("mysql:dbname=test;host=localhost", "root", "",
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false));
$DB->exec("CREATE TEMPORARY TABLE t(f VARCHAR(1))");
$stmt = $DB->prepare("INSERT INTO t VALUES(:value)");
$value = "aa";
$stmt->bindParam(":value", $value);
try {
$stmt->execute();
} catch (PDOException $e) {}
$stmt->execute();
Expected result:
----------------
Script successfully executed
Actual result:
--------------
Segmentation fault
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 12:00:01 2025 UTC |
It seems you don't have strict mode enabled. Try this. <?php $DB = new PDO("mysql:dbname=test;host=localhost", "root", "", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_INIT_COMMAND => "SET SQL_MODE = 'STRICT_ALL_TABLES'")); $DB->exec("CREATE TEMPORARY TABLE t(f VARCHAR(1))"); $stmt = $DB->prepare("INSERT INTO t VALUES(:value)"); $value = "aa"; $stmt->bindParam(":value", $value); try { $stmt->execute(); } catch (PDOException $e) {} $stmt->execute();Sorry, CentOS is with mysqlnd now. Testing on Fedora: root@test # uname -a Linux test 2.6.35.11-83.fc14.x86_64 #1 SMP Mon Feb 7 07:06:44 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux 06:32:59 ~ root@test # php -v PHP 5.3.6 (cli) (built: Mar 17 2011 20:56:13) Copyright (c) 1997-2011 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies 06:33:02 ~ root@test # find / | grep libmysql /usr/lib64/mysql/libmysqlclient.so.16.0.0 /usr/lib64/mysql/libmysqlclient_r.so.16.0.0 /usr/lib64/mysql/libmysqlclient_r.so.16 /usr/lib64/mysql/libmysqlclient.so.16 06:33:06 ~ root@test # cat test.php <?php var_dump(function_exists("mysqli_fetch_all")); $DB = new PDO("mysql:dbname=test;host=localhost", "root", "", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_INIT_COMMAND => "SET SQL_MODE = 'STRICT_ALL_TABLES'")); $DB->exec("CREATE TEMPORARY TABLE t(f VARCHAR(1))"); $stmt = $DB->prepare("INSERT INTO t VALUES(:value)"); $value = "aa"; $stmt->bindParam(":value", $value); try { $stmt->execute(); } catch (PDOException $e) {} $stmt->execute(); 06:33:17 ~ root@test # php test.php bool(false) Segmentation fault 06:33:24 ~ root@test # mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.1.56 Source distribution Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This software comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to modify and redistribute it under the GPL v2 license Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit Bye 06:34:43 ~ root@test #Affects libmysql only. No issue when using mysqlnd. Johannes, please review and apply patch: nixnutz@linux-fuxh:~/php/php-src/branches/PHP_5_3> svn diff ext/pdo_mysql/ Index: ext/pdo_mysql/mysql_statement.c =================================================================== --- ext/pdo_mysql/mysql_statement.c (Revision 310880) +++ ext/pdo_mysql/mysql_statement.c (Arbeitskopie) @@ -136,6 +136,7 @@ { pdo_mysql_stmt *S = stmt->driver_data; pdo_mysql_db_handle *H = S->H; + int paramno; PDO_DBG_ENTER("pdo_mysql_stmt_execute_prepared_libmysql"); @@ -143,6 +144,10 @@ if (mysql_stmt_bind_param(S->stmt, S->params) || mysql_stmt_execute(S->stmt)) { if (S->params) { memset(S->params, 0, S->num_params * sizeof(MYSQL_BIND)); + for (paramno = 0; paramno < S->num_params; paramno++) { + S->params[paramno].is_null = &S->in_null[paramno]; + S->params[paramno].length = &S->in_length[paramno]; + } } pdo_mysql_error_stmt(stmt); if (mysql_stmt_errno(S->stmt) == 2057) {