Bug 53650

Summary: a script segfaults PHP
Product: [Retired] Red Hat Linux Reporter: Florin Andrei <florin>
Component: phpAssignee: Phil Copeland <copeland>
Status: CLOSED ERRATA QA Contact: David Lawrence <dkl>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.0   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-12-07 23:58:50 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Florin Andrei 2001-09-13 22:19:04 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.3) Gecko/20010823

Description of problem:
I try to debug a wrong PHP script, using "php -l scriptname.php"
But i get a coredump :-(

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1.run "php -l myscript.php"
2.
3.
	

Actual Results:  segfault

Additional info:

Here is my script that coredumps PHP:

<?php
$db_host = "localhost";
$db_user = "network";
$db_pass = "gallowspole";
$db_base = "network";

$db_link = mysql_pconnect ($db_host, $db_user, $db_pass);
$err = mysql_select_db ($db_base, $db_link) or die ("cannot connect to
	$db_base database");

$all_conn_table = mysql_query ("select * from connections order by ind");
$all_locs_table = mysql_query ("select * from locations order by ind");
$all_nets_table = mysql_query ("select * from networks order by ind");
$all_prox_table = mysql_query ("select * from proxies order by ind");

while ($temp_row = mysql_fetch_row ($all_conn_table)) {
	$i = $temp_row[0];
	$all_conn[$i][0] = $i;
	for ($j=1; $j<=3; $j++) $all_conn[$i][$j] = $temp_row[$j];
}
$max_conn = $i;

while ($temp_row = mysql_fetch_row ($all_locs_table)) {
	$i = $temp_row[0];
	$all_locs[$i][0] = $i;
	for ($j=1; $j<=2; $j++) $all_locs[$i][$j] = $temp_row[$j];
}
$max_locs = $i;

while ($temp_row = mysql_fetch_row ($all_nets_table)) {
	$i = $temp_row[0];
	$all_nets[$i][0] = $i;
	for ($j=1; $j<=6; $j++) $all_nets[$i][$j] = $temp_row[$j];
}
$max_nets = $i;

while ($temp_row = mysql_fetch_row ($all_prox_table)) {
	$i = $temp_row[0];
	$all_prox[$i][0] = $i;
	for ($j=1; $j<=3; $j++) $all_prox[$i][$j] = $temp_row[$j];
}
$max_prox = $i;

// main loop for proxy pac files
//for ($my_loc=1; $my_loc<=$max_locs; $my_loc++) {
for ($my_loc=1; $my_loc<=1; $my_loc++) {
	if (!($all_locs[$my_loc][0] > 0)) continue;
	echo "$my_loc\n";
	// get first the list of networks at my own location
	$max_direct_nets = 0;
	for ($i=1; $i<=$max_nets; $i++) {
		if (!($all_nets[$i][0] > 0)) continue;
		if ($all_nets[$i][6] == $my_loc) {
			++$max_direct_nets;
			for ($j=0; $j<=6; $j++) {
				$direct_nets[$max_direct_nets][$j] = $all_nets[$i][$j];
			}
		}
	}
	echo "$max_direct_nets\n";
	// this variable will show how many nets are at my location,
	// so i can use it to diff. these nets from other direct-access nets
	$my_nets = $max_direct_nets;
	// this check is required because our database is screwed up :-D
	if ($my_nets > 0) {
		//do we have a proxy at our location?
		$have_proxy = 0;
		for ($i=1; $i<=$max_prox; $i++) {
			if (!($all_prox[$i][0] > 0)) continue;
			if ($all_prox[$i][1] == $my_loc) $have_proxy++;
		}
		echo "$have_proxy\n";
		$max_neighbor = 0;
		// now get a list of all my neighbors
		// and search for local (non-WAN) connections
		for ($i=1; $i<=$max_conn; $i++) {
			if (!($all_conn[$i][0] > 0)) continue;
			if ($all_conn[$i][1] == $my_loc) {
				$max_neighbor++;
				$my_neighbor[$max_neighbor][1] = $all_conn[$i][2];
				if ($all_conn[$i][3] == "1") {
					$my_neighbor[$max_neighbor][2] = 1;
				} else {
					$my_neighbor[$max_neighbor][2] = 0;
				}
			}
			if ($all_conn[$i][2] == $my_loc) {
				$max_neighbor++;
				$my_neighbor[$max_neighbor][1] = $all_conn[$i][1];
				if ($all_conn[$i][3] == "1") {
					$my_neighbor[$max_neighbor][2] = 1;
				} else {
					$my_neighbor[$max_neighbor][2] = 0;
				}
			}
		}
		// if we don't have a proxy here...
		if ($have_proxy == 0) {
			// yet another sanity check...
			if ($max_neighbor != 0) {
				// get a list with all networks from all neighbors
				// except for "local" (non-WAN) neighbors
				// and append them to direct_nets
				for ($i=1; $i<=$max_neighbor; $i++) {
					if ($my_neighbor[$i][2] == 1) continue;
					for ($j=1; $j<=$max_nets; $j++) {
						if (!($all_nets[$j][0] > 0)) continue;
						if ($all_nets[$j][6] == $my_neighbor[$i][1]) {
							++$max_direct_nets;
							for ($k=0; $k<=6; $k++) {
								$direct_nets[$max_direct_nets][$k] = $all_nets[$j][$k];
							}
						}
					}
				}
			}
		}
		// yet another sanity check...
		if ($max_neighbor != 0) {
			// get a list with all networks from all "local" (non-WAN) neighbors
			// and append them to direct_nets
			for ($i=1; $i<=$max_neighbor; $i++) {
				if ($my_neighbor[$i][2] == 0) continue;
				for ($j=1; $j<=$max_nets; $j++) {
					if (!($all_nets[$j][0] > 0)) continue;
					if ($all_nets[$j][6] == $my_neighbor[$i][1]) {
						++$max_direct_nets;
						for ($k=0; $k<=6; $k++) {
							$direct_nets[$max_direct_nets][$k] = $all_nets[$j][$k];
						}
					}
				}
			}
		}
		echo "$max_direct_nets\n";
		// sort the networks array in ascending order, using bubble-sort algo.
		if ($max_direct_nets > 1) {
			do {
				$changes = 0;
				for ($i=2; $i<=$max_direct_nets; $i++) {
					//figure out if we have to swap them
					$reverse = 0;
					if ($direct_nets[$i][1] < $direct_nets[$i-1][1]) {
						$reverse = 1;
					} elseif ($direct_nets[$i][1] == $direct_nets[$i-1][1]) {
						if ($direct_nets[$i][2] < $direct_nets[$i-1][2]) {
							$reverse = 1;
						} elseif ($direct_nets[$i][2] == $direct_nets[$i-1][2]) {
							if ($direct_nets[$i][3] < $direct_nets[$i-1][3]) {
								$reverse = 1;
							} elseif ($direct_nets[$i][3] == $direct_nets[$i-1][3]) {
								if ($direct_nets[$i][4] < $direct_nets[$i-1][4]) {
									$reverse = 1;
								}
							}
						}
					}
					if ($reverse == 1) {
						++$changes;
						//swap networks
						for ($j=1; $j<=6; $j++) {
							$temp = $direct_nets[$i-1][$j];
							$direct_nets[$i-1][$j] = $direct_nets[$i][$j];
							$direct_nets[$i][$j] = $temp;
						}
					}
				}
			} while ($changes > 0);
		}
		//
		// consolidate the sorted networks under smaller netmasks
		//
//
	for ($i=1; $i<=$max_direct_nets; $i++) {
//
		$netaddr = $direct_nets[$i][1] * (2 ** 24);
//
		$netaddr = $netaddr + $direct_nets[$i][2] * (2 ** 16);
//
		$netaddr = $netaddr + $direct_nets[$i][3] * (2 ** 8);
//
		$netaddr = $netaddr + $direct_nets[$i][4];
//
		// compute the non-dotted broadcast addresses
//
		$bcast = $netaddr + (2 ** (32 - $direct_nets[$i][5])) - 1;
//
		$direct_nets[$i][7] = $netaddr;
//
		$direct_nets[$i][8] = $bcast;
//
	}
		//
		// search for large nets and collapse
		do {
			$changes = 0;
			// let's define some useful cursors:
			// $i is the first net in a collapsed block (floor)
			// $ceil is the last net in a collapsed block (ceiling)
			// $temp_ceil is used to search for new $ceil's
			for ($i=1; $i<$max_direct_nets; $i++) {
				// is $direct_nets[$i] a possible "floor"?
				// compute the number of zeros in the non-dotted netaddress
				// (binary representation, of course)
				$nrzr = 0;
				$netaddr = $direct_nets[$i][7];
				$mask = $direct_nets[$i][5];
				do {
					$modulus = $netaddr % (2 ** $nrzr);
					++$nrzr;
				} while ($modulus == 0);
				--$nrzr;
				// do we have less zeros in the address than in the netmask?
				if ($nrzr <= (32 - $mask)) {
					// yes. then it's not a possible floor. skip.
					continue;
				}
				// now search for $ceil
				$ceil = $i;
				$temp_ceil = $i;
				$not_contig = 0;
				while (($temp_ceil<$max_direct_nets) && ($not_contig == 0)) {
					$not_contig = 0;
					++$temp_ceil;
					// are they contiguous? if not, exit.
					if ($direct_nets[$temp_ceil][7] != ($direct_nets[$temp_ceil - 1][8] + 1)) {
						$not_contig = 1;
						continue;
					}
					$temp_bcast = $direct_nets[$temp_ceil][8];
					// when collapsing nets, the result should be in CIDR format
					$temp_mask = $mask;
					$good_bcast = 0;
					do {
						--$temp_mask;
						$new_bcast = $netaddr + (2 ** (32 - $temp_mask)) - 1;
						if ($new_bcast == $temp_bcast) {
							// looks like they are collapsible
							$ceil = $temp_ceil;
							$new_mask = $temp_mask;
							$good_bcast = 1;
							continue;
						}
					} while ($new_mask > 0);
				}
				if (($ceil == $floor) || ($good_bcast == 0)) {
					// no collapse. sorry
					continue;
				}
				// build the collapsed network:
				// netmask
				$direct_nets[$i][5] = $new_mask;
				// broadcast
				$direct_nets[$i][8] = $direct_nets[$ceil][8];
				// the Universe is collapsing.
				// thanks for being with us. :o)
				$height = $ceil - $i;
				for ($j=$i+1; $j<=$ceil; $j++) {
					for ($k=1; $k<=8; $k++) {
						$direct_nets[$j][$k] = $direct_nets[$j+$height][$k];
					}
				}
				$max_direct_nets = $max_direct_nets - $height;
				++$changes;
			}
		} while ($changes > 0);
		// good. now we're supposed to have all the information required
		//
		// get my location's name
		$my_name = $all_locs[$my_loc][1];
		// which is my default proxy?
		$proxy_ind = $all_locs[$my_loc][2];
		$proxy_host = $all_prox[$proxy_ind][2];
		$proxy_port = $all_prox[$proxy_ind][3];
		$proxy_url = $proxy_host . ":" . $proxy_port;
		// build pacfile name
		$fname = "pac" . $my_loc. ".txt";
		// let's rock! :o)
		$fp = fopen("$fname", "w");
		fputs($fp, "// PAC file for $my_name\n");
		fputs($fp, "\n");
		fputs($fp, "function FindProxyForURL(url, host) {\n");
		fputs($fp, "	addr = dnsResolve(host)\n");
		fputs($fp, "	if (addr) {\n");
		fputs($fp, "		if (	0");
		echo " - writing file";
		for ($i=1; $i<=$max_direct_nets; $i++) {
			if (!($direct_nets[$i][0] > 0)) continue;
			$net = $direct_nets[$i][1];
			for ($j=2; $j<=4; $j++) {
				$net = $net . "." . $direct_nets[$i][$j];
			}
//
		echo "$net\n";
			$mask = $direct_nets[$i][5];
			for ($j=1; $j<=4; $j++) {
				$mask = $mask - 8;
				if ($mask >= 0) {
					$mask_part[$j] = 255;
				} else {
					$mask_part[$j] = 256 - pow(2, (0 - $mask));
					if ($mask_part[$j] < 0) {
						$mask_part[$j] = 0;
					}
				}
			}
			$new_mask = $mask_part[1] . "." . $mask_part[2] . "." . $mask_part[3] . "." .
$mask_part[4];
			fputs($fp, "\n");
			fputs($fp, "			|| isInNet(addr, \"$net\", \"$new_mask\")");
		}
		fputs($fp, "\n");
		fputs($fp, "			|| isInNet(addr, \"127.0.0.1\", \"255.255.255.255\")");
		fputs($fp, ")\n");
		fputs($fp, "			return \"DIRECT\";\n");
		fputs($fp, "		else\n");
		fputs($fp, "			return \"PROXY $proxy_url\";\n");
		fputs($fp, "	} else\n");
		fputs($fp, "		return \"PROXY $proxy_url\";\n");
		fputs($fp, "}\n");
		fclose($fp);
	}
	echo "\n";
}

// main loop for the networks file
$fname = "nets.txt";
$fp = fopen("$fname", "w");
for ($net=1; $net<=$max_nets; $net++) {
	if (!($all_nets[$net][0] > 0)) continue;
	fputs($fp, "{$all_nets[$net][1]}.{$all_nets[$net][2]}.{$all_nets[$net][3]}.{$all_nets[$net][4]}/{$all_nets[$net][5]}	{$all_nets[$net][6]}\n");
}
fclose($fp);
?>

Comment 1 Phil Copeland 2002-05-09 19:00:08 UTC
Current errata
also your script is broken
[root@group root]# php -l test.php 
<br>
<b>Parse error</b>:  parse error in <b>/root/test.php</b> on line <b>176</b><br>
Errors parsing test.php

but it won't coredump

Phil
=--=