diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/mbstring/tests/zend_multibyte-10.phpt | 2 | ||||
-rw-r--r-- | ext/mbstring/tests/zend_multibyte-11.phpt | 2 | ||||
-rw-r--r-- | ext/mbstring/tests/zend_multibyte-12.phpt | 2 | ||||
-rw-r--r-- | ext/session/php_session.h | 2 | ||||
-rw-r--r-- | ext/session/session.c | 44 | ||||
-rw-r--r-- | ext/session/tests/031.phpt | 1 | ||||
-rw-r--r-- | ext/spl/spl_observer.c | 14 | ||||
-rw-r--r-- | ext/standard/php_var.h | 2 | ||||
-rw-r--r-- | ext/standard/var.c | 15 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 148 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 86 | ||||
-rw-r--r-- | ext/tokenizer/tokenizer.c | 44 |
12 files changed, 223 insertions, 139 deletions
diff --git a/ext/mbstring/tests/zend_multibyte-10.phpt b/ext/mbstring/tests/zend_multibyte-10.phpt index a5ba74d50d..566c506077 100644 --- a/ext/mbstring/tests/zend_multibyte-10.phpt +++ b/ext/mbstring/tests/zend_multibyte-10.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (10) --SKIPIF-- +--INI-- +zend.multibyte=On --FILE-- <?php declare(encoding="ISO-8859-15"); diff --git a/ext/mbstring/tests/zend_multibyte-11.phpt b/ext/mbstring/tests/zend_multibyte-11.phpt index 0b59e75fb5..8a93ab50cf 100644 --- a/ext/mbstring/tests/zend_multibyte-11.phpt +++ b/ext/mbstring/tests/zend_multibyte-11.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (11) --SKIPIF-- +--INI-- +zend.multibyte=On --FILE-- <?php declare(encoding="ISO-8859-15") { diff --git a/ext/mbstring/tests/zend_multibyte-12.phpt b/ext/mbstring/tests/zend_multibyte-12.phpt index d7207e49d7..cefa314e91 100644 --- a/ext/mbstring/tests/zend_multibyte-12.phpt +++ b/ext/mbstring/tests/zend_multibyte-12.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (12) --SKIPIF-- +--INI-- +zend.multibyte=On --FILE-- <?php declare(encoding="ISO-8859-15"); diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 608d6bfdc2..2bf0d858f7 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -221,7 +221,7 @@ typedef struct ps_serializer_struct { PHPAPI void session_adapt_url(const char *, size_t, char **, size_t * TSRMLS_DC); PHPAPI void php_add_session_var(zend_string *name TSRMLS_DC); -PHPAPI void php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC); +PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC); PHPAPI zval *php_get_session_var(zend_string *name TSRMLS_DC); PHPAPI int php_session_register_module(ps_module *); diff --git a/ext/session/session.c b/ext/session/session.c index acb17cebec..946708a5ca 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -159,11 +159,12 @@ PHPAPI void php_add_session_var(zend_string *name TSRMLS_DC) /* {{{ */ } /* }}} */ -PHPAPI void php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC) /* {{{ */ +PHPAPI zval* php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC) /* {{{ */ { IF_SESSION_VARS() { - zend_set_hash_symbol(state_val, name->val, name->len, Z_ISREF_P(state_val), 1, Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars)))); + return zend_hash_update(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name, state_val); } + return NULL; } /* }}} */ @@ -924,11 +925,13 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */ } if (has_value) { - ZVAL_NULL(¤t); + ZVAL_UNDEF(¤t); if (php_var_unserialize(¤t, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { - php_set_session_var(name, ¤t, &var_hash TSRMLS_CC); + zval *zv = php_set_session_var(name, ¤t, &var_hash TSRMLS_CC); + var_replace(&var_hash, ¤t, zv); + } else { + zval_ptr_dtor(¤t); } - zval_ptr_dtor(¤t); } PS_ADD_VARL(name); STR_RELEASE(name); @@ -978,7 +981,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */ { const char *p, *q; const char *endptr = val + vallen; - zval stack, *current = NULL; + zval current; int has_value; int namelen; zend_string *name; @@ -988,7 +991,6 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */ p = val; - array_init(&stack); while (p < endptr) { zval *tmp; q = p; @@ -1013,12 +1015,12 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */ } if (has_value) { - zval dummy; - ZVAL_NULL(&dummy); - //??? hash table resize? - current = zend_hash_next_index_insert(Z_ARRVAL(stack), &dummy); - if (php_var_unserialize(current, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { - php_set_session_var(name, current, &var_hash TSRMLS_CC); + ZVAL_UNDEF(¤t); + if (php_var_unserialize(¤t, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { + zval *zv = php_set_session_var(name, ¤t, &var_hash TSRMLS_CC); + var_replace(&var_hash, ¤t, zv); + } else { + zval_ptr_dtor(¤t); } } PS_ADD_VARL(name); @@ -1030,7 +1032,6 @@ skip: break_outer_loop: PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - zval_ptr_dtor(&stack); return SUCCESS; } @@ -1909,15 +1910,22 @@ static PHP_FUNCTION(session_save_path) Return the current session id. If newid is given, the session id is replaced with newid */ static PHP_FUNCTION(session_id) { - char *name = NULL; + zend_string *name = NULL; int name_len, argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "|s", &name, &name_len) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "|S", &name) == FAILURE) { return; } if (PS(id)) { - RETVAL_STR(STR_COPY(PS(id))); + //??? keep compatibility for "\0" characters + //??? see: ext/session/tests/session_id_error3.phpt + int len = strlen(PS(id)->val); + if (UNEXPECTED(len != PS(id)->len)) { + RETVAL_STR(STR_INIT(PS(id)->val, len, 0)); + } else { + RETVAL_STR(STR_COPY(PS(id))); + } } else { RETVAL_EMPTY_STRING(); } @@ -1926,7 +1934,7 @@ static PHP_FUNCTION(session_id) if (PS(id)) { STR_RELEASE(PS(id)); } - PS(id) = STR_INIT(name, name_len, 0); + PS(id) = STR_COPY(name); } } /* }}} */ diff --git a/ext/session/tests/031.phpt b/ext/session/tests/031.phpt index e8deb3dac5..7486c4b866 100644 --- a/ext/session/tests/031.phpt +++ b/ext/session/tests/031.phpt @@ -2,6 +2,7 @@ setting hash_function to sha512 and hash_bits_per_character > 4 should not crash --SKIPIF-- <?php include('skipif.inc'); ?> +<?php if (!extension_loaded('hash')) die('skip hash extension not available'); ?> --INI-- session.use_cookies=0 session.cache_limiter= diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index e4e36760f2..0b2eee69eb 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -194,7 +194,7 @@ spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern return (spl_SplObjectStorageElement*)zend_hash_find_ptr(&intern->storage, hash); } /* }}} */ -void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *obj, zval *inf TSRMLS_DC) /* {{{ */ +spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *obj, zval *inf TSRMLS_DC) /* {{{ */ { spl_SplObjectStorageElement *pelement, element; zend_string *hash = spl_object_storage_get_hash(intern, this, obj TSRMLS_CC); @@ -213,7 +213,7 @@ void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *o ZVAL_NULL(&pelement->inf); } spl_object_storage_free_hash(intern, hash); - return; + return pelement; } ZVAL_COPY(&element.obj, obj); @@ -222,8 +222,9 @@ void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *o } else { ZVAL_NULL(&element.inf); } - zend_hash_update_mem(&intern->storage, hash, &element, sizeof(spl_SplObjectStorageElement)); + pelement = zend_hash_update_mem(&intern->storage, hash, &element, sizeof(spl_SplObjectStorageElement)); spl_object_storage_free_hash(intern, hash); + return pelement; } /* }}} */ int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *this, zval *obj TSRMLS_DC) /* {{{ */ @@ -796,7 +797,9 @@ SPL_METHOD(SplObjectStorage, unserialize) const unsigned char *p, *s; php_unserialize_data_t var_hash; zval entry, pmembers, pcount, inf; + spl_SplObjectStorageElement *element; long count; + HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; @@ -838,6 +841,7 @@ SPL_METHOD(SplObjectStorage, unserialize) if(*p != 'O' && *p != 'C' && *p != 'r') { goto outexcept; } + /* sore reference to allow cross-references between different elements */ if (!php_var_unserialize(&entry, &p, s + buf_len, &var_hash TSRMLS_CC)) { goto outexcept; } @@ -869,7 +873,9 @@ SPL_METHOD(SplObjectStorage, unserialize) var_push_dtor(&var_hash, &pelement->obj); } } - spl_object_storage_attach(intern, getThis(), &entry, &inf TSRMLS_CC); + element = spl_object_storage_attach(intern, getThis(), &entry, &inf TSRMLS_CC); + var_replace(&var_hash, &entry, &element->obj); + var_replace(&var_hash, &inf, &element->inf); zval_ptr_dtor(&entry); zval_ptr_dtor(&inf); } diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index 2472ebf57c..4ecdd09dd7 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -51,6 +51,7 @@ typedef struct php_unserialize_data* php_unserialize_data_t; PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *var_hash TSRMLS_DC); PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC); +PHPAPI int php_var_unserialize_ref(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC); PHPAPI int php_var_unserialize_intern(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC); #define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \ @@ -114,6 +115,7 @@ do { \ } \ } while (0) +PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval *nzval); PHPAPI void var_push_dtor(php_unserialize_data_t *var_hash, zval *val); PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval); PHPAPI void var_destroy(php_unserialize_data_t *var_hash); diff --git a/ext/standard/var.c b/ext/standard/var.c index 8881b70079..01da9bb692 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -616,17 +616,26 @@ PHP_FUNCTION(var_export) static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC); -static inline int php_add_var_hash(HashTable *var_hash, zval *var, zval *var_old TSRMLS_DC) /* {{{ */ +static inline int php_add_var_hash(HashTable *var_hash, zval *var_ptr, zval *var_old TSRMLS_DC) /* {{{ */ { zval var_no, *zv; char id[32], *p; register int len; + zval *var = var_ptr; + if (Z_ISREF_P(var)) { + var = Z_REFVAL_P(var); + } 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) Z_OBJ_P(var)); *(--p) = 'O'; len = id + sizeof(id) - 1 - p; + } else if (var_ptr != var) { + p = smart_str_print_long(id + sizeof(id) - 1, + (long) Z_REF_P(var)); + *(--p) = 'R'; + len = id + sizeof(id) - 1 - p; } else { p = smart_str_print_long(id + sizeof(id) - 1, (long) var); len = id + sizeof(id) - 1 - p; @@ -634,7 +643,7 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, zval *var_old if ((zv = zend_hash_str_find(var_hash, p, len)) != NULL) { ZVAL_COPY_VALUE(var_old, zv); - if (!Z_ISREF_P(var)) { + if (var == var_ptr) { /* we still need to bump up the counter, since non-refs will * be counted separately by unserializer */ ZVAL_LONG(&var_no, -1); @@ -812,7 +821,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var ZVAL_UNDEF(&var_already); if (var_hash && - php_add_var_hash(var_hash, Z_ISREF_P(struc)? Z_REFVAL_P(struc) : struc, &var_already TSRMLS_CC) == FAILURE) { + php_add_var_hash(var_hash, struc, &var_already TSRMLS_CC) == FAILURE) { if (Z_ISREF_P(struc)) { smart_str_appendl(buf, "R:", 2); smart_str_append_long(buf, Z_LVAL(var_already)); diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index c062c5800d..2525350bbc 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -34,6 +34,12 @@ typedef struct { void *next; } var_entries; +typedef struct { + zval data[VAR_ENTRIES_MAX]; + long used_slots; + void *next; +} var_dtor_entries; + static inline void var_push(php_unserialize_data_t *var_hashx, zval *rval) { var_entries *var_hash = (*var_hashx)->last; @@ -60,13 +66,13 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval *rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) { - var_entries *var_hash = (*var_hashx)->last_dtor; + var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { - var_hash = emalloc(sizeof(var_entries)); + var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; @@ -79,19 +85,21 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) (*var_hashx)->last_dtor = var_hash; } - if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval); - var_hash->data[var_hash->used_slots++] = rval; + ZVAL_COPY(&var_hash->data[var_hash->used_slots], rval); + var_hash->used_slots++; } +//??? +#if 0 PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval) { - var_entries *var_hash = (*var_hashx)->last_dtor; + var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { - var_hash = emalloc(sizeof(var_entries)); + var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; @@ -104,10 +112,31 @@ PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rva (*var_hashx)->last_dtor = var_hash; } - var_hash->data[var_hash->used_slots++] = rval; + ZVAL_COPY_VALUE(&var_hash->data[var_hash->used_slots], rval); + var_hash->used_slots++; +} +#endif + +PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval *nzval) +{ + long i; + var_entries *var_hash = (*var_hashx)->first; +#if VAR_ENTRIES_DBG + 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++) { + if (var_hash->data[i] == ozval) { + var_hash->data[i] = nzval; + /* do not break here */ + } + } + var_hash = var_hash->next; + } } -static int var_access(php_unserialize_data_t *var_hashx, long id, zval **store) +static zval *var_access(php_unserialize_data_t *var_hashx, long id) { var_entries *var_hash = (*var_hashx)->first; #if VAR_ENTRIES_DBG @@ -119,13 +148,11 @@ static int var_access(php_unserialize_data_t *var_hashx, long id, zval **store) id -= VAR_ENTRIES_MAX; } - if (!var_hash) return !SUCCESS; + if (!var_hash) return NULL; - if (id < 0 || id >= var_hash->used_slots) return !SUCCESS; + if (id < 0 || id >= var_hash->used_slots) return NULL; - *store = var_hash->data[id]; - - return SUCCESS; + return var_hash->data[id]; } PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) @@ -133,6 +160,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) void *next; long i; var_entries *var_hash = (*var_hashx)->first; + var_dtor_entries *var_dtor_hash = (*var_hashx)->first_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); #endif @@ -143,15 +171,13 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) var_hash = next; } - var_hash = (*var_hashx)->first_dtor; - - while (var_hash) { - for (i = 0; i < var_hash->used_slots; i++) { - zval_ptr_dtor(var_hash->data[i]); + while (var_dtor_hash) { + for (i = 0; i < var_dtor_hash->used_slots; i++) { + zval_ptr_dtor(&var_dtor_hash->data[i]); } - next = var_hash->next; - efree(var_hash); - var_hash = next; + next = var_dtor_hash->next; + efree(var_dtor_hash); + var_dtor_hash = next; } } @@ -207,7 +233,7 @@ static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen #define YYMARKER marker -#line 215 "ext/standard/var_unserializer.re" +#line 241 "ext/standard/var_unserializer.re" @@ -275,6 +301,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long while (elements-- > 0) { zval key, *data, d, *old_data; + ZVAL_UNDEF(&key); if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { zval_dtor(&key); return 0; @@ -292,12 +319,14 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long switch (Z_TYPE(key)) { case IS_LONG: if ((old_data = zend_hash_index_find(ht, Z_LVAL(key))) != NULL) { + //??? update hash var_push_dtor(var_hash, old_data); } data = zend_hash_index_update(ht, Z_LVAL(key), &d); break; case IS_STRING: if ((old_data = zend_symtable_find(ht, Z_STR(key))) != NULL) { + //??? update hash var_push_dtor(var_hash, old_data); } data = zend_symtable_update(ht, Z_STR(key), &d); @@ -394,6 +423,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) zval retval; zval fname; + //??? TODO: resize before if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_P(rval), elements, 1)) { return 0; } @@ -439,7 +469,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) start = cursor; -#line 443 "ext/standard/var_unserializer.c" +#line 473 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -499,9 +529,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 789 "ext/standard/var_unserializer.re" +#line 817 "ext/standard/var_unserializer.re" { return 0; } -#line 505 "ext/standard/var_unserializer.c" +#line 535 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -544,13 +574,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 783 "ext/standard/var_unserializer.re" +#line 811 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 554 "ext/standard/var_unserializer.c" +#line 584 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -580,7 +610,7 @@ yy20: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 644 "ext/standard/var_unserializer.re" +#line 672 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -719,7 +749,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 723 "ext/standard/var_unserializer.c" +#line 753 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -744,7 +774,7 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 636 "ext/standard/var_unserializer.re" +#line 664 "ext/standard/var_unserializer.re" { //??? INIT_PZVAL(rval); @@ -752,7 +782,7 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 756 "ext/standard/var_unserializer.c" +#line 786 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -773,7 +803,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 615 "ext/standard/var_unserializer.re" +#line 643 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -794,7 +824,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 798 "ext/standard/var_unserializer.c" +#line 828 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -815,7 +845,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 585 "ext/standard/var_unserializer.re" +#line 613 "ext/standard/var_unserializer.re" { size_t len, maxlen; //??? TODO: use zend_string* instead of char* @@ -845,7 +875,7 @@ yy41: efree(str); return 1; } -#line 849 "ext/standard/var_unserializer.c" +#line 879 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -866,7 +896,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 558 "ext/standard/var_unserializer.re" +#line 586 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -893,7 +923,7 @@ yy48: ZVAL_STRINGL(rval, str, len); return 1; } -#line 897 "ext/standard/var_unserializer.c" +#line 927 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -981,7 +1011,7 @@ yy61: } yy63: ++YYCURSOR; -#line 549 "ext/standard/var_unserializer.re" +#line 577 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -990,7 +1020,7 @@ use_double: ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 994 "ext/standard/var_unserializer.c" +#line 1024 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1049,7 +1079,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 533 "ext/standard/var_unserializer.re" +#line 561 "ext/standard/var_unserializer.re" { *p = YYCURSOR; @@ -1065,7 +1095,7 @@ yy73: return 1; } -#line 1069 "ext/standard/var_unserializer.c" +#line 1099 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1092,7 +1122,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 507 "ext/standard/var_unserializer.re" +#line 535 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1118,7 +1148,7 @@ yy79: ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } -#line 1122 "ext/standard/var_unserializer.c" +#line 1152 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1126,22 +1156,22 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 501 "ext/standard/var_unserializer.re" +#line 529 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } -#line 1136 "ext/standard/var_unserializer.c" +#line 1166 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 495 "ext/standard/var_unserializer.re" +#line 523 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } -#line 1145 "ext/standard/var_unserializer.c" +#line 1175 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1164,7 +1194,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 472 "ext/standard/var_unserializer.re" +#line 500 "ext/standard/var_unserializer.re" { long id; @@ -1172,22 +1202,22 @@ yy91: if (!var_hash) return 0; id = parse_iv(start + 2) - 1; - if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } //??? //??? if (rval == rval_ref) return 0; - if (!ZVAL_IS_UNDEF(rval)) { - var_push_dtor_no_addref(var_hash, rval); - } +//??? if (!ZVAL_IS_UNDEF(rval)) { +//??? var_push_dtor_no_addref(var_hash, rval); +//??? } ZVAL_COPY(rval, rval_ref); //??? Z_UNSET_ISREF_PP(rval); return 1; } -#line 1191 "ext/standard/var_unserializer.c" +#line 1221 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1210,7 +1240,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 447 "ext/standard/var_unserializer.re" +#line 477 "ext/standard/var_unserializer.re" { long id; @@ -1218,13 +1248,11 @@ yy97: if (!var_hash) return 0; id = parse_iv(start + 2) - 1; - if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } - if (!ZVAL_IS_UNDEF(rval)) { - zval_ptr_dtor(rval); - } + zval_ptr_dtor(rval); if (Z_ISREF_P(rval_ref)) { ZVAL_COPY(rval, rval_ref); } else { @@ -1235,9 +1263,9 @@ yy97: return 1; } -#line 1239 "ext/standard/var_unserializer.c" +#line 1267 "ext/standard/var_unserializer.c" } -#line 791 "ext/standard/var_unserializer.re" +#line 819 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index ec9bfae398..c4595a63c4 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -32,6 +32,12 @@ typedef struct { void *next; } var_entries; +typedef struct { + zval data[VAR_ENTRIES_MAX]; + long used_slots; + void *next; +} var_dtor_entries; + static inline void var_push(php_unserialize_data_t *var_hashx, zval *rval) { var_entries *var_hash = (*var_hashx)->last; @@ -58,13 +64,13 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval *rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) { - var_entries *var_hash = (*var_hashx)->last_dtor; + var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { - var_hash = emalloc(sizeof(var_entries)); + var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; @@ -77,19 +83,21 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) (*var_hashx)->last_dtor = var_hash; } - if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval); - var_hash->data[var_hash->used_slots++] = rval; + ZVAL_COPY(&var_hash->data[var_hash->used_slots], rval); + var_hash->used_slots++; } +//??? +#if 0 PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval) { - var_entries *var_hash = (*var_hashx)->last_dtor; + var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { - var_hash = emalloc(sizeof(var_entries)); + var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; @@ -102,10 +110,31 @@ PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rva (*var_hashx)->last_dtor = var_hash; } - var_hash->data[var_hash->used_slots++] = rval; + ZVAL_COPY_VALUE(&var_hash->data[var_hash->used_slots], rval); + var_hash->used_slots++; +} +#endif + +PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval *nzval) +{ + long i; + var_entries *var_hash = (*var_hashx)->first; +#if VAR_ENTRIES_DBG + 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++) { + if (var_hash->data[i] == ozval) { + var_hash->data[i] = nzval; + /* do not break here */ + } + } + var_hash = var_hash->next; + } } -static int var_access(php_unserialize_data_t *var_hashx, long id, zval **store) +static zval *var_access(php_unserialize_data_t *var_hashx, long id) { var_entries *var_hash = (*var_hashx)->first; #if VAR_ENTRIES_DBG @@ -117,13 +146,11 @@ static int var_access(php_unserialize_data_t *var_hashx, long id, zval **store) id -= VAR_ENTRIES_MAX; } - if (!var_hash) return !SUCCESS; + if (!var_hash) return NULL; - if (id < 0 || id >= var_hash->used_slots) return !SUCCESS; + if (id < 0 || id >= var_hash->used_slots) return NULL; - *store = var_hash->data[id]; - - return SUCCESS; + return var_hash->data[id]; } PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) @@ -131,6 +158,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) void *next; long i; var_entries *var_hash = (*var_hashx)->first; + var_dtor_entries *var_dtor_hash = (*var_hashx)->first_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); #endif @@ -141,15 +169,13 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) var_hash = next; } - var_hash = (*var_hashx)->first_dtor; - - while (var_hash) { - for (i = 0; i < var_hash->used_slots; i++) { - zval_ptr_dtor(var_hash->data[i]); + while (var_dtor_hash) { + for (i = 0; i < var_dtor_hash->used_slots; i++) { + zval_ptr_dtor(&var_dtor_hash->data[i]); } - next = var_hash->next; - efree(var_hash); - var_hash = next; + next = var_dtor_hash->next; + efree(var_dtor_hash); + var_dtor_hash = next; } } @@ -279,6 +305,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long while (elements-- > 0) { zval key, *data, d, *old_data; + ZVAL_UNDEF(&key); if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { zval_dtor(&key); return 0; @@ -296,12 +323,14 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long switch (Z_TYPE(key)) { case IS_LONG: if ((old_data = zend_hash_index_find(ht, Z_LVAL(key))) != NULL) { + //??? update hash var_push_dtor(var_hash, old_data); } data = zend_hash_index_update(ht, Z_LVAL(key), &d); break; case IS_STRING: if ((old_data = zend_symtable_find(ht, Z_STR(key))) != NULL) { + //??? update hash var_push_dtor(var_hash, old_data); } data = zend_symtable_update(ht, Z_STR(key), &d); @@ -398,6 +427,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) zval retval; zval fname; + //??? TODO: resize before if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_P(rval), elements, 1)) { return 0; } @@ -451,13 +481,11 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) if (!var_hash) return 0; id = parse_iv(start + 2) - 1; - if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } - if (!ZVAL_IS_UNDEF(rval)) { - zval_ptr_dtor(rval); - } + zval_ptr_dtor(rval); if (Z_ISREF_P(rval_ref)) { ZVAL_COPY(rval, rval_ref); } else { @@ -476,16 +504,16 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) if (!var_hash) return 0; id = parse_iv(start + 2) - 1; - if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } //??? //??? if (rval == rval_ref) return 0; - if (!ZVAL_IS_UNDEF(rval)) { - var_push_dtor_no_addref(var_hash, rval); - } +//??? if (!ZVAL_IS_UNDEF(rval)) { +//??? var_push_dtor_no_addref(var_hash, rval); +//??? } ZVAL_COPY(rval, rval_ref); //??? Z_UNSET_ISREF_PP(rval); diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 8e2aaab923..a9830910af 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -104,7 +104,7 @@ PHP_MINFO_FUNCTION(tokenizer) static void tokenize(zval *return_value TSRMLS_DC) { zval token; - zval *keyword; + zval keyword; int token_type; zend_bool destroy; int token_line = 1; @@ -130,18 +130,17 @@ static void tokenize(zval *return_value TSRMLS_DC) } if (token_type >= 256) { - MAKE_STD_ZVAL(keyword); - array_init(keyword); - add_next_index_long(keyword, token_type); + array_init(&keyword); + add_next_index_long(&keyword, token_type); if (token_type == T_END_HEREDOC) { if (CG(increment_lineno)) { token_line = ++CG(zend_lineno); CG(increment_lineno) = 0; } } - add_next_index_stringl(keyword, (char *)zendtext, zendleng, 1); - add_next_index_long(keyword, token_line); - add_next_index_zval(return_value, keyword); + add_next_index_stringl(&keyword, (char *)zendtext, zendleng, 1); + add_next_index_long(&keyword, token_line); + add_next_index_zval(return_value, &keyword); } else { add_next_index_stringl(return_value, (char *)zendtext, zendleng, 1); } @@ -158,12 +157,11 @@ static void tokenize(zval *return_value TSRMLS_DC) ) { // fetch the rest into a T_INLINE_HTML if (zendcursor != zendlimit) { - MAKE_STD_ZVAL(keyword); - array_init(keyword); - add_next_index_long(keyword, T_INLINE_HTML); - add_next_index_stringl(keyword, (char *)zendcursor, zendlimit - zendcursor, 1); - add_next_index_long(keyword, token_line); - add_next_index_zval(return_value, keyword); + array_init(&keyword); + add_next_index_long(&keyword, T_INLINE_HTML); + add_next_index_stringl(&keyword, (char *)zendcursor, zendlimit - zendcursor, 1); + add_next_index_long(&keyword, token_line); + add_next_index_zval(return_value, &keyword); } break; } @@ -179,20 +177,18 @@ static void tokenize(zval *return_value TSRMLS_DC) */ PHP_FUNCTION(token_get_all) { - char *source = NULL; - int argc = ZEND_NUM_ARGS(); - int source_len; - zval source_z; + zend_string *source; + zval source_zval; zend_lex_state original_lex_state; - if (zend_parse_parameters(argc TSRMLS_CC, "s", &source, &source_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &source) == FAILURE) { return; } - ZVAL_STRINGL(&source_z, source, source_len, 1); + ZVAL_STR(&source_zval, STR_COPY(source)); zend_save_lexical_state(&original_lex_state TSRMLS_CC); - if (zend_prepare_string_for_scanning(&source_z, "" TSRMLS_CC) == FAILURE) { + if (zend_prepare_string_for_scanning(&source_zval, "" TSRMLS_CC) == FAILURE) { zend_restore_lexical_state(&original_lex_state TSRMLS_CC); RETURN_FALSE; } @@ -202,7 +198,7 @@ PHP_FUNCTION(token_get_all) tokenize(return_value TSRMLS_CC); zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - zval_dtor(&source_z); + zval_dtor(&source_zval); } /* }}} */ @@ -210,13 +206,13 @@ PHP_FUNCTION(token_get_all) */ PHP_FUNCTION(token_name) { - int argc = ZEND_NUM_ARGS(); long type; - if (zend_parse_parameters(argc TSRMLS_CC, "l", &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) { return; } - RETVAL_STRING(get_token_type_name(type), 1); + + RETVAL_STRING(get_token_type_name(type)); } /* }}} */ |