ID:               47928
 Comment by:       wcshields at gmail dot com
 Reported By:      jjuergens at web dot de
 Status:           Verified
 Bug Type:         MySQLi related
 Operating System: *
 PHP Version:      5.2CVS-2009-04-19
 New Comment:

I just noticed the status of #46808 is marked as "Bogus". Unfortunately
there's no history to see who marked it that way or why but I guess that
explains why no action was taken on it.

This issue has been reported in various forms for over two years now.
The fact that such reports were written off essentially as hoaxes or
pranks or just plain incompetence by everyone else speaks volumes about
the lack of professionalism and due diligence by whoever is responsible
for investigating such bugs.

So Allelujah that someone finally bothered--years later--to actually
fix it. Maybe if the PHP devs took such reports more seriously, packages
like mysqli wouldn't be the horrible buggy messes that they are.


Previous Comments:
------------------------------------------------------------------------

[2009-04-19 14:11:14] [email protected]

See also bug #46808


------------------------------------------------------------------------

[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

Reply via email to