php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch serialize.patch for *General Issues Bug #67452

Patch version 2014-06-17 09:56 UTC

Return to Bug #67452 | Download this patch
Patch Revisions:

Developer: remi@php.net

diff -up ext/standard/basic_functions.h.orig ext/standard/basic_functions.h
--- ext/standard/basic_functions.h.orig	2014-06-17 11:44:32.077914111 +0200
+++ ext/standard/basic_functions.h	2014-06-17 11:45:45.703878782 +0200
@@ -208,6 +208,7 @@ typedef struct _php_basic_globals {
 	struct {
 		void *var_hash;
 		unsigned level;
+		ulong top;
 	} serialize;
 	struct {
 		void *var_hash;
diff -up ext/standard/php_var.h.orig ext/standard/php_var.h
--- ext/standard/php_var.h.orig	2014-06-17 11:42:09.118365411 +0200
+++ ext/standard/php_var.h	2014-06-17 11:43:57.069675513 +0200
@@ -61,6 +61,7 @@ do  { \
 		if (!BG(serialize_lock)) { \
 			BG(serialize).var_hash = (void *)(var_hash_ptr); \
 			BG(serialize).level = 1; \
+			BG(serialize).top = EG(objects_store).top; \
 		} \
 	} else { \
 		(var_hash_ptr) = (php_serialize_data_t)BG(serialize).var_hash; \
diff -up ext/standard/var.c.orig ext/standard/var.c
--- ext/standard/var.c.orig	2014-06-17 11:41:55.866339150 +0200
+++ ext/standard/var.c	2014-06-17 11:55:46.450090627 +0200
@@ -545,17 +545,18 @@ static void php_var_serialize_intern(sma
 
 static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old TSRMLS_DC) /* {{{ */
 {
-	ulong var_no;
+	ulong var_no, h=0, q=0;
 	char id[32], *p;
 	register int len;
 
 	if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
-		p = smart_str_print_long(id + sizeof(id) - 1,
-				(long) zend_objects_get_address(var TSRMLS_CC));
+		h = (ulong)Z_OBJ_HANDLE_P(var);
+		q = (ulong)zend_objects_get_address(var TSRMLS_CC);
+		p = smart_str_print_unsigned(id + sizeof(id) - 1, q);
 		*(--p) = 'O';
 		len = id + sizeof(id) - 1 - p;
 	} else {
-		p = smart_str_print_long(id + sizeof(id) - 1, (long) var);
+		p = smart_str_print_unsigned(id + sizeof(id) - 1, (ulong) var);
 		len = id + sizeof(id) - 1 - p;
 	}
 
@@ -567,17 +568,23 @@ static inline int php_add_var_hash(HashT
 			zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL);
 		}
 #if 0
-		fprintf(stderr, "- had var (%d): %lu\n", Z_TYPE_P(var), **(ulong**)var_old);
+		fprintf(stderr, "- had var (%d): %lu (q=%lx,h=%lu,top=%lu)\n", Z_TYPE_P(var), **(ulong**)var_old, q, h, (ulong)BG(serialize).top);
 #endif
 		return FAILURE;
 	}
 
-	/* +1 because otherwise hash will think we are trying to store NULL pointer */
-	var_no = zend_hash_num_elements(var_hash) + 1;
-	zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
+	/* Ignore temporary object created after the start of serialization
+ 	   Using EG(objects_store).top is not perfect, as EG(objects_store).free_list_head is ignored */
+	if (h < BG(serialize).top) {
+		/* +1 because otherwise hash will think we are trying to store NULL pointer */
+		var_no = zend_hash_num_elements(var_hash) + 1;
+		zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
 #if 0
-	fprintf(stderr, "+ add var (%d): %lu\n", Z_TYPE_P(var), var_no);
+		fprintf(stderr, "+ add var (%d): %lu (q=%lx,h=%lu,top=%lu)\n", Z_TYPE_P(var), var_no, q, h, (ulong)BG(serialize).top);
+	} else {
+		fprintf(stderr, "- ignore var (%d): %lu (q=%lx,h=%lu,top=%lu)\n", Z_TYPE_P(var), **(ulong**)var_old, q, h, (ulong)BG(serialize).top);
 #endif
+	}
 	return SUCCESS;
 }
 /* }}} */
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 01:01:28 2024 UTC