21
21
#include " php_incomplete_class.h"
22
22
#include " zend_portability.h"
23
23
24
+ /* {{{ reference-handling for unserializer: var_* */
25
+ #define VAR_ENTRIES_MAX 1018 /* 1024 - offsetof(php_unserialize_data, entries) / sizeof(void*) */
26
+ #define VAR_DTOR_ENTRIES_MAX 255 /* 256 - offsetof(var_dtor_entries, data) / sizeof(zval) */
27
+ #define VAR_ENTRIES_DBG 0
28
+
29
+ /* VAR_FLAG used in var_dtor entries to signify an entry on which __wakeup should be called */
30
+ #define VAR_WAKEUP_FLAG 1
31
+
32
+ typedef struct {
33
+ zend_long used_slots;
34
+ void *next;
35
+ zval *data[VAR_ENTRIES_MAX];
36
+ } var_entries;
37
+
38
+ typedef struct {
39
+ zend_long used_slots;
40
+ void *next;
41
+ zval data[VAR_ENTRIES_MAX];
42
+ } var_dtor_entries;
43
+
24
44
struct php_unserialize_data {
25
- void *first ;
26
- void *last ;
27
- void *first_dtor ;
28
- void *last_dtor ;
29
- HashTable *allowed_classes ;
45
+ var_entries *last ;
46
+ var_dtor_entries *first_dtor ;
47
+ var_dtor_entries *last_dtor ;
48
+ HashTable *allowed_classes ;
49
+ var_entries entries ;
30
50
};
31
51
32
52
PHPAPI php_unserialize_data_t php_var_unserialize_init () {
33
53
php_unserialize_data_t d;
34
54
/* fprintf(stderr, "UNSERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */
35
55
if (BG (serialize_lock) || !BG (unserialize).level ) {
36
- d = ecalloc (1 , sizeof (struct php_unserialize_data ));
56
+ d = emalloc (sizeof (struct php_unserialize_data ));
57
+ d->last = &d->entries ;
58
+ d->first_dtor = d->last_dtor = NULL ;
59
+ d->allowed_classes = NULL ;
60
+ d->entries .used_slots = 0 ;
61
+ d->entries .next = NULL ;
37
62
if (!BG (serialize_lock)) {
38
63
BG (unserialize).data = d;
39
64
BG (unserialize).level = 1 ;
@@ -63,44 +88,19 @@ PHPAPI void php_var_unserialize_set_allowed_classes(php_unserialize_data_t d, Ha
63
88
d->allowed_classes = classes;
64
89
}
65
90
66
-
67
- /* {{{ reference-handling for unserializer: var_* */
68
- #define VAR_ENTRIES_MAX 1024
69
- #define VAR_ENTRIES_DBG 0
70
-
71
- /* VAR_FLAG used in var_dtor entries to signify an entry on which __wakeup should be called */
72
- #define VAR_WAKEUP_FLAG 1
73
-
74
- typedef struct {
75
- zval *data[VAR_ENTRIES_MAX];
76
- zend_long used_slots;
77
- void *next;
78
- } var_entries;
79
-
80
- typedef struct {
81
- zval data[VAR_ENTRIES_MAX];
82
- zend_long used_slots;
83
- void *next;
84
- } var_dtor_entries;
85
-
86
91
static inline void var_push (php_unserialize_data_t *var_hashx, zval *rval)
87
92
{
88
93
var_entries *var_hash = (*var_hashx)->last ;
89
94
#if VAR_ENTRIES_DBG
90
95
fprintf (stderr, " var_push(%ld): %d\n " , var_hash?var_hash->used_slots :-1L , Z_TYPE_P (rval));
91
96
#endif
92
97
93
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
98
+ if (var_hash->used_slots == VAR_ENTRIES_MAX) {
94
99
var_hash = emalloc (sizeof (var_entries));
95
100
var_hash->used_slots = 0 ;
96
101
var_hash->next = 0 ;
97
102
98
- if (!(*var_hashx)->first ) {
99
- (*var_hashx)->first = var_hash;
100
- } else {
101
- ((var_entries *) (*var_hashx)->last )->next = var_hash;
102
- }
103
-
103
+ (*var_hashx)->last ->next = var_hash;
104
104
(*var_hashx)->last = var_hash;
105
105
}
106
106
@@ -127,15 +127,15 @@ PHPAPI zval *var_tmp_var(php_unserialize_data_t *var_hashx)
127
127
}
128
128
129
129
var_hash = (*var_hashx)->last_dtor ;
130
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX ) {
130
+ if (!var_hash || var_hash->used_slots == VAR_DTOR_ENTRIES_MAX ) {
131
131
var_hash = emalloc (sizeof (var_dtor_entries));
132
132
var_hash->used_slots = 0 ;
133
133
var_hash->next = 0 ;
134
134
135
135
if (!(*var_hashx)->first_dtor ) {
136
136
(*var_hashx)->first_dtor = var_hash;
137
137
} else {
138
- ((var_dtor_entries *) (* var_hashx)->last_dtor ) ->next = var_hash;
138
+ (* var_hashx)->last_dtor ->next = var_hash;
139
139
}
140
140
141
141
(*var_hashx)->last_dtor = var_hash;
@@ -148,7 +148,7 @@ PHPAPI zval *var_tmp_var(php_unserialize_data_t *var_hashx)
148
148
PHPAPI void var_replace (php_unserialize_data_t *var_hashx, zval *ozval, zval *nzval)
149
149
{
150
150
zend_long i;
151
- var_entries *var_hash = (*var_hashx)->first ;
151
+ var_entries *var_hash = & (*var_hashx)->entries ;
152
152
#if VAR_ENTRIES_DBG
153
153
fprintf (stderr, " var_replace(%ld): %d\n " , var_hash?var_hash->used_slots :-1L , Z_TYPE_P (nzval));
154
154
#endif
@@ -166,7 +166,7 @@ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval *nz
166
166
167
167
static zval *var_access (php_unserialize_data_t *var_hashx, zend_long id)
168
168
{
169
- var_entries *var_hash = (*var_hashx)->first ;
169
+ var_entries *var_hash = & (*var_hashx)->entries ;
170
170
#if VAR_ENTRIES_DBG
171
171
fprintf (stderr, " var_access(%ld): %ld\n " , var_hash?var_hash->used_slots :-1L , id);
172
172
#endif
@@ -187,7 +187,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
187
187
{
188
188
void *next;
189
189
zend_long i;
190
- var_entries *var_hash = (*var_hashx)->first ;
190
+ var_entries *var_hash = (*var_hashx)->entries . next ;
191
191
var_dtor_entries *var_dtor_hash = (*var_hashx)->first_dtor ;
192
192
zend_bool wakeup_failed = 0 ;
193
193
zval wakeup_name;
0 commit comments