From 06cdf297a8802e59ae8947e66022ba6fa240ea0f Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Mon, 26 Nov 2001 21:04:21 +0000 Subject: [PATCH] - Adding a callback mechanism to the unserializer. (patch by Bernd Roemer ) #- An explainatory e-mail will be send to php-dev --- ext/standard/var_unserializer.c | 39 ++++++++++++++++++++++++++++----- main/main.c | 1 + main/php_globals.h | 2 ++ php.ini-dist | 9 ++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index cbc00fbb19912..ef3f2b8d576fa 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -371,6 +371,13 @@ yy19: yych = *++YYCURSOR; zend_class_entry *ce; int incomplete_class = 0; + char *rval_temp; + + zval *user_func; + zval *retval_ptr; + zval **args[1]; + zval *arg_func_name; + INIT_PZVAL(*rval); len2 = len = parse_iv(start + 2); if (len == 0) @@ -385,12 +392,34 @@ yy19: yych = *++YYCURSOR; } } - if (zend_hash_find(EG(class_table), class_name, len2 + 1, (void **) &ce) != SUCCESS) { - incomplete_class = 1; - ce = PHP_IC_ENTRY; - } else + if (zend_hash_find(CG(class_table), class_name, len2 + 1, (void **) &ce) != SUCCESS) { + if (PG(unserialize_callback_func) == NULL) { + incomplete_class = 1; + ce = PHP_IC_ENTRY; + } else { + MAKE_STD_ZVAL(user_func); + ZVAL_STRING(user_func, PG(unserialize_callback_func), 1); + + args[0] = &arg_func_name; + MAKE_STD_ZVAL(arg_func_name); + ZVAL_STRING(arg_func_name, class_name, 1); + + if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { + zend_error(E_WARNING, "'unserialize_callback_func' defined (%s) but not found", user_func->value.str.val); + incomplete_class = 1; + ce = PHP_IC_ENTRY; + } else { + if (zend_hash_find(CG(class_table), class_name, len2 + 1, (void **) &ce) != SUCCESS) { + zend_error(E_WARNING, "'unserialize_callback_func' (%s) hasn't defined the class it was called for", user_func->value.str.val); + incomplete_class = 1; + ce = PHP_IC_ENTRY; + } else + efree(class_name); + } + } + } else efree(class_name); - + *p = YYCURSOR; elements = object_common1(UNSERIALIZE_PASSTHRU, ce); diff --git a/main/main.c b/main/main.c index 20ee57a25dc1a..2ab207f1608ed 100644 --- a/main/main.c +++ b/main/main.c @@ -239,6 +239,7 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("track_errors", "0", PHP_INI_ALL, OnUpdateBool, track_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("y2k_compliance", "0", PHP_INI_ALL, OnUpdateBool, y2k_compliance, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateStringUnempty, unserialize_callback_func, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator.output, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStringUnempty, arg_separator.input, php_core_globals, core_globals) diff --git a/main/php_globals.h b/main/php_globals.h index e1caa6eaf38ca..fdb92900e528e 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -66,6 +66,8 @@ struct _php_core_globals { char *output_handler; + char *unserialize_callback_func; + char *safe_mode_exec_dir; long memory_limit; diff --git a/php.ini-dist b/php.ini-dist index eb78b97005788..0f64ff4f39d43 100644 --- a/php.ini-dist +++ b/php.ini-dist @@ -94,6 +94,15 @@ output_buffering = Off ; Setting an output handler automatically turns on output buffering. output_handler = +; The unserialize callback function will called (with the undefind class' +; name as parameter), if the unserializer finds an undefined class +; which should be instanciated. +; A warning appears if the specified function is not defined, or if the +; function doesn't include/implement the missing class. +; So only set this entry, if you really want to implement such a +; callback-function. +unserialize_callback_func= + ; Transparent output compression using the zlib library ; Valid values for this option are 'off', 'on', or a specific buffer size ; to be used for compression (default is 4KB)