php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57551 can not use rename/override_function more than once
Submitted: 2007-02-27 10:22 UTC Modified: 2015-02-26 07:38 UTC
From: info at neo2enigma dot ir Assigned:
Status: Suspended Package: apd (PECL)
PHP Version: 4.4.4 OS: RedHat AS 4
Private report: No CVE-ID: None
 [2007-02-27 10:22 UTC] info at neo2enigma dot ir
Description:
------------
I'm using apd-0.9.2 on apache 2.2 and php 4.4.4 on Redhat AD 4
I can only use once override/rename_function.
I got this error in apache error_log:

rename_function(mysql_select_db,msssql_select_db) failed: mssql_select_db already exists! in /var/www/html/apd.php on line 4
rename_function(mysql_query,msssql_query) failed: mssql_select_db already exists! in /var/www/html/apd.php on line 7
mysql_query(): supplies resource is not a valid MySQL-Link resource in /var/ww/html/apd.php on line 8

rename_function(mysql_fetch_array,msssql_fetch_array) failed: mssql_select_db already exists! in /var/www/html/apd.php on line 9
mysql_fetch_array(): supplies resource is not a valid MySQL-Link resource in /var/ww/html/apd.php on line 10

and here is the source code:

<?php
override_function('mysql_connect', '$sis_host, $sis_user, $sis_pass', 'return mssql_connect($sis_host, $sis_user, $sis_pass);');
$lnk=mysql_connect('abc.abc.com','test','test') or die("Server Error!!");
rename_function('mysql_select_db', 'mssql_select_db');
$db=mssql_select_db('test',$lnk);
$q="select * from t1";
rename_function('mysql_query','mssql_query');
$result=mysql_query($q,$lnk);
rename_function('mysql_fetch_array', 'mssql_fetch_array');
while ($row = mysql_fetch_array($result))
{
	echo $row['name']."<br>";
}
?> 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-06-16 20:58 UTC] geoff at spacevs dot com
This is because APD uses the function name __overridden__ for overridden function (php_apd.c:607). I am not sure as to why they have done this, but it would be fairly simple to patch it to generate a random name for the function.

On lines 610 and 611, there are two unused defined variable "temp_function_name" and "temp_function_name_length", it seems that these are intended for this exact use, but was never implemented.

Here is a patch for this, however, my experience with C is very limited, and with the zend engine, even less. Someone with more experiance may want to review this patch first:

--- orig.c	2008-06-17 10:27:26.000000000 +1000
+++ php_apd.c	2008-06-17 10:57:01.000000000 +1000
@@ -608,7 +608,7 @@
 PHP_FUNCTION(override_function)
 {
 	char *eval_code,*eval_name, *temp_function_name;
-	int eval_code_length, retval, temp_function_name_length;
+	int eval_code_length, retval, temp_function_name_length, i;
 	zval **z_function_name, **z_function_args, **z_function_code;
 	
 	if (ZEND_NUM_ARGS() != 3 || 
@@ -622,13 +622,22 @@
 	convert_to_string_ex(z_function_args);
 	convert_to_string_ex(z_function_code);
 
-	eval_code_length = sizeof("function " TEMP_OVRD_FUNC_NAME) 
+	temp_function_name_length = sizeof(TEMP_OVRD_FUNC_NAME);
+	temp_function_name = (char *) emalloc(temp_function_name_length + 10);
+	sprintf(temp_function_name, "%s", TEMP_OVRD_FUNC_NAME);
+	for(i = 0; i < 10; i++)
+		temp_function_name[temp_function_name_length+i-1] = 97 + (rand() % 26);
+	temp_function_name_length += 10;
+	temp_function_name[temp_function_name_length-1] = 0;
+
+	eval_code_length = sizeof("function ") + temp_function_name_length 
 		+ Z_STRLEN_PP(z_function_args)
 		+ 2 /* parentheses */
 		+ 2 /* curlies */
 		+ Z_STRLEN_PP(z_function_code);
 	eval_code = (char *) emalloc(eval_code_length);
-	sprintf(eval_code, "function " TEMP_OVRD_FUNC_NAME "(%s){%s}",
+	sprintf(eval_code, "function %s (%s){%s}",
+			temp_function_name,
 			Z_STRVAL_PP(z_function_args), Z_STRVAL_PP(z_function_code));
 	eval_name = zend_make_compiled_string_description("runtime-created override function" TSRMLS_CC);
 	retval = zend_eval_string(eval_code, NULL, eval_name TSRMLS_CC);
@@ -638,12 +647,14 @@
 	if (retval == SUCCESS) {
 		zend_function *func;
 
-		if (zend_hash_find(EG(function_table), TEMP_OVRD_FUNC_NAME,
-						   sizeof(TEMP_OVRD_FUNC_NAME), (void **) &func) == FAILURE) 
+		if (zend_hash_find(EG(function_table), temp_function_name,
+						   temp_function_name_length, (void **) &func) == FAILURE) 
 			{
 				zend_error(E_ERROR, "%s() temporary function name not present in global function_table", get_active_function_name(TSRMLS_C));
+				efree(temp_function_name);
 				RETURN_FALSE;
 			}
+		efree(temp_function_name);
 		function_add_ref(func);
 		zend_hash_del(EG(function_table), Z_STRVAL_PP(z_function_name),
 					  Z_STRLEN_PP(z_function_name) + 1);
@@ -656,6 +667,7 @@
 		RETURN_TRUE;
 	}   
 	else {
+		efree(temp_function_name);
 		RETURN_FALSE;
 	}
 }
 [2015-02-26 07:38 UTC] krakjoe@php.net
-Status: Open +Status: Suspended
 [2015-02-26 07:38 UTC] krakjoe@php.net
APD hasn't had a release in 10 years, this means it's source code is way out of sync with modern PHP.

I'm going to mark this bug as suspended, the report can still be found if a maintainer for APD comes forward.

Sorry about the wait.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 28 11:01:30 2024 UTC