php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #50816
Patch bug50816.patch revision 2011-07-30 16:06 UTC by laruence@php.net
revision 2011-07-30 15:24 UTC by laruence@php.net
Patch 50816-2.diff revision 2011-07-29 14:30 UTC by pierrick@php.net
revision 2011-07-29 04:14 UTC by pierrick@php.net
Patch 50816.diff revision 2011-07-29 00:54 UTC by pierrick@php.net

Patch 50816-2.diff for Scripting Engine problem Bug #50816

Patch version 2011-07-29 14:30 UTC

Return to Bug #50816 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions: 2011-07-29 14:30 UTC | 2011-07-29 04:14 UTC

Developer: pierrick@php.net


 Index: Zend/tests/bug50816.phpt
 ===================================================================
 --- Zend/tests/bug50816.phpt	(revision 0)
 +++ Zend/tests/bug50816.phpt	(revision 0)
 @@ -0,0 +1,35 @@
 +--TEST--
 +Bug #50816 (Using class constants in array definition fails).
 +--FILE--
 +<?php
 +
 +class Foo {
 +   const STR_ONE = 'bar';
 +   const STR_TWO = 'bar';
 +   const INT_ONE = 1;
 +   const INT_TWO = 1;
 +   const DBL_ONE = 2.2;
 +   const DBL_TWO = 2.2;
 +   const NULL_ONE = NULL;
 +   const NULL_TWO = NULL;
 +
 +   public static $mapWithConst = array(
 +           self::STR_ONE => 'one', self::STR_TWO => 'two',
 +           self::INT_ONE => 'one', self::INT_TWO => 'two',
 +           self::DBL_ONE => 'one', self::DBL_TWO => 'two',
 +           self::NULL_ONE => 'one', self::NULL_TWO => 'two');
 +
 +}
 +var_dump(Foo::$mapWithConst);
 +?>
 +--EXPECT--
 +array(4) {
 +  ["bar"]=>
 +  string(3) "two"
 +  [1]=>
 +  string(3) "two"
 +  [2]=>
 +  string(3) "two"
 +  [""]=>
 +  string(3) "two"
 +}
  Index: Zend/tests/bug45742.phpt
  ===================================================================
  --- Zend/tests/bug45742.phpt	(revision 313904)
  +++ Zend/tests/bug45742.phpt	(working copy)


  Index: Zend/zend_hash.c
  ===================================================================
  --- Zend/zend_hash.c	(revision 313904)
  +++ Zend/zend_hash.c	(working copy)
 @@ -1206,6 +1206,63 @@
  	}
  }
 @@ -1229,34 +1229,37 @@
   
 +ZEND_API int zend_hash_del_key_if_before(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, HashPosition *pos)
 +{
 +	Bucket *p;
 +	
 +	p = pos ? (*pos) : ht->pInternalPointer;
 +
 +	IS_CONSISTENT(ht);
 +	CHECK_INIT(ht);
 +
 +	if (p) {
 +		if (key_type == HASH_KEY_IS_LONG) {
 +			
 +			Bucket *q = ht->arBuckets[num_index & ht->nTableMask];
 +
 +    		while (q != NULL) {
 +				if ((q->h == num_index) && (q->nKeyLength == 0)) {
 +					p = p->pListLast;
 +					while(p) {
 +						if (p == q) {
 +							zend_hash_index_del(ht, p->h);
 +							return SUCCESS;
 +						}
 +						p = p->pListLast;
 +					}
 +					return SUCCESS;
 +				}
 +				q = q->pNext;
 +			}
 +
 +		} else if (key_type == HASH_KEY_IS_STRING) {
 +			ulong h = zend_inline_hash_func(str_index, str_length);
 +			Bucket *q = ht->arBuckets[h & ht->nTableMask];
 +
 +			while (q != NULL) {
 +				if (q->arKey == p->arKey ||
 +						((q->h == h) && (q->nKeyLength == str_length) && !memcmp(q->arKey, str_index, str_length))) {
 +
 +					p = p->pListLast;
 +					while(p) {
 +						if (p == q)
 +						{
 +							zend_hash_del(ht, p->arKey, p->nKeyLength);
 +							return SUCCESS;
 +						}
 +						p = p->pListLast;
 +					}
 +					return SUCCESS;
 +				}
 +				q = q->pNext;
 +			}
 +
 +		}
 +	}
 +
 +	return SUCCESS;
 +}
 +
  /* This function changes key of currevt element without changing elements'
   * order. If element with target key already exists, it will be deleted first.
   */
 Index: Zend/zend_hash.h
 ===================================================================
 --- Zend/zend_hash.h	(revision 313904)
 +++ Zend/zend_hash.h	(working copy)
 @@ -156,7 +156,9 @@
  		zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
  #define zend_hash_index_del(ht, h) \
  		zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
 +ZEND_API int zend_hash_del_key_if_before(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, HashPosition *pos);
  			if (mode != HASH_UPDATE_KEY_ANYWAY) {
  				Bucket *q = ht->arBuckets[num_index & ht->nTableMask];
 -				int found = 0;
   
 +
  ZEND_API ulong zend_get_hash_value(const char *arKey, uint nKeyLength);
  
  /* Data retreival */
 @@ -183,6 +185,7 @@
  ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
  ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
  
 +
  typedef struct _HashPointer {
  	HashPosition pos;
  	ulong h;
 Index: Zend/zend_execute_API.c
 ===================================================================
 --- Zend/zend_execute_API.c	(revision 313904)
 +++ Zend/zend_execute_API.c	(working copy)
 @@ -658,16 +658,20 @@
  				while (q != NULL) {
 -					if (q == p) {
 -						found = 1;
 -					} else if (!q->nKeyLength && q->h == num_index) {
 -						if (found) {
 -							if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
 -								break;
 -							} else {
 -								if (p->nKeyLength) {
 -									zend_hash_del(ht, p->arKey, p->nKeyLength);
 -								} else {
 -									zend_hash_index_del(ht, p->h);
 +					if ((q->h == num_index) && (q->nKeyLength == 0)) {
 +						if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
 +							Bucket *r = p->pListNext;
 +							while(r) {
 +								if (r == q) {
 +									if (p->nKeyLength) {
 +										zend_hash_del(ht, p->arKey, p->nKeyLength);
 +									} else {
 +										zend_hash_index_del(ht, p->h);
 +									}
 +									return FAILURE;
  								}
 -								return FAILURE;
 +								r = r->pListNext;
  							}
 +							break;
  						} else {
 -							if (mode & HASH_UPDATE_KEY_IF_AFTER) {
 -								break;
 -							} else {
 -								if (p->nKeyLength) {
 -									zend_hash_del(ht, p->arKey, p->nKeyLength);
 -								} else {
 -									zend_hash_index_del(ht, p->h);
 +							Bucket *r = p->pListLast;
 +							while(r) {
 +								if (r == q) {
 +									if (p->nKeyLength) {
 +										zend_hash_del(ht, p->arKey, p->nKeyLength);
 +									} else {
 +										zend_hash_index_del(ht, p->h);
 +									}
 +									return FAILURE;
  								}
 -								return FAILURE;
 +								r = r->pListLast;
  							}
 +							break;
  						}
  					}
  					q = q->pNext;
 @@ -1273,35 +1276,38 @@
  			if (mode != HASH_UPDATE_KEY_ANYWAY) {
  				ulong h = zend_inline_hash_func(str_index, str_length);
  				Bucket *q = ht->arBuckets[h & ht->nTableMask];
 -				int found = 0;
   
  			switch (Z_TYPE(const_value)) {
  				case IS_STRING:
 +					zend_hash_del_key_if_before(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, 0, NULL);
  					ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
  					break;
  				case IS_BOOL:
  				case IS_LONG:
 +					zend_hash_del_key_if_before(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), NULL);
  					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
  					break;
  				case IS_DOUBLE:
 +					zend_hash_del_key_if_before(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), NULL);
  					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
  					break;
  				case IS_NULL:
 +					zend_hash_del_key_if_before(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, NULL);
  					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
  					break;
  				default:
  				while (q != NULL) {
 -					if (q == p) {
 -						found = 1;
 -					} else if (q->h == h && q->nKeyLength == str_length && 
 -					           memcmp(q->arKey, str_index, str_length) == 0) {
 -					    if (found) {
 -							if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
 -								break;
 -							} else {
 -								if (p->nKeyLength) {
 -									zend_hash_del(ht, p->arKey, p->nKeyLength);
 -								} else {
 -									zend_hash_index_del(ht, p->h);
 +					if (q->h == h && q->nKeyLength == str_length &&
 +							memcmp(q->arKey, str_index, str_length) == 0) {
 +						if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
 +							Bucket *r = p->pListNext;
 +							while(r) {
 +								if (r == q) {
 +									if (p->nKeyLength) {
 +										zend_hash_del(ht, p->arKey, p->nKeyLength);
 +									} else {
 +										zend_hash_index_del(ht, p->h);
 +									}
 +									return FAILURE;
  								}
 -								return FAILURE;
 +								r = r->pListNext;
  							}
 +							break;
  						} else {
 -							if (mode & HASH_UPDATE_KEY_IF_AFTER) {
 -								break;
 -							} else {
 -								if (p->nKeyLength) {
 -									zend_hash_del(ht, p->arKey, p->nKeyLength);
 -								} else {
 -									zend_hash_index_del(ht, p->h);
 +							Bucket *r = p->pListLast;
 +							while(r) {
 +								if (r == q) {
 +									if (p->nKeyLength) {
 +										zend_hash_del(ht, p->arKey, p->nKeyLength);
 +									} else {
 +										zend_hash_index_del(ht, p->h);
 +									}
 +									return FAILURE;
  								}
 -								return FAILURE;
 +								r = r->pListLast;
  							}
 +							break;
  						}
  					}
  					q = q->pNext;
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 15:02:26 2014 UTC