ID: 47928 Updated by: [email protected] Reported By: jjuergens at web dot de Status: Verified Bug Type: MySQLi related Operating System: * PHP Version: 5.2CVS-2009-04-19 New Comment:
See also bug #46808 Previous Comments: ------------------------------------------------------------------------ [2009-04-19 14:07:02] [email protected] Here is the shortest possible test I could come up with: <?php /* Test database and table with data: drop database crashtest; create database crashtest; use crashtest; create table crash ( test longtext ); insert into crash set test='123456789'; grant select on crashtest.* to 'test'@'localhost'; */ $dbLink=new mysqli("localhost","test","","crashtest",3306); $stmt=$dbLink->prepare("SELECT test FROM crash"); $stmt->execute(); $stmt->bind_result($foo); while($stmt->fetch()); $stmt->close(); ?> The problem seems to be with the longtext column. If that is changed to text column, everything works just fine. ------------------------------------------------------------------------ [2009-04-19 10:59:40] [email protected] Above example causes crash also on my test server. (I removed other irrelevant comments) ------------------------------------------------------------------------ [2009-04-18 09:57:10] jjuergens at web dot de <?php //IMPORTANT: Database-Name (here: tst) needs to have exactly 3 characters! $dbLink=new mysqli("localhost","user","pass","tst",3306); $dbLink->query("CREATE TABLE IF NOT EXISTS `sessionData` ( `sessionId` varchar(60) collate utf8_unicode_ci NOT NULL, `pathHash` varchar(32) collate utf8_unicode_ci NOT NULL, `path` varchar(100) collate utf8_unicode_ci NOT NULL, `data` longtext collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`sessionId`,`pathHash`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"); $dbLink->query("INSERT INTO `sessionData` (`sessionId`, `pathHash`, `path`, `data`) VALUES ('e75c7781166e3a361b7cff546563d5e8', '633fed500f479acaaaf54be8ec9ac657', '/bla', '0018a901234001222425678901235678345612341315789012345678901234567890123423456789012223456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678')"); $stmt=$dbLink->prepare("SELECT * FROM `sessionData` WHERE `sessionId`=? AND `pathHash`=? LIMIT 1"); $arg1="e75c7781166e3a361b7cff546563d5e8"; $arg2="633fed500f479acaaaf54be8ec9ac657"; $stmt->bind_param("ss",$arg1,$arg2); $stmt->execute(); $resData=$stmt->result_metadata(); while($field=mysqli_fetch_field($resData)){ $resFields[$field->name]=null; } call_user_func_array(array($stmt,'bind_result'),$resFields); $result=array(); while($stmt->fetch()){ $tmpRes=array(); foreach($resFields as $key=>$value){ $tmpRes[$key]=$value; } array_push($result,$tmpRes); } $stmt->close(); print_r($result); ?> ------------------------------------------------------------------------ [2009-04-08 20:37:18] jjuergens at web dot de Description: ------------ When trying to retrieve data from a MySQL-Database using a mysqli-statement, PHP just crashes. I excerpted the code below from a larger web-application and invoked it via the PHP-Cli and it still fails with a memory-error. Interestingly enough though, if you just change a single value within $arg1 and $arg2 (e.g. replace the last 8 from $arg1 with a 7), the bug doesn't occur anymore. I've included a Valgrind-output which shows the error. MySQL-Version is 5.0.67. Reproduce code: --------------- <?php /* This is the database-table used: CREATE TABLE `sessionData` ( `sessionId` varchar(60) collate utf8_unicode_ci NOT NULL, `pathHash` varchar(32) collate utf8_unicode_ci NOT NULL, `path` varchar(100) collate utf8_unicode_ci NOT NULL, `data` longtext collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`sessionId`,`pathHash`), CONSTRAINT `sessionData_ibfk_1` FOREIGN KEY (`sessionId`) REFERENCES `sessionIndex` (`sessionId`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci */ //create db-link $dbLink=new mysqli("host","user","pass","db",3306); //create the statement $stmt=$dbLink->prepare("SELECT * FROM `sessionData` WHERE `sessionId`=? AND `pathHash`=? LIMIT 1"); //bind params $arg1="e75c7781166e3a361b7cff546563d5e8"; $arg2="9ddec3abec5c92628022210892e76afb"; $stmt->bind_param("ss",$arg1,$arg2); //execute $stmt->execute(); //create set of result-fields (see http://php.net/manual/de/mysqli-stmt.bind-result.php#85470) $resData=$stmt->result_metadata(); $resFields=array(); $bindArray=array(); while($field=mysqli_fetch_field($resData)){ $resFields[]=&$bindArray[$field->name]; } //bind result-fields call_user_func_array(array($stmt,'bind_result'),$resFields); //fetch result $res=0; while($stmt->fetch()){ $tmpRes=array(); foreach($bindArray as $key=>$value){ $tmpRes[$key]=$value; } //add this row (not needed for bug reproduction) // array_push($result,$tmpRes); $res++; } //close statement $stmt->close(); Expected result: ---------------- In this case, the script should just exit normally without a result. Actual result: -------------- Running it in a shell, I get a memory-error. Using Valgrind, I get the following: ==13749== Memcheck, a memory error detector. ==13749== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==13749== Using LibVEX rev 1854, a library for dynamic binary translation. ==13749== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==13749== Using valgrind-3.3.1, a dynamic binary instrumentation framework. ==13749== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==13749== For more details, rerun with: -v ==13749== ==13749== Invalid read of size 4 ==13749== at 0x51AA261: mysql_stmt_fetch (in /usr/lib/libmysqlclient.so.15.0.0) ==13749== by 0x5187D5C: zif_mysqli_stmt_fetch (in /usr/lib/php5/extensions/mysqli.so) ==13749== by 0x81DE342: (within /usr/bin/php5) ==13749== by 0x81C94BA: execute (in /usr/bin/php5) ==13749== by 0x81A3D4F: zend_execute_scripts (in /usr/bin/php5) ==13749== by 0x81589F9: php_execute_script (in /usr/bin/php5) ==13749== by 0x821C780: main (in /usr/bin/php5) ==13749== Address 0x84 is not stack'd, malloc'd or (recently) free'd ==13749== ==13749== Process terminating with default action of signal 11 (SIGSEGV) ==13749== Access not within mapped region at address 0x84 ==13749== at 0x51AA261: mysql_stmt_fetch (in /usr/lib/libmysqlclient.so.15.0.0) ==13749== by 0x5187D5C: zif_mysqli_stmt_fetch (in /usr/lib/php5/extensions/mysqli.so) ==13749== by 0x81DE342: (within /usr/bin/php5) ==13749== by 0x81C94BA: execute (in /usr/bin/php5) ==13749== by 0x81A3D4F: zend_execute_scripts (in /usr/bin/php5) ==13749== by 0x81589F9: php_execute_script (in /usr/bin/php5) ==13749== by 0x821C780: main (in /usr/bin/php5) ==13749== ==13749== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 118 from 2) ==13749== malloc/free: in use at exit: 1,296,363 bytes in 13,676 blocks. ==13749== malloc/free: 14,687 allocs, 1,011 frees, 2,096,685 bytes allocated. ==13749== For counts of detected errors, rerun with: -v ==13749== searching for pointers to 13,676 not-freed blocks. ==13749== checked 1,736,688 bytes. ==13749== ==13749== LEAK SUMMARY: ==13749== definitely lost: 30,599 bytes in 11 blocks. ==13749== possibly lost: 10,263 bytes in 2 blocks. ==13749== still reachable: 1,255,501 bytes in 13,663 blocks. ==13749== suppressed: 0 bytes in 0 blocks. ==13749== Rerun with --leak-check=full to see details of leaked memory. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=47928&edit=1
