summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/mbstring/tests/zend_multibyte-10.phpt2
-rw-r--r--ext/mbstring/tests/zend_multibyte-11.phpt2
-rw-r--r--ext/mbstring/tests/zend_multibyte-12.phpt2
-rw-r--r--ext/session/php_session.h2
-rw-r--r--ext/session/session.c44
-rw-r--r--ext/session/tests/031.phpt1
-rw-r--r--ext/spl/spl_observer.c14
-rw-r--r--ext/standard/php_var.h2
-rw-r--r--ext/standard/var.c15
-rw-r--r--ext/standard/var_unserializer.c148
-rw-r--r--ext/standard/var_unserializer.re86
-rw-r--r--ext/tokenizer/tokenizer.c44
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(&current);
+ ZVAL_UNDEF(&current);
if (php_var_unserialize(&current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
- php_set_session_var(name, &current, &var_hash TSRMLS_CC);
+ zval *zv = php_set_session_var(name, &current, &var_hash TSRMLS_CC);
+ var_replace(&var_hash, &current, zv);
+ } else {
+ zval_ptr_dtor(&current);
}
- zval_ptr_dtor(&current);
}
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(&current);
+ if (php_var_unserialize(&current, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
+ zval *zv = php_set_session_var(name, &current, &var_hash TSRMLS_CC);
+ var_replace(&var_hash, &current, zv);
+ } else {
+ zval_ptr_dtor(&current);
}
}
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));
}
/* }}} */