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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
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

Add a Patch

Pull Requests

Add a Pull Request

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-2018 The PHP Group
All rights reserved.
Last updated: Sat Nov 17 03:01:25 2018 UTC