--- embedaddon/php/ext/standard/var_unserializer.re 2012/02/21 23:48:02 1.1 +++ embedaddon/php/ext/standard/var_unserializer.re 2013/07/22 01:32:05 1.1.1.3 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.re,v 1.1 2012/02/21 23:48:02 misho Exp $ */ +/* $Id: var_unserializer.re,v 1.1.1.3 2013/07/22 01:32:05 misho Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -33,22 +33,23 @@ typedef struct { static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last; +#if 0 + fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first) - var_hashx->first = var_hash; - else - prev->next = var_hash; + if (!(*var_hashx)->first) { + (*var_hashx)->first = var_hash; + } else { + ((var_entries *) (*var_hashx)->last)->next = var_hash; + } + + (*var_hashx)->last = var_hash; } var_hash->data[var_hash->used_slots++] = *rval; @@ -56,22 +57,23 @@ static inline void var_push(php_unserialize_data_t *va PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first_dtor, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last_dtor; +#if 0 + fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first_dtor) - var_hashx->first_dtor = var_hash; - else - prev->next = var_hash; + if (!(*var_hashx)->first_dtor) { + (*var_hashx)->first_dtor = var_hash; + } else { + ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; + } + + (*var_hashx)->last_dtor = var_hash; } Z_ADDREF_PP(rval); @@ -81,7 +83,10 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval)); +#endif while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) { @@ -96,8 +101,11 @@ PHPAPI void var_replace(php_unserialize_data_t *var_ha static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store) { - var_entries *var_hash = var_hashx->first; - + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id); +#endif + while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = var_hash->next; id -= VAR_ENTRIES_MAX; @@ -116,7 +124,10 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_ha { void *next; long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); +#endif while (var_hash) { next = var_hash->next; @@ -124,7 +135,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_ha var_hash = next; } - var_hash = var_hashx->first_dtor; + var_hash = (*var_hashx)->first_dtor; while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) { @@ -368,6 +379,9 @@ static inline long object_common1(UNSERIALIZE_PARAMETE return elements; } +#ifdef PHP_WIN32 +# pragma optimize("", off) +#endif static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) { zval *retval_ptr = NULL; @@ -381,23 +395,38 @@ static inline int object_common2(UNSERIALIZE_PARAMETER zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0); + BG(serialize_lock)++; call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; } - if (retval_ptr) + if (retval_ptr) { zval_ptr_dtor(&retval_ptr); + } + if (EG(exception)) { + return 0; + } + return finish_nested_data(UNSERIALIZE_PASSTHRU); } +#ifdef PHP_WIN32 +# pragma optimize("", on) +#endif PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval **rval_ref; - limit = cursor = *p; + limit = max; + cursor = *p; + if (YYCURSOR >= YYLIMIT) { + return 0; + } + if (var_hash && cursor[0] != 'R') { var_push(var_hash, rval); } @@ -654,10 +683,22 @@ object ":" uiv ":" ["] { do { /* Try to find class directly */ + BG(serialize_lock) = 1; if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { + BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + return 0; + } ce = *pce; break; } + BG(serialize_lock) = 0; + + if (EG(exception)) { + efree(class_name); + return 0; + } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { @@ -672,7 +713,15 @@ object ":" uiv ":" ["] { args[0] = &arg_func_name; MAKE_STD_ZVAL(arg_func_name); ZVAL_STRING(arg_func_name, class_name, 1); + BG(serialize_lock) = 1; if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { + BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; @@ -680,8 +729,15 @@ object ":" uiv ":" ["] { zval_ptr_dtor(&arg_func_name); break; } + BG(serialize_lock) = 0; if (retval_ptr) { zval_ptr_dtor(&retval_ptr); + } + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; } /* The callback function may have defined the class */