summaryrefslogtreecommitdiff
path: root/ext/standard/var_unserializer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/var_unserializer.c')
-rw-r--r--ext/standard/var_unserializer.c635
1 files changed, 635 insertions, 0 deletions
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
new file mode 100644
index 0000000000..fe2fdcbf00
--- /dev/null
+++ b/ext/standard/var_unserializer.c
@@ -0,0 +1,635 @@
+/* Generated by re2c 0.5 on Fri Nov 9 14:39:34 2001 */
+#line 1 "/home/sas/src/php4/ext/standard/var_unserializer.re"
+#include "php.h"
+#include "ext/standard/php_var.h"
+#include "php_incomplete_class.h"
+
+/* {{{ reference-handling for unserializer: var_* */
+#define VAR_ENTRIES_MAX 1024
+
+typedef struct {
+ zval *data[VAR_ENTRIES_MAX];
+ int used_slots;
+ void *next;
+} var_entries;
+
+static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
+{
+ var_entries *var_hash = var_hashx->first, *prev = NULL;
+
+ while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
+ prev = var_hash;
+ var_hash = var_hash->next;
+ }
+
+ if (!var_hash) {
+ 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;
+ }
+
+ var_hash->data[var_hash->used_slots++] = *rval;
+}
+
+void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
+{
+ int i;
+ var_entries *var_hash = var_hashx->first;
+
+ while (var_hash) {
+ for (i = 0; i < var_hash->used_slots; i++) {
+ if (var_hash->data[i] == ozval) {
+ var_hash->data[i] = *nzval;
+ return;
+ }
+ }
+ var_hash = var_hash->next;
+ }
+}
+
+static int var_access(php_unserialize_data_t *var_hashx, int id, zval ***store)
+{
+ var_entries *var_hash = var_hashx->first;
+
+ while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
+ var_hash = var_hash->next;
+ id -= VAR_ENTRIES_MAX;
+ }
+
+ if (!var_hash) return !SUCCESS;
+
+ if (id >= var_hash->used_slots) return !SUCCESS;
+
+ *store = &var_hash->data[id];
+
+ return SUCCESS;
+}
+
+void var_destroy(php_unserialize_data_t *var_hashx)
+{
+ void *next;
+ var_entries *var_hash = var_hashx->first;
+
+ while (var_hash) {
+ next = var_hash->next;
+ efree(var_hash);
+ var_hash = next;
+ }
+}
+
+/* }}} */
+
+#define YYFILL(n) do { } while (0)
+#define YYCTYPE unsigned char
+#define YYCURSOR cursor
+#define YYLIMIT limit
+#define YYMARKER marker
+
+
+#line 97
+
+
+
+
+static inline int parse_iv2(const char *p, const char **q)
+{
+ char cursor;
+ int result = 0;
+
+ while (1) {
+ cursor = *p;
+ if (cursor >= '0' && cursor <= '9') {
+ result = result * 10 + cursor - '0';
+ } else {
+ break;
+ }
+ p++;
+ }
+ if (q) *q = p;
+ return result;
+}
+
+static inline int parse_iv(const char *p)
+{
+ return parse_iv2(p, NULL);
+}
+
+#define UNSERIALIZE_PARAMETER zval **rval, const char **p, const char *max, php_unserialize_data_t *var_hash TSRMLS_DC
+#define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
+
+static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int elements)
+{
+ while (elements-- > 0) {
+ zval *key, *data;
+
+ ALLOC_INIT_ZVAL(key);
+
+ if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
+ zval_dtor(key);
+ FREE_ZVAL(key);
+ return 0;
+ }
+
+ ALLOC_INIT_ZVAL(data);
+
+ if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
+ zval_dtor(key);
+ FREE_ZVAL(key);
+ zval_dtor(data);
+ FREE_ZVAL(data);
+ return 0;
+ }
+
+ switch (Z_TYPE_P(key)) {
+ case IS_LONG:
+ zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
+ break;
+ case IS_STRING:
+ zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
+ break;
+
+ }
+
+ zval_dtor(key);
+ FREE_ZVAL(key);
+ }
+
+ return 1;
+}
+
+static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
+{
+ if (*((*p)++) == '}')
+ return 1;
+
+ zval_ptr_dtor(rval);
+ return 0;
+}
+
+static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
+{
+ int elements;
+
+ elements = parse_iv2((*p) + 2, p);
+
+ (*p) += 2;
+
+ object_init_ex(*rval, ce);
+ return elements;
+}
+
+static inline int object_common2(UNSERIALIZE_PARAMETER, int elements)
+{
+ zval *retval_ptr = NULL;
+ zval fname;
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
+ return 0;
+ }
+
+ INIT_PZVAL(&fname);
+ ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
+ call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
+
+ if (retval_ptr)
+ zval_ptr_dtor(&retval_ptr);
+
+ return finish_nested_data(UNSERIALIZE_PASSTHRU);
+
+}
+
+PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+{
+ const unsigned char *cursor, *limit, *marker, *start;
+ zval **rval_ref;
+
+ cursor = *p;
+
+ if (var_hash && cursor[0] != 'R') {
+ var_push(var_hash, rval);
+ }
+
+ start = cursor;
+
+
+
+{
+ YYCTYPE yych;
+ unsigned int yyaccept;
+ static unsigned char yybm[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ };
+ goto yy0;
+yy1: ++YYCURSOR;
+yy0:
+ if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ if(yych <= 'c'){
+ if(yych <= 'Q'){
+ if(yych <= 'M') goto yy13;
+ if(yych <= 'N') goto yy5;
+ if(yych <= 'O') goto yy12;
+ goto yy13;
+ } else {
+ if(yych <= '`'){
+ if(yych <= 'R') goto yy3;
+ goto yy13;
+ } else {
+ if(yych <= 'a') goto yy10;
+ if(yych <= 'b') goto yy6;
+ goto yy13;
+ }
+ }
+ } else {
+ if(yych <= 'n'){
+ if(yych <= 'd') goto yy8;
+ if(yych == 'i') goto yy7;
+ goto yy13;
+ } else {
+ if(yych <= 'r'){
+ if(yych <= 'o') goto yy11;
+ goto yy13;
+ } else {
+ if(yych <= 's') goto yy9;
+ if(yych <= '\277') goto yy13;
+ }
+ }
+ }
+yy2: YYCURSOR = YYMARKER;
+ switch(yyaccept){
+ case 0: goto yy4;
+ }
+yy3: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy65;
+yy4:
+#line 356
+ { return 0; }
+yy5: yych = *++YYCURSOR;
+ if(yych == ';') goto yy63;
+ goto yy4;
+yy6: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy58;
+ goto yy4;
+yy7: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy53;
+ goto yy4;
+yy8: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy38;
+ goto yy4;
+yy9: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy32;
+ goto yy4;
+yy10: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy26;
+ goto yy4;
+yy11: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy20;
+ goto yy4;
+yy12: yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == ':') goto yy14;
+ goto yy4;
+yy13: yych = *++YYCURSOR;
+ goto yy4;
+yy14: yych = *++YYCURSOR;
+ if(yybm[0+yych] & 128) goto yy15;
+ goto yy2;
+yy15: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy16: if(yybm[0+yych] & 128) goto yy15;
+ if(yych != ':') goto yy2;
+yy17: yych = *++YYCURSOR;
+ if(yych != '"') goto yy2;
+yy18: yych = *++YYCURSOR;
+yy19:
+#line 317
+ {
+ int len;
+ int elements;
+ int len2;
+ char *class_name;
+ zend_class_entry *ce;
+ int incomplete_class = 0;
+
+ INIT_PZVAL(*rval);
+ len2 = len = parse_iv(start + 2);
+ if (len == 0)
+ return 0;
+
+ class_name = estrndup(YYCURSOR, len);
+ YYCURSOR += len;
+
+ while (len-- > 0) {
+ if (class_name[len] >= 'A' && class_name[len] <= 'Z') {
+ class_name[len] = class_name[len] - 'A' + 'a';
+ }
+ }
+
+ if (zend_hash_find(EG(class_table), class_name, len2 + 1, (void **) &ce) != SUCCESS) {
+ incomplete_class = 1;
+ ce = PHP_IC_ENTRY;
+ } else
+ efree(class_name);
+
+ *p = YYCURSOR;
+ elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+
+ if (incomplete_class) {
+ php_store_class_name(*rval, class_name, len2);
+ efree(class_name);
+ }
+
+ return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+yy20: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy21: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy22: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy21;
+ if(yych >= ';') goto yy2;
+yy23: yych = *++YYCURSOR;
+ if(yych != '"') goto yy2;
+yy24: yych = *++YYCURSOR;
+yy25:
+#line 309
+ {
+
+ INIT_PZVAL(*rval);
+
+ return object_common2(UNSERIALIZE_PASSTHRU,
+ object_common1(UNSERIALIZE_PASSTHRU, &zend_standard_class_def));
+}
+yy26: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy27: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy28: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy27;
+ if(yych >= ';') goto yy2;
+yy29: yych = *++YYCURSOR;
+ if(yych != '{') goto yy2;
+yy30: yych = *++YYCURSOR;
+yy31:
+#line 291
+ {
+ int elements = parse_iv(start + 2);
+
+ *p = YYCURSOR;
+
+ INIT_PZVAL(*rval);
+ Z_TYPE_PP(rval) = IS_ARRAY;
+ ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
+
+ zend_hash_init(Z_ARRVAL_PP(rval), elements + 1, NULL, ZVAL_PTR_DTOR, 0);
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
+ return 0;
+ }
+
+ return finish_nested_data(UNSERIALIZE_PASSTHRU);
+}
+yy32: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy33: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy34: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy33;
+ if(yych >= ';') goto yy2;
+yy35: yych = *++YYCURSOR;
+ if(yych != '"') goto yy2;
+yy36: yych = *++YYCURSOR;
+yy37:
+#line 271
+ {
+ int len;
+ char *str;
+
+ len = parse_iv(start + 2);
+
+ if (len == 0) {
+ str = empty_string;
+ } else {
+ str = estrndup(YYCURSOR, len);
+ }
+
+ YYCURSOR += len + 2;
+ *p = YYCURSOR;
+
+ INIT_PZVAL(*rval);
+ ZVAL_STRINGL(*rval, str, len, 0);
+ return 1;
+}
+yy38: yych = *++YYCURSOR;
+ if(yych == '.') goto yy41;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy39: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy40: if(yych <= '/'){
+ if(yych == '.') goto yy50;
+ goto yy2;
+ } else {
+ if(yych <= '9') goto yy39;
+ if(yych == ';') goto yy44;
+ goto yy2;
+ }
+yy41: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy42: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy43: if(yych <= ';'){
+ if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy42;
+ if(yych <= ':') goto yy2;
+ } else {
+ if(yych <= 'E'){
+ if(yych <= 'D') goto yy2;
+ goto yy46;
+ } else {
+ if(yych == 'e') goto yy46;
+ goto yy2;
+ }
+ }
+yy44: yych = *++YYCURSOR;
+yy45:
+#line 264
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_DOUBLE(*rval, atof(start + 2));
+ return 1;
+}
+yy46: yych = *++YYCURSOR;
+ if(yych <= ','){
+ if(yych != '+') goto yy2;
+ } else {
+ if(yych <= '-') goto yy47;
+ if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy48;
+ goto yy2;
+ }
+yy47: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy48: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy49: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy48;
+ if(yych == ';') goto yy44;
+ goto yy2;
+yy50: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy51: ++YYCURSOR;
+ if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+ yych = *YYCURSOR;
+yy52: if(yych <= ';'){
+ if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy51;
+ if(yych <= ':') goto yy2;
+ goto yy44;
+ } else {
+ if(yych <= 'E'){
+ if(yych <= 'D') goto yy2;
+ goto yy46;
+ } else {
+ if(yych == 'e') goto yy46;
+ goto yy2;
+ }
+ }
+yy53: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy54: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy55: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy54;
+ if(yych != ';') goto yy2;
+yy56: yych = *++YYCURSOR;
+yy57:
+#line 257
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_LONG(*rval, parse_iv(start + 2));
+ return 1;
+}
+yy58: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy59: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy60: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy59;
+ if(yych != ';') goto yy2;
+yy61: yych = *++YYCURSOR;
+yy62:
+#line 250
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_BOOL(*rval, parse_iv(start + 2));
+ return 1;
+}
+yy63: yych = *++YYCURSOR;
+yy64:
+#line 243
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_NULL(*rval);
+ return 1;
+}
+yy65: yych = *++YYCURSOR;
+ if(yych <= '/') goto yy2;
+ if(yych >= ':') goto yy2;
+yy66: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy67: if(yych <= '/') goto yy2;
+ if(yych <= '9') goto yy66;
+ if(yych != ';') goto yy2;
+yy68: yych = *++YYCURSOR;
+yy69:
+#line 224
+ {
+ int id;
+
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_iv(start + 2) - 1;
+ if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+ return 0;
+ }
+
+ zval_ptr_dtor(rval);
+ *rval = *rval_ref;
+ (*rval)->refcount++;
+ (*rval)->is_ref = 1;
+
+ return 1;
+}
+}
+#line 358
+
+
+ return 0;
+}