php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58548 Optimzier doesn't fixes jump code properly for ZEND_JMPZNZ
Submitted: 2009-02-10 21:30 UTC Modified: 2017-10-24 23:37 UTC
From: basant dot kukreja at gmail dot com Assigned:
Status: Suspended Package: optimizer (PECL)
PHP Version: HEAD CVS-2009-02-10 (dev) OS: Solaris 10
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: basant dot kukreja at gmail dot com
New email:
PHP Version: OS:

 

 [2009-02-10 21:30 UTC] basant dot kukreja at gmail dot com
Description:
------------
Php crashes for a simple script like the below (in Reproduce code).

On debugging, I figured out that ZEND_JMPZNZ is not handled correctly.


Reproduce code:
---------------
<?php

$besim_hosts = array('abcd');

print "count of hosts = " . count($besim_hosts);

for ($i = 0; $i < count($besim_hosts); $i++)
{
    print "host = " . $besim_hosts[$i];
}
?>

Expected result:
----------------
php should run fine.

Actual result:
--------------
Crashes

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-10 21:39 UTC] basant dot kukreja at gmail dot com
There are 3 issues which I found
* First ZEND_JMPZNZ jmp address is not fixed properly.

If you look at the snip of the opcodes
         39  JMPZNZ                                       53           OP1[  IS_TMP_VAR ~1 ] OP2[ , ->48 ]
         40* POST_INC                                          RES[  IS_TMP_VAR ~1 ]       OP1[  IS_CV !7 ]
         41* FREE                                                      OP1[  IS_TMP_VAR ~1 ]
         42* JMP                                                       OP1[ ->36 ]
   24    43* FETCH_CONSTANT                                    RES[  IS_TMP_VAR ~1 ]       OP1[  IS_UNUSED  ] OP2[  IS_CONST (24567152) 'i' ]
...
   27    48  RETURN                                                    OP1[  IS_CONST (0) 1 ]
         49* ZEND_HANDLE_EXCEPTION                                    

JMPZNZ will jump to 53 which doesn't exist and php crashes arbitrarily. My
suggested fix, fixes the extended_value.

Php jumps to undefined location by ZEND_JMPZNZ_SPEC_TMP_HANDLER.

zend_vm_execute.h
static int ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
...
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
...
}

Issue 2 :
* optimization_level should be defined as zend_ulong otherwise php crashes
  during initialization for 64 bit.

Issue 3 :
* Simple compilation issue.

Here is the suggested patch :
--- ../../../../unchanged/pecl/optimizer/./optimize.c	2009-01-13 12:22:42.000000000 -0800
+++ ./optimize.c	2009-02-10 18:03:40.002346000 -0800
@@ -3775,6 +3775,9 @@
 				if (p->start[p->len - 1].opcode == ZEND_CATCH) {
 					p->start[p->len - 1].extended_value = p->jmp_ext->start - start;
 				}
+				else if (p->start[p->len - 1].opcode == ZEND_JMPZNZ) {
+					p->start[p->len - 1].extended_value = p->jmp_ext->start - start;
+				}
 			}
 		}
 		p = p->next;
--- ../../../../unchanged/pecl/optimizer/./php_optimizer.c	2008-12-20 00:18:29.000000000 -0800
+++ ./php_optimizer.c	2009-02-10 18:05:07.367382000 -0800
@@ -79,6 +79,7 @@
 static zend_bool optimizer_ini_bool_decode(zend_uint value_length, char* value)
 {
 	if ((value_length == 2 && strcasecmp("on", value) == 0) || 
+		(value_length == 1 && strcasecmp("1", value) == 0) || 
 		(value_length == 3 && strcasecmp("yes", value) == 0) || 
 		(value_length == 4 && strcasecmp("true", value) == 0)) {
 		return 1;
@@ -190,7 +191,7 @@
 				zend_ini_entry* apc_enabled = NULL;
 
 				if (zend_hash_find(EG(ini_directives), "apc.enabled", sizeof("apc.enabled"), (void**)&apc_enabled) == SUCCESS) {
-					if (optimizer_ini_bool_decode(apc_enabled.value_length, apc_enabled.value)) {
+					if (optimizer_ini_bool_decode(apc_enabled->value_length, apc_enabled->value)) {
 						compile_f_reg = OPTIMIZER_COMPILE_APC_REG;
 					}
 				} else {
--- ../../../../unchanged/pecl/optimizer/./php_optimizer.h	2008-12-20 00:10:46.000000000 -0800
+++ ./php_optimizer.h	2009-02-10 17:03:48.700971000 -0800
@@ -107,7 +107,7 @@
 	char* optimize_out_funcs;
 	zend_uint optimize_out_funcs_l;
   
-	zend_uint optimization_level; /* An arbitrary level that specifies what will happen in the optimizer */
+	zend_ulong optimization_level; /* An arbitrary level that specifies what will happen in the optimizer */
 	zend_uint peephole_passes;    /* The number of passes to be done by the peephole optimizer */
 	zend_bool optimize_for_speed; /* true if the optimizer should favor execution time speed over memory conservation */
 	                              /* We will try to optimize for both as much as possible but when a decission for one over the other needs to be made this will help decide it */
 [2017-10-24 23:37 UTC] kalle@php.net
-Status: Open +Status: Suspended
 [2017-10-24 23:37 UTC] kalle@php.net
The optimizer pecl extension had not had a release since 2008 and its safe to say that development has ceased in favor of alternatives such as opcache included with PHP as of PHP5.5+, I'm gonna suspend this in case the package does pick back up development, and in that case it should be re-opened
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC