com php-src: Clean up __sleep() related code: e xt/standard/var.c

[email protected] (Nikita Popov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    ddc0dbf1a3a91756dd0e3a631788a65ce2d1dd25
Author:    Nikita Popov <[email protected]>         Sun, 12 Mar 2017 21:32:47 +0100
Parents:   d2285e1613f239043d439a6b439ee510452f5e07
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=ddc0dbf1a3a91756dd0e3a631788a65ce2d1dd25

Log:
Clean up __sleep() related code

Changed paths:
  M  ext/standard/var.c
diff_ddc0dbf1a3a91756dd0e3a631788a65ce2d1dd25.txt (text/plain, 9 KB)
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 5b6bc66..1e1e94a 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -671,21 +671,44 @@ static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc
 }
 /* }}} */
 
-static HashTable *php_var_serialize_collect_names(HashTable *src, uint32_t count, zend_bool incomplete) /* {{{ */ {
+static int php_var_serialize_call_sleep(zval *retval, zval *struc) /* {{{ */
+{
+	zval fname;
+	int res;
+
+	ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1);
+	BG(serialize_lock)++;
+	res = call_user_function_ex(CG(function_table), struc, &fname, retval, 0, 0, 1, NULL);
+	BG(serialize_lock)--;
+	zval_dtor(&fname);
+
+	if (res == FAILURE || Z_ISUNDEF_P(retval)) {
+		zval_ptr_dtor(retval);
+		return FAILURE;
+	}
+
+	if (!HASH_OF(retval)) {
+		zval_ptr_dtor(retval);
+		php_error_docref(NULL, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+
+static void php_var_serialize_collect_names(HashTable *ht, HashTable *src) /* {{{ */
+{
 	zval *val;
-	HashTable *ht;
-	zend_string *key, *name;
+	zend_string *name;
 
-	ALLOC_HASHTABLE(ht);
-	zend_hash_init(ht, count, NULL, NULL, 0);
-	ZEND_HASH_FOREACH_STR_KEY_VAL(src, key, val) {
-		if (incomplete && strcmp(ZSTR_VAL(key), MAGIC_MEMBER) == 0) {
-			continue;
-		}
+	zend_hash_init(ht, zend_hash_num_elements(src), NULL, NULL, 0);
+	ZEND_HASH_FOREACH_VAL(src, val) {
 		if (Z_TYPE_P(val) != IS_STRING) {
 			php_error_docref(NULL, E_NOTICE,
 					"__sleep should return an array only containing the names of instance-variables to serialize.");
 		}
+
 		name = zval_get_string(val);
 		if (zend_hash_exists(ht, name)) {
 			php_error_docref(NULL, E_NOTICE,
@@ -696,114 +719,81 @@ static HashTable *php_var_serialize_collect_names(HashTable *src, uint32_t count
 		zend_hash_add_empty_element(ht, name);
 		zend_string_release(name);
 	} ZEND_HASH_FOREACH_END();
-
-	return ht;
 }
 /* }}} */
 
 static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, php_serialize_data_t var_hash) /* {{{ */
 {
-	uint32_t count;
-	zend_bool incomplete_class;
-	HashTable *ht;
-
-	incomplete_class = php_var_serialize_class_name(buf, struc);
-	/* count after serializing name, since php_var_serialize_class_name
-	 * changes the count if the variable is incomplete class */
-	if (Z_TYPE_P(retval_ptr) == IS_ARRAY) {
-		ht = Z_ARRVAL_P(retval_ptr);
-		count = zend_array_count(ht);
-	} else if (Z_TYPE_P(retval_ptr) == IS_OBJECT) {
-		ht = Z_OBJPROP_P(retval_ptr);
-		count = zend_array_count(ht);
-		if (incomplete_class) {
-			--count;
-		}
-	} else {
-		count = 0;
-		ht = NULL;
-	}
-
-	if (count > 0) {
-		zval *d;
-		zval nval, *nvalp;
-		zend_string *name;
-		HashTable *names, *propers;
-
-		names = php_var_serialize_collect_names(ht, count, incomplete_class);
-
-		smart_str_append_unsigned(buf, zend_hash_num_elements(names));
-		smart_str_appendl(buf, ":{", 2);
-
-		ZVAL_NULL(&nval);
-		nvalp = &nval;
-		propers = Z_OBJPROP_P(struc);
-
-		ZEND_HASH_FOREACH_STR_KEY(names, name) {
-			if ((d = zend_hash_find(propers, name)) != NULL) {
-				if (Z_TYPE_P(d) == IS_INDIRECT) {
-					d = Z_INDIRECT_P(d);
-					if (Z_TYPE_P(d) == IS_UNDEF) {
+	zend_class_entry *ce = Z_OBJCE_P(struc);
+	HashTable names, *propers;
+	zval nval;
+	zend_string *name;
+
+	php_var_serialize_class_name(buf, struc);
+	php_var_serialize_collect_names(&names, HASH_OF(retval_ptr));
+
+	smart_str_append_unsigned(buf, zend_hash_num_elements(&names));
+	smart_str_appendl(buf, ":{", 2);
+
+	ZVAL_NULL(&nval);
+	propers = Z_OBJPROP_P(struc);
+
+	ZEND_HASH_FOREACH_STR_KEY(&names, name) {
+		zval *val = zend_hash_find(propers, name);
+		if (val != NULL) {
+			if (Z_TYPE_P(val) == IS_INDIRECT) {
+				val = Z_INDIRECT_P(val);
+				if (Z_TYPE_P(val) == IS_UNDEF) {
+					continue;
+				}
+			}
+			php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
+			php_var_serialize_intern(buf, val, var_hash);
+		} else {
+			zend_string *prot_name, *priv_name;
+
+			priv_name = zend_mangle_property_name(
+					ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
+			val = zend_hash_find(propers, priv_name);
+			if (val != NULL) {
+				if (Z_TYPE_P(val) == IS_INDIRECT) {
+					val = Z_INDIRECT_P(val);
+					if (Z_ISUNDEF_P(val)) {
 						continue;
 					}
 				}
-				php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
-				php_var_serialize_intern(buf, d, var_hash);
-			} else {
-				zend_class_entry *ce = Z_OBJ_P(struc)->ce;
-				if (ce) {
-					zend_string *prot_name, *priv_name;
-
-					do {
-						priv_name = zend_mangle_property_name(
-								ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
-						if ((d = zend_hash_find(propers, priv_name)) != NULL) {
-							if (Z_TYPE_P(d) == IS_INDIRECT) {
-								d = Z_INDIRECT_P(d);
-								if (Z_ISUNDEF_P(d)) {
-									break;
-								}
-							}
-							php_var_serialize_string(buf, ZSTR_VAL(priv_name), ZSTR_LEN(priv_name));
-							zend_string_free(priv_name);
-							php_var_serialize_intern(buf, d, var_hash);
-							break;
-						}
-						zend_string_free(priv_name);
-						prot_name = zend_mangle_property_name(
-								"*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
-						if ((d = zend_hash_find(propers, prot_name)) != NULL) {
-							if (Z_TYPE_P(d) == IS_INDIRECT) {
-								d = Z_INDIRECT_P(d);
-								if (Z_TYPE_P(d) == IS_UNDEF) {
-									zend_string_free(prot_name);
-									break;
-								}
-							}
-							php_var_serialize_string(buf, ZSTR_VAL(prot_name), ZSTR_LEN(prot_name));
-							zend_string_free(prot_name);
-							php_var_serialize_intern(buf, d, var_hash);
-							break;
-						}
+				php_var_serialize_string(buf, ZSTR_VAL(priv_name), ZSTR_LEN(priv_name));
+				zend_string_free(priv_name);
+				php_var_serialize_intern(buf, val, var_hash);
+				continue;
+			}
+			zend_string_free(priv_name);
+			prot_name = zend_mangle_property_name(
+					"*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
+			val = zend_hash_find(propers, prot_name);
+			if (val != NULL) {
+				if (Z_TYPE_P(val) == IS_INDIRECT) {
+					val = Z_INDIRECT_P(val);
+					if (Z_TYPE_P(val) == IS_UNDEF) {
 						zend_string_free(prot_name);
-						php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
-						php_var_serialize_intern(buf, nvalp, var_hash);
-						php_error_docref(NULL, E_NOTICE,
-								"\"%s\" returned as member variable from __sleep() but does not exist", ZSTR_VAL(name));
-					} while (0);
-				} else {
-					php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
-					php_var_serialize_intern(buf, nvalp, var_hash);
+						continue;
+					}
 				}
+				php_var_serialize_string(buf, ZSTR_VAL(prot_name), ZSTR_LEN(prot_name));
+				zend_string_free(prot_name);
+				php_var_serialize_intern(buf, val, var_hash);
+				continue;
 			}
-		} ZEND_HASH_FOREACH_END();
-		smart_str_appendc(buf, '}');
+			zend_string_free(prot_name);
+			php_var_serialize_string(buf, ZSTR_VAL(name), ZSTR_LEN(name));
+			php_var_serialize_intern(buf, &nval, var_hash);
+			php_error_docref(NULL, E_NOTICE,
+					"\"%s\" returned as member variable from __sleep() but does not exist", ZSTR_VAL(name));
+		}
+	} ZEND_HASH_FOREACH_END();
+	smart_str_appendc(buf, '}');
 
-		zend_hash_destroy(names);
-		FREE_HASHTABLE(names);
-	} else {
-		smart_str_appendl(buf, "0:{}", 4);
-	}
+	zend_hash_destroy(&names);
 }
 /* }}} */
 
@@ -890,39 +880,23 @@ again:
 				}
 
 				if (ce != PHP_IC_ENTRY && zend_hash_str_exists(&ce->function_table, "__sleep", sizeof("__sleep")-1)) {
-					zval fname, tmp, retval;
-					int res;
-
+					zval retval, tmp;
 					ZVAL_COPY(&tmp, struc);
-					ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1);
-					BG(serialize_lock)++;
-					res = call_user_function_ex(CG(function_table), &tmp, &fname, &retval, 0, 0, 1, NULL);
-					BG(serialize_lock)--;
-					zval_dtor(&fname);
-
-					if (EG(exception)) {
-						zval_ptr_dtor(&retval);
-						zval_ptr_dtor(&tmp);
-						return;
-					}
 
-					if (res == SUCCESS) {
-						if (Z_TYPE(retval) != IS_UNDEF) {
-							if (HASH_OF(&retval)) {
-								php_var_serialize_class(buf, &tmp, &retval, var_hash);
-							} else {
-								php_error_docref(NULL, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
-								/* we should still add element even if it's not OK,
-								 * since we already wrote the length of the array before */
-								smart_str_appendl(buf,"N;", 2);
-							}
+					if (php_var_serialize_call_sleep(&retval, &tmp) == FAILURE) {
+						if (!EG(exception)) {
+							/* we should still add element even if it's not OK,
+							 * since we already wrote the length of the array before */
+							smart_str_appendl(buf, "N;", 2);
 						}
-						zval_ptr_dtor(&retval);
 						zval_ptr_dtor(&tmp);
 						return;
 					}
+
+					php_var_serialize_class(buf, &tmp, &retval, var_hash);
 					zval_ptr_dtor(&retval);
 					zval_ptr_dtor(&tmp);
+					return;
 				}
 
 				/* fall-through */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.