php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #7219 Mysql-related stack fault with PHP 4.0.3
Submitted: 2000-10-15 09:35 UTC Modified: 2002-06-18 18:15 UTC
From: rubein at earthlink dot net Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 4.0.3 OS: Win98
Private report: No CVE-ID: None
 [2000-10-15 09:35 UTC] rubein at earthlink dot net
The following section of code produces a stack fault in PHP 4.0.3:

while(1) {
	$append = array();
	$append[0] = $resid;
	switch($restype) {
		case "messages":	case "m":	$append[1] = "messages";	$child = "messages";	$parent = "threads";	break;
		case "threads":	case "t":	$append[1] = "threads";		$child = "threads";	$parent = "boards";	break;
		case "boards":	case "b":	$append[1] = "boards";		$child = "boards";	$parent = "boards";	break;
		case "realms":	case "r":	$append[1] = "realms";		$restype = "realms";	break;
	}
	$ret[] = $append;
	if($restype == "realms") return $ret;
	
	$result = mysql_query("SELECT p.id AS id FROM $child AS c, $parent AS p WHERE c.id=$resid AND p.id=c.parent"); // THis is line 378.
	if($result = mysql_fetch_array($result, MYSQL_ASSOC)) {
		$restype = $parent;
		$resid = $result["id"];
	}
	else {
		$restype = "realms";
		$resid = $realmid;
	}
}


Judging from some debug code I tossed in, this (bad) query is being sent to mysql:

SELECT p.id AS id FROM AS c, AS p WHERE c.id=1 AND p.id=c.parent

Although the query is incorrect (there's apparently a bug in my code somewhere, but that's irrelevant for the purposes of this bug report), it would make far more sense for PHP to either catch itself or at least get caught in an infinite loop. Instead, it stack faults:

PHP caused a stack fault in module MSVCRT.DLL at 015f:780035be.
Registers:
EAX=00542138 CS=015f EIP=780035be EFLGS=00010216
EBX=00000002 SS=0167 ESP=00541ed8 EBP=00000000
ECX=00543174 DS=0167 ESI=00000000 FS=9e6f
EDX=100cdcf4 ES=0167 EDI=007634a0 GS=0000
Bytes at CS:EIP:
53 55 56 57 8b bc 24 64 02 00 00 33 c9 33 ed 89 
Stack dump:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

This bug is reproduced any time the script is reloaded. The warning (Repeated several, several times) is this:

Warning: Supplied argument is not a valid MySQL result resource in include.php on line 378


Operating system: Win98
Webserver: Apache 1.3.12/Win32
PHP: 4.0.3, running as a CGI module
Using the built-in mysql extensions under MySQL 3.23.25-beta (as determined by SELECT version();)

- Daniel Grace

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-10-15 09:51 UTC] rubein at earthlink dot net
Actually, after more thorough testing it was determined that *this* was the cause of the problem, a function which depended on the code of the above function:

function secALevel($resid, $restable, $realmid, $uid, $explicit = 0) {
	// Determine the parent tree
	if($explicit == 1)	
		$plist = array(array(0 => $resid, 1 => $restable));
	else
		$plist = brdParentTree($resid, $restable, $realmid);
	
	$prequery = array();
	foreach($plist AS $value) {
		$prequery[] = "(parent=$value[0] AND parent_table=$value[1])";   /* CAUSES CRASHES */
	}

	$whereclause = implode(" OR ", $prequery);
	echo "\n<BR>DEBUG: whereclause is $whereclause";
	flush();

	// Perform the query
	if(!$result = mysql_query("SELECT value FROM access AS a,users AS u WHERE ($whereclause) AND uid=$uid")) 
		htmPageError("secALevel(): Failed to retrieve access list. " . sqlError());

	$ret = AL_GUEST;

	while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
		if($row["level"] > $ret || ($row["level"] == AL_NEWBIE && $ret = AL_USER)) $ret = $row["level"];
	}

	return $ret;
}

---
If the commented CAUSES crashes line is changed so that the string is properly quoted (within the query, e.g.) AND has the closing parenthesis, things work fine. E.g. replacing it with this line works:

$prequery[] = "(parent=$value[0] AND parent_table=" . strQuote($value[1]) . ")";


(strQuote is a small function I wrote that either returns 'null' or an escaped string with quotation marks around it, useful for turning user input into mysql queries)
 [2001-01-07 03:57 UTC] sniper@php.net
Does this happen with PHP 4.0.4 ??

--Jani
 [2001-01-09 12:38 UTC] cynic@php.net
user feedback:
----
I no longer have the offending code handy (it was buggy and has since been fixed), however I have seriously narrowed it down to what causes it. The following code, however, reproduces the crash in both PHP 4.0.3 and PHP 4.0.4

<?
function test() {
  test();
}

test();
?>
----

PHP doesn't check for the level of recursion, so such a function will eventually eat up all of your memory. You have to perform due checks and break as needed.


 [2001-01-09 12:47 UTC] sniper@php.net
Duplicate of #8471


 [2001-01-09 12:48 UTC] derick@php.net
dup of 8471
 [2002-06-18 18:15 UTC] sniper@php.net
you can cause these with any infinite recursive function for example. The #8471 bug is Suspended..no need to have duplicates of it.

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 00:01:28 2024 UTC