1 : /* Generated by re2c 0.13.5 on Tue Mar 17 16:18:30 2009 */
2 : #line 1 "ext/standard/var_unserializer.re"
3 : /*
4 : +----------------------------------------------------------------------+
5 : | PHP Version 5 |
6 : +----------------------------------------------------------------------+
7 : | Copyright (c) 1997-2009 The PHP Group |
8 : +----------------------------------------------------------------------+
9 : | This source file is subject to version 3.01 of the PHP license, |
10 : | that is bundled with this package in the file LICENSE, and is |
11 : | available through the world-wide-web at the following url: |
12 : | http://www.php.net/license/3_01.txt |
13 : | If you did not receive a copy of the PHP license and are unable to |
14 : | obtain it through the world-wide-web, please send a note to |
15 : | license@php.net so we can mail you a copy immediately. |
16 : +----------------------------------------------------------------------+
17 : | Author: Sascha Schumann <sascha@schumann.cx> |
18 : +----------------------------------------------------------------------+
19 : */
20 :
21 : /* $Id: var_unserializer.c 277375 2009-03-17 23:10:13Z felipe $ */
22 :
23 : #include "php.h"
24 : #include "ext/standard/php_var.h"
25 : #include "php_incomplete_class.h"
26 :
27 : /* {{{ reference-handling for unserializer: var_* */
28 : #define VAR_ENTRIES_MAX 1024
29 :
30 : typedef struct {
31 : zval *data[VAR_ENTRIES_MAX];
32 : long used_slots;
33 : void *next;
34 : } var_entries;
35 :
36 : static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
37 : {
38 : var_entries *var_hash = var_hashx->first, *prev = NULL;
39 :
40 : while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
41 : prev = var_hash;
42 : var_hash = var_hash->next;
43 : }
44 :
45 : if (!var_hash) {
46 : var_hash = emalloc(sizeof(var_entries));
47 : var_hash->used_slots = 0;
48 : var_hash->next = 0;
49 :
50 : if (!var_hashx->first)
51 : var_hashx->first = var_hash;
52 : else
53 : prev->next = var_hash;
54 : }
55 :
56 : var_hash->data[var_hash->used_slots++] = *rval;
57 : }
58 :
59 : static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
60 : {
61 : var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
62 :
63 : while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
64 : prev = var_hash;
65 : var_hash = var_hash->next;
66 : }
67 :
68 : if (!var_hash) {
69 : var_hash = emalloc(sizeof(var_entries));
70 : var_hash->used_slots = 0;
71 : var_hash->next = 0;
72 :
73 : if (!var_hashx->first_dtor)
74 : var_hashx->first_dtor = var_hash;
75 : else
76 : prev->next = var_hash;
77 : }
78 :
79 : (*rval)->refcount++;
80 : var_hash->data[var_hash->used_slots++] = *rval;
81 : }
82 :
83 : PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
84 : {
85 : long i;
86 : var_entries *var_hash = var_hashx->first;
87 :
88 : while (var_hash) {
89 : for (i = 0; i < var_hash->used_slots; i++) {
90 : if (var_hash->data[i] == ozval) {
91 : var_hash->data[i] = *nzval;
92 : /* do not break here */
93 : }
94 : }
95 : var_hash = var_hash->next;
96 : }
97 : }
98 :
99 : static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
100 : {
101 : var_entries *var_hash = var_hashx->first;
102 :
103 : while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
104 : var_hash = var_hash->next;
105 : id -= VAR_ENTRIES_MAX;
106 : }
107 :
108 : if (!var_hash) return !SUCCESS;
109 :
110 : if (id < 0 || id >= var_hash->used_slots) return !SUCCESS;
111 :
112 : *store = &var_hash->data[id];
113 :
114 : return SUCCESS;
115 : }
116 :
117 : PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
118 : {
119 : void *next;
120 : long i;
121 : var_entries *var_hash = var_hashx->first;
122 :
123 : while (var_hash) {
124 : next = var_hash->next;
125 : efree(var_hash);
126 : var_hash = next;
127 : }
128 :
129 : var_hash = var_hashx->first_dtor;
130 :
131 : while (var_hash) {
132 : for (i = 0; i < var_hash->used_slots; i++) {
133 : zval_ptr_dtor(&var_hash->data[i]);
134 : }
135 : next = var_hash->next;
136 : efree(var_hash);
137 : var_hash = next;
138 : }
139 : }
140 :
141 : /* }}} */
142 :
143 : static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen)
144 : {
145 : size_t i, j;
146 : char *str = safe_emalloc(*len, 1, 1);
147 : unsigned char *end = *(unsigned char **)p+maxlen;
148 :
149 : if (end < *p) {
150 : efree(str);
151 : return NULL;
152 : }
153 :
154 : for (i = 0; i < *len; i++) {
155 : if (*p >= end) {
156 : efree(str);
157 : return NULL;
158 : }
159 : if (**p != '\\') {
160 : str[i] = (char)**p;
161 : } else {
162 : unsigned char ch = 0;
163 :
164 : for (j = 0; j < 2; j++) {
165 : (*p)++;
166 : if (**p >= '0' && **p <= '9') {
167 : ch = (ch << 4) + (**p -'0');
168 : } else if (**p >= 'a' && **p <= 'f') {
169 : ch = (ch << 4) + (**p -'a'+10);
170 : } else if (**p >= 'A' && **p <= 'F') {
171 : ch = (ch << 4) + (**p -'A'+10);
172 : } else {
173 : efree(str);
174 : return NULL;
175 : }
176 : }
177 : str[i] = (char)ch;
178 : }
179 : (*p)++;
180 : }
181 : str[i] = 0;
182 : *len = i;
183 : return str;
184 : }
185 :
186 : #define YYFILL(n) do { } while (0)
187 : #define YYCTYPE unsigned char
188 : #define YYCURSOR cursor
189 : #define YYLIMIT limit
190 : #define YYMARKER marker
191 :
192 :
193 : #line 198 "ext/standard/var_unserializer.re"
194 :
195 :
196 :
197 :
198 : static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
199 : {
200 : char cursor;
201 : long result = 0;
202 : int neg = 0;
203 :
204 : switch (*p) {
205 : case '-':
206 : neg++;
207 : /* fall-through */
208 : case '+':
209 : p++;
210 : }
211 :
212 : while (1) {
213 : cursor = (char)*p;
214 : if (cursor >= '0' && cursor <= '9') {
215 : result = result * 10 + cursor - '0';
216 : } else {
217 : break;
218 : }
219 : p++;
220 : }
221 : if (q) *q = p;
222 : if (neg) return -result;
223 : return result;
224 : }
225 :
226 : static inline long parse_iv(const unsigned char *p)
227 : {
228 : return parse_iv2(p, NULL);
229 : }
230 :
231 : /* no need to check for length - re2c already did */
232 : static inline size_t parse_uiv(const unsigned char *p)
233 : {
234 : unsigned char cursor;
235 : size_t result = 0;
236 :
237 : if (*p == '+') {
238 : p++;
239 : }
240 :
241 : while (1) {
242 : cursor = *p;
243 : if (cursor >= '0' && cursor <= '9') {
244 : result = result * 10 + (size_t)(cursor - (unsigned char)'0');
245 : } else {
246 : break;
247 : }
248 : p++;
249 : }
250 : return result;
251 : }
252 :
253 : #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
254 : #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
255 :
256 : static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
257 : {
258 : while (elements-- > 0) {
259 : zval *key, *data, **old_data;
260 :
261 : ALLOC_INIT_ZVAL(key);
262 :
263 : if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) {
264 : zval_dtor(key);
265 : FREE_ZVAL(key);
266 : return 0;
267 : }
268 :
269 : if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) {
270 : zval_dtor(key);
271 : FREE_ZVAL(key);
272 : return 0;
273 : }
274 :
275 : ALLOC_INIT_ZVAL(data);
276 :
277 : if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) {
278 : zval_dtor(key);
279 : FREE_ZVAL(key);
280 : zval_dtor(data);
281 : FREE_ZVAL(data);
282 : return 0;
283 : }
284 :
285 : switch (Z_TYPE_P(key)) {
286 : case IS_LONG:
287 : if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
288 : var_push_dtor(var_hash, old_data);
289 : }
290 : zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
291 : break;
292 : case IS_STRING:
293 : if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
294 : var_push_dtor(var_hash, old_data);
295 : }
296 : zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
297 : break;
298 : }
299 :
300 : zval_dtor(key);
301 : FREE_ZVAL(key);
302 :
303 : if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
304 : (*p)--;
305 : return 0;
306 : }
307 : }
308 :
309 : return 1;
310 : }
311 :
312 : static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
313 : {
314 : if (*((*p)++) == '}')
315 : return 1;
316 :
317 : #if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
318 : zval_ptr_dtor(rval);
319 : #endif
320 : return 0;
321 : }
322 :
323 : static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
324 : {
325 : long datalen;
326 :
327 : if (ce->unserialize == NULL) {
328 : zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
329 : return 0;
330 : }
331 :
332 : datalen = parse_iv2((*p) + 2, p);
333 :
334 : (*p) += 2;
335 :
336 : if (datalen < 0 || (*p) + datalen >= max) {
337 : zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %ld present", datalen, (long)(max - (*p)));
338 : return 0;
339 : }
340 :
341 : if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
342 : return 0;
343 : }
344 :
345 : (*p) += datalen;
346 :
347 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
348 : }
349 :
350 : static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
351 : {
352 : long elements;
353 :
354 : elements = parse_iv2((*p) + 2, p);
355 :
356 : (*p) += 2;
357 :
358 : object_init_ex(*rval, ce);
359 : return elements;
360 : }
361 :
362 : static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
363 : {
364 : zval *retval_ptr = NULL;
365 : zval fname;
366 :
367 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
368 : return 0;
369 : }
370 :
371 : if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
372 : zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
373 : INIT_PZVAL(&fname);
374 : ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
375 : call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
376 : }
377 :
378 : if (retval_ptr)
379 : zval_ptr_dtor(&retval_ptr);
380 :
381 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
382 :
383 : }
384 :
385 : PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
386 : {
387 : const unsigned char *cursor, *limit, *marker, *start;
388 : zval **rval_ref;
389 :
390 : limit = cursor = *p;
391 :
392 : if (var_hash && cursor[0] != 'R') {
393 : var_push(var_hash, rval);
394 : }
395 :
396 : start = cursor;
397 :
398 :
399 :
400 :
401 : #line 402 "ext/standard/var_unserializer.c"
402 : {
403 : YYCTYPE yych;
404 : static const unsigned char yybm[] = {
405 : 0, 0, 0, 0, 0, 0, 0, 0,
406 : 0, 0, 0, 0, 0, 0, 0, 0,
407 : 0, 0, 0, 0, 0, 0, 0, 0,
408 : 0, 0, 0, 0, 0, 0, 0, 0,
409 : 0, 0, 0, 0, 0, 0, 0, 0,
410 : 0, 0, 0, 0, 0, 0, 0, 0,
411 : 128, 128, 128, 128, 128, 128, 128, 128,
412 : 128, 128, 0, 0, 0, 0, 0, 0,
413 : 0, 0, 0, 0, 0, 0, 0, 0,
414 : 0, 0, 0, 0, 0, 0, 0, 0,
415 : 0, 0, 0, 0, 0, 0, 0, 0,
416 : 0, 0, 0, 0, 0, 0, 0, 0,
417 : 0, 0, 0, 0, 0, 0, 0, 0,
418 : 0, 0, 0, 0, 0, 0, 0, 0,
419 : 0, 0, 0, 0, 0, 0, 0, 0,
420 : 0, 0, 0, 0, 0, 0, 0, 0,
421 : 0, 0, 0, 0, 0, 0, 0, 0,
422 : 0, 0, 0, 0, 0, 0, 0, 0,
423 : 0, 0, 0, 0, 0, 0, 0, 0,
424 : 0, 0, 0, 0, 0, 0, 0, 0,
425 : 0, 0, 0, 0, 0, 0, 0, 0,
426 : 0, 0, 0, 0, 0, 0, 0, 0,
427 : 0, 0, 0, 0, 0, 0, 0, 0,
428 : 0, 0, 0, 0, 0, 0, 0, 0,
429 : 0, 0, 0, 0, 0, 0, 0, 0,
430 : 0, 0, 0, 0, 0, 0, 0, 0,
431 : 0, 0, 0, 0, 0, 0, 0, 0,
432 : 0, 0, 0, 0, 0, 0, 0, 0,
433 : 0, 0, 0, 0, 0, 0, 0, 0,
434 : 0, 0, 0, 0, 0, 0, 0, 0,
435 : 0, 0, 0, 0, 0, 0, 0, 0,
436 : 0, 0, 0, 0, 0, 0, 0, 0,
437 : };
438 :
439 1737 : if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
440 1737 : yych = *YYCURSOR;
441 1737 : switch (yych) {
442 : case 'C':
443 131 : case 'O': goto yy13;
444 53 : case 'N': goto yy5;
445 91 : case 'R': goto yy2;
446 1 : case 'S': goto yy10;
447 170 : case 'a': goto yy11;
448 32 : case 'b': goto yy6;
449 51 : case 'd': goto yy8;
450 654 : case 'i': goto yy7;
451 0 : case 'o': goto yy12;
452 10 : case 'r': goto yy4;
453 533 : case 's': goto yy9;
454 0 : case '}': goto yy14;
455 11 : default: goto yy16;
456 : }
457 91 : yy2:
458 91 : yych = *(YYMARKER = ++YYCURSOR);
459 91 : if (yych == ':') goto yy95;
460 41 : yy3:
461 : #line 721 "ext/standard/var_unserializer.re"
462 : { return 0; }
463 : #line 464 "ext/standard/var_unserializer.c"
464 10 : yy4:
465 10 : yych = *(YYMARKER = ++YYCURSOR);
466 10 : if (yych == ':') goto yy89;
467 0 : goto yy3;
468 53 : yy5:
469 53 : yych = *++YYCURSOR;
470 53 : if (yych == ';') goto yy87;
471 0 : goto yy3;
472 32 : yy6:
473 32 : yych = *(YYMARKER = ++YYCURSOR);
474 32 : if (yych == ':') goto yy83;
475 0 : goto yy3;
476 654 : yy7:
477 654 : yych = *(YYMARKER = ++YYCURSOR);
478 654 : if (yych == ':') goto yy77;
479 6 : goto yy3;
480 51 : yy8:
481 51 : yych = *(YYMARKER = ++YYCURSOR);
482 51 : if (yych == ':') goto yy53;
483 0 : goto yy3;
484 533 : yy9:
485 533 : yych = *(YYMARKER = ++YYCURSOR);
486 533 : if (yych == ':') goto yy46;
487 0 : goto yy3;
488 1 : yy10:
489 1 : yych = *(YYMARKER = ++YYCURSOR);
490 1 : if (yych == ':') goto yy39;
491 0 : goto yy3;
492 170 : yy11:
493 170 : yych = *(YYMARKER = ++YYCURSOR);
494 170 : if (yych == ':') goto yy32;
495 1 : goto yy3;
496 0 : yy12:
497 0 : yych = *(YYMARKER = ++YYCURSOR);
498 0 : if (yych == ':') goto yy25;
499 0 : goto yy3;
500 131 : yy13:
501 131 : yych = *(YYMARKER = ++YYCURSOR);
502 131 : if (yych == ':') goto yy17;
503 0 : goto yy3;
504 0 : yy14:
505 0 : ++YYCURSOR;
506 : #line 715 "ext/standard/var_unserializer.re"
507 : {
508 : /* this is the case where we have less data than planned */
509 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
510 : return 0; /* not sure if it should be 0 or 1 here? */
511 : }
512 : #line 513 "ext/standard/var_unserializer.c"
513 11 : yy16:
514 11 : yych = *++YYCURSOR;
515 11 : goto yy3;
516 131 : yy17:
517 131 : yych = *++YYCURSOR;
518 131 : if (yybm[0+yych] & 128) {
519 131 : goto yy20;
520 : }
521 0 : if (yych == '+') goto yy19;
522 21 : yy18:
523 21 : YYCURSOR = YYMARKER;
524 21 : goto yy3;
525 0 : yy19:
526 0 : yych = *++YYCURSOR;
527 0 : if (yybm[0+yych] & 128) {
528 0 : goto yy20;
529 : }
530 0 : goto yy18;
531 144 : yy20:
532 144 : ++YYCURSOR;
533 144 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
534 144 : yych = *YYCURSOR;
535 144 : if (yybm[0+yych] & 128) {
536 13 : goto yy20;
537 : }
538 131 : if (yych != ':') goto yy18;
539 131 : yych = *++YYCURSOR;
540 131 : if (yych != '"') goto yy18;
541 131 : ++YYCURSOR;
542 : #line 603 "ext/standard/var_unserializer.re"
543 : {
544 : size_t len, len2, len3, maxlen;
545 : long elements;
546 : char *class_name;
547 : zend_class_entry *ce;
548 : zend_class_entry **pce;
549 : int incomplete_class = 0;
550 :
551 : int custom_object = 0;
552 :
553 : zval *user_func;
554 : zval *retval_ptr;
555 : zval **args[1];
556 : zval *arg_func_name;
557 :
558 : if (*start == 'C') {
559 : custom_object = 1;
560 : }
561 :
562 : INIT_PZVAL(*rval);
563 : len2 = len = parse_uiv(start + 2);
564 : maxlen = max - YYCURSOR;
565 : if (maxlen < len || len == 0) {
566 : *p = start + 2;
567 : return 0;
568 : }
569 :
570 : class_name = (char*)YYCURSOR;
571 :
572 : YYCURSOR += len;
573 :
574 : if (*(YYCURSOR) != '"') {
575 : *p = YYCURSOR;
576 : return 0;
577 : }
578 : if (*(YYCURSOR+1) != ':') {
579 : *p = YYCURSOR+1;
580 : return 0;
581 : }
582 :
583 : len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377");
584 : if (len3 != len)
585 : {
586 : *p = YYCURSOR + len3 - len;
587 : return 0;
588 : }
589 :
590 : class_name = estrndup(class_name, len);
591 :
592 : do {
593 : /* Try to find class directly */
594 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
595 : ce = *pce;
596 : break;
597 : }
598 :
599 : /* Check for unserialize callback */
600 : if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
601 : incomplete_class = 1;
602 : ce = PHP_IC_ENTRY;
603 : break;
604 : }
605 :
606 : /* Call unserialize callback */
607 : MAKE_STD_ZVAL(user_func);
608 : ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
609 : args[0] = &arg_func_name;
610 : MAKE_STD_ZVAL(arg_func_name);
611 : ZVAL_STRING(arg_func_name, class_name, 1);
612 : if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
613 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
614 : incomplete_class = 1;
615 : ce = PHP_IC_ENTRY;
616 : zval_ptr_dtor(&user_func);
617 : zval_ptr_dtor(&arg_func_name);
618 : break;
619 : }
620 : if (retval_ptr) {
621 : zval_ptr_dtor(&retval_ptr);
622 : }
623 :
624 : /* The callback function may have defined the class */
625 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
626 : ce = *pce;
627 : } else {
628 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
629 : incomplete_class = 1;
630 : ce = PHP_IC_ENTRY;
631 : }
632 :
633 : zval_ptr_dtor(&user_func);
634 : zval_ptr_dtor(&arg_func_name);
635 : break;
636 : } while (1);
637 :
638 : *p = YYCURSOR;
639 :
640 : if (custom_object) {
641 : efree(class_name);
642 : return object_custom(UNSERIALIZE_PASSTHRU, ce);
643 : }
644 :
645 : elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
646 :
647 : if (incomplete_class) {
648 : php_store_class_name(*rval, class_name, len2);
649 : }
650 : efree(class_name);
651 :
652 : return object_common2(UNSERIALIZE_PASSTHRU, elements);
653 : }
654 : #line 655 "ext/standard/var_unserializer.c"
655 0 : yy25:
656 0 : yych = *++YYCURSOR;
657 0 : if (yych <= ',') {
658 0 : if (yych != '+') goto yy18;
659 : } else {
660 0 : if (yych <= '-') goto yy26;
661 0 : if (yych <= '/') goto yy18;
662 0 : if (yych <= '9') goto yy27;
663 0 : goto yy18;
664 : }
665 0 : yy26:
666 0 : yych = *++YYCURSOR;
667 0 : if (yych <= '/') goto yy18;
668 0 : if (yych >= ':') goto yy18;
669 0 : yy27:
670 0 : ++YYCURSOR;
671 0 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
672 0 : yych = *YYCURSOR;
673 0 : if (yych <= '/') goto yy18;
674 0 : if (yych <= '9') goto yy27;
675 0 : if (yych >= ';') goto yy18;
676 0 : yych = *++YYCURSOR;
677 0 : if (yych != '"') goto yy18;
678 0 : ++YYCURSOR;
679 : #line 595 "ext/standard/var_unserializer.re"
680 : {
681 :
682 : INIT_PZVAL(*rval);
683 :
684 : return object_common2(UNSERIALIZE_PASSTHRU,
685 : object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
686 : }
687 : #line 688 "ext/standard/var_unserializer.c"
688 169 : yy32:
689 169 : yych = *++YYCURSOR;
690 169 : if (yych == '+') goto yy33;
691 169 : if (yych <= '/') goto yy18;
692 168 : if (yych <= '9') goto yy34;
693 0 : goto yy18;
694 0 : yy33:
695 0 : yych = *++YYCURSOR;
696 0 : if (yych <= '/') goto yy18;
697 0 : if (yych >= ':') goto yy18;
698 169 : yy34:
699 169 : ++YYCURSOR;
700 169 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
701 169 : yych = *YYCURSOR;
702 169 : if (yych <= '/') goto yy18;
703 168 : if (yych <= '9') goto yy34;
704 167 : if (yych >= ';') goto yy18;
705 167 : yych = *++YYCURSOR;
706 167 : if (yych != '{') goto yy18;
707 166 : ++YYCURSOR;
708 : #line 573 "ext/standard/var_unserializer.re"
709 : {
710 : long elements = parse_iv(start + 2);
711 : /* use iv() not uiv() in order to check data range */
712 : *p = YYCURSOR;
713 :
714 : if (elements < 0) {
715 : return 0;
716 : }
717 :
718 : INIT_PZVAL(*rval);
719 : Z_TYPE_PP(rval) = IS_ARRAY;
720 : ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
721 :
722 : zend_hash_init(Z_ARRVAL_PP(rval), elements + 1, NULL, ZVAL_PTR_DTOR, 0);
723 :
724 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
725 : return 0;
726 : }
727 :
728 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
729 : }
730 : #line 731 "ext/standard/var_unserializer.c"
731 1 : yy39:
732 1 : yych = *++YYCURSOR;
733 1 : if (yych == '+') goto yy40;
734 1 : if (yych <= '/') goto yy18;
735 1 : if (yych <= '9') goto yy41;
736 0 : goto yy18;
737 0 : yy40:
738 0 : yych = *++YYCURSOR;
739 0 : if (yych <= '/') goto yy18;
740 0 : if (yych >= ':') goto yy18;
741 3 : yy41:
742 3 : ++YYCURSOR;
743 3 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
744 3 : yych = *YYCURSOR;
745 3 : if (yych <= '/') goto yy18;
746 3 : if (yych <= '9') goto yy41;
747 1 : if (yych >= ';') goto yy18;
748 1 : yych = *++YYCURSOR;
749 1 : if (yych != '"') goto yy18;
750 1 : ++YYCURSOR;
751 : #line 544 "ext/standard/var_unserializer.re"
752 : {
753 : size_t len, maxlen;
754 : char *str;
755 :
756 : len = parse_uiv(start + 2);
757 : maxlen = max - YYCURSOR;
758 : if (maxlen < len) {
759 : *p = start + 2;
760 : return 0;
761 : }
762 :
763 : if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
764 : return 0;
765 : }
766 :
767 : if (*(YYCURSOR) != '"') {
768 : efree(str);
769 : *p = YYCURSOR;
770 : return 0;
771 : }
772 :
773 : YYCURSOR += 2;
774 : *p = YYCURSOR;
775 :
776 : INIT_PZVAL(*rval);
777 : ZVAL_STRINGL(*rval, str, len, 0);
778 : return 1;
779 : }
780 : #line 781 "ext/standard/var_unserializer.c"
781 533 : yy46:
782 533 : yych = *++YYCURSOR;
783 533 : if (yych == '+') goto yy47;
784 533 : if (yych <= '/') goto yy18;
785 532 : if (yych <= '9') goto yy48;
786 0 : goto yy18;
787 0 : yy47:
788 0 : yych = *++YYCURSOR;
789 0 : if (yych <= '/') goto yy18;
790 0 : if (yych >= ':') goto yy18;
791 607 : yy48:
792 607 : ++YYCURSOR;
793 607 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
794 607 : yych = *YYCURSOR;
795 607 : if (yych <= '/') goto yy18;
796 607 : if (yych <= '9') goto yy48;
797 532 : if (yych >= ';') goto yy18;
798 532 : yych = *++YYCURSOR;
799 532 : if (yych != '"') goto yy18;
800 532 : ++YYCURSOR;
801 : #line 516 "ext/standard/var_unserializer.re"
802 : {
803 : size_t len, maxlen;
804 : char *str;
805 :
806 : len = parse_uiv(start + 2);
807 : maxlen = max - YYCURSOR;
808 : if (maxlen < len) {
809 : *p = start + 2;
810 : return 0;
811 : }
812 :
813 : str = (char*)YYCURSOR;
814 :
815 : YYCURSOR += len;
816 :
817 : if (*(YYCURSOR) != '"') {
818 : *p = YYCURSOR;
819 : return 0;
820 : }
821 :
822 : YYCURSOR += 2;
823 : *p = YYCURSOR;
824 :
825 : INIT_PZVAL(*rval);
826 : ZVAL_STRINGL(*rval, str, len, 1);
827 : return 1;
828 : }
829 : #line 830 "ext/standard/var_unserializer.c"
830 51 : yy53:
831 51 : yych = *++YYCURSOR;
832 51 : if (yych <= '/') {
833 12 : if (yych <= ',') {
834 0 : if (yych == '+') goto yy57;
835 0 : goto yy18;
836 : } else {
837 12 : if (yych <= '-') goto yy55;
838 0 : if (yych <= '.') goto yy60;
839 0 : goto yy18;
840 : }
841 : } else {
842 39 : if (yych <= 'I') {
843 38 : if (yych <= '9') goto yy58;
844 1 : if (yych <= 'H') goto yy18;
845 1 : goto yy56;
846 : } else {
847 1 : if (yych != 'N') goto yy18;
848 : }
849 : }
850 1 : yych = *++YYCURSOR;
851 1 : if (yych == 'A') goto yy76;
852 0 : goto yy18;
853 12 : yy55:
854 12 : yych = *++YYCURSOR;
855 12 : if (yych <= '/') {
856 0 : if (yych == '.') goto yy60;
857 0 : goto yy18;
858 : } else {
859 12 : if (yych <= '9') goto yy58;
860 1 : if (yych != 'I') goto yy18;
861 : }
862 2 : yy56:
863 2 : yych = *++YYCURSOR;
864 2 : if (yych == 'N') goto yy72;
865 0 : goto yy18;
866 0 : yy57:
867 0 : yych = *++YYCURSOR;
868 0 : if (yych == '.') goto yy60;
869 0 : if (yych <= '/') goto yy18;
870 0 : if (yych >= ':') goto yy18;
871 150 : yy58:
872 150 : ++YYCURSOR;
873 150 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
874 150 : yych = *YYCURSOR;
875 150 : if (yych <= ':') {
876 141 : if (yych <= '.') {
877 39 : if (yych <= '-') goto yy18;
878 39 : goto yy70;
879 : } else {
880 102 : if (yych <= '/') goto yy18;
881 102 : if (yych <= '9') goto yy58;
882 0 : goto yy18;
883 : }
884 : } else {
885 9 : if (yych <= 'E') {
886 9 : if (yych <= ';') goto yy63;
887 0 : if (yych <= 'D') goto yy18;
888 0 : goto yy65;
889 : } else {
890 0 : if (yych == 'e') goto yy65;
891 0 : goto yy18;
892 : }
893 : }
894 0 : yy60:
895 0 : yych = *++YYCURSOR;
896 0 : if (yych <= '/') goto yy18;
897 0 : if (yych >= ':') goto yy18;
898 0 : yy61:
899 0 : ++YYCURSOR;
900 0 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
901 0 : yych = *YYCURSOR;
902 0 : if (yych <= ';') {
903 0 : if (yych <= '/') goto yy18;
904 0 : if (yych <= '9') goto yy61;
905 0 : if (yych <= ':') goto yy18;
906 : } else {
907 0 : if (yych <= 'E') {
908 0 : if (yych <= 'D') goto yy18;
909 0 : goto yy65;
910 : } else {
911 0 : if (yych == 'e') goto yy65;
912 0 : goto yy18;
913 : }
914 : }
915 48 : yy63:
916 48 : ++YYCURSOR;
917 : #line 506 "ext/standard/var_unserializer.re"
918 : {
919 : #if SIZEOF_LONG == 4
920 : use_double:
921 : #endif
922 : *p = YYCURSOR;
923 : INIT_PZVAL(*rval);
924 : ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
925 : return 1;
926 : }
927 : #line 928 "ext/standard/var_unserializer.c"
928 8 : yy65:
929 8 : yych = *++YYCURSOR;
930 8 : if (yych <= ',') {
931 0 : if (yych != '+') goto yy18;
932 : } else {
933 8 : if (yych <= '-') goto yy66;
934 0 : if (yych <= '/') goto yy18;
935 0 : if (yych <= '9') goto yy67;
936 0 : goto yy18;
937 : }
938 8 : yy66:
939 8 : yych = *++YYCURSOR;
940 8 : if (yych <= ',') {
941 0 : if (yych == '+') goto yy69;
942 0 : goto yy18;
943 : } else {
944 8 : if (yych <= '-') goto yy69;
945 8 : if (yych <= '/') goto yy18;
946 8 : if (yych >= ':') goto yy18;
947 : }
948 9 : yy67:
949 9 : ++YYCURSOR;
950 9 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
951 9 : yych = *YYCURSOR;
952 9 : if (yych <= '/') goto yy18;
953 9 : if (yych <= '9') goto yy67;
954 8 : if (yych == ';') goto yy63;
955 0 : goto yy18;
956 0 : yy69:
957 0 : yych = *++YYCURSOR;
958 0 : if (yych <= '/') goto yy18;
959 0 : if (yych <= '9') goto yy67;
960 0 : goto yy18;
961 1965 : yy70:
962 1965 : ++YYCURSOR;
963 1965 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
964 1965 : yych = *YYCURSOR;
965 1965 : if (yych <= ';') {
966 1957 : if (yych <= '/') goto yy18;
967 1957 : if (yych <= '9') goto yy70;
968 31 : if (yych <= ':') goto yy18;
969 31 : goto yy63;
970 : } else {
971 8 : if (yych <= 'E') {
972 8 : if (yych <= 'D') goto yy18;
973 8 : goto yy65;
974 : } else {
975 0 : if (yych == 'e') goto yy65;
976 0 : goto yy18;
977 : }
978 : }
979 2 : yy72:
980 2 : yych = *++YYCURSOR;
981 2 : if (yych != 'F') goto yy18;
982 3 : yy73:
983 3 : yych = *++YYCURSOR;
984 3 : if (yych != ';') goto yy18;
985 3 : ++YYCURSOR;
986 : #line 491 "ext/standard/var_unserializer.re"
987 : {
988 : *p = YYCURSOR;
989 : INIT_PZVAL(*rval);
990 :
991 : if (!strncmp(start + 2, "NAN", 3)) {
992 : ZVAL_DOUBLE(*rval, php_get_nan());
993 : } else if (!strncmp(start + 2, "INF", 3)) {
994 : ZVAL_DOUBLE(*rval, php_get_inf());
995 : } else if (!strncmp(start + 2, "-INF", 4)) {
996 : ZVAL_DOUBLE(*rval, -php_get_inf());
997 : }
998 :
999 : return 1;
1000 : }
1001 : #line 1002 "ext/standard/var_unserializer.c"
1002 1 : yy76:
1003 1 : yych = *++YYCURSOR;
1004 1 : if (yych == 'N') goto yy73;
1005 0 : goto yy18;
1006 648 : yy77:
1007 648 : yych = *++YYCURSOR;
1008 648 : if (yych <= ',') {
1009 6 : if (yych != '+') goto yy18;
1010 : } else {
1011 642 : if (yych <= '-') goto yy78;
1012 632 : if (yych <= '/') goto yy18;
1013 632 : if (yych <= '9') goto yy79;
1014 0 : goto yy18;
1015 : }
1016 10 : yy78:
1017 10 : yych = *++YYCURSOR;
1018 10 : if (yych <= '/') goto yy18;
1019 10 : if (yych >= ':') goto yy18;
1020 801 : yy79:
1021 801 : ++YYCURSOR;
1022 801 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1023 801 : yych = *YYCURSOR;
1024 801 : if (yych <= '/') goto yy18;
1025 794 : if (yych <= '9') goto yy79;
1026 635 : if (yych != ';') goto yy18;
1027 635 : ++YYCURSOR;
1028 : #line 464 "ext/standard/var_unserializer.re"
1029 : {
1030 : #if SIZEOF_LONG == 4
1031 : int digits = YYCURSOR - start - 3;
1032 :
1033 : if (start[2] == '-' || start[2] == '+') {
1034 : digits--;
1035 : }
1036 :
1037 : /* Use double for large long values that were serialized on a 64-bit system */
1038 : if (digits >= MAX_LENGTH_OF_LONG - 1) {
1039 : if (digits == MAX_LENGTH_OF_LONG - 1) {
1040 : int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
1041 :
1042 : if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
1043 : goto use_double;
1044 : }
1045 : } else {
1046 : goto use_double;
1047 : }
1048 : }
1049 : #endif
1050 : *p = YYCURSOR;
1051 : INIT_PZVAL(*rval);
1052 : ZVAL_LONG(*rval, parse_iv(start + 2));
1053 : return 1;
1054 : }
1055 : #line 1056 "ext/standard/var_unserializer.c"
1056 32 : yy83:
1057 32 : yych = *++YYCURSOR;
1058 32 : if (yych <= '/') goto yy18;
1059 32 : if (yych >= '2') goto yy18;
1060 32 : yych = *++YYCURSOR;
1061 32 : if (yych != ';') goto yy18;
1062 32 : ++YYCURSOR;
1063 : #line 457 "ext/standard/var_unserializer.re"
1064 : {
1065 : *p = YYCURSOR;
1066 : INIT_PZVAL(*rval);
1067 : ZVAL_BOOL(*rval, parse_iv(start + 2));
1068 : return 1;
1069 : }
1070 : #line 1071 "ext/standard/var_unserializer.c"
1071 53 : yy87:
1072 53 : ++YYCURSOR;
1073 : #line 450 "ext/standard/var_unserializer.re"
1074 : {
1075 : *p = YYCURSOR;
1076 : INIT_PZVAL(*rval);
1077 : ZVAL_NULL(*rval);
1078 : return 1;
1079 : }
1080 : #line 1081 "ext/standard/var_unserializer.c"
1081 10 : yy89:
1082 10 : yych = *++YYCURSOR;
1083 10 : if (yych <= ',') {
1084 0 : if (yych != '+') goto yy18;
1085 : } else {
1086 10 : if (yych <= '-') goto yy90;
1087 10 : if (yych <= '/') goto yy18;
1088 10 : if (yych <= '9') goto yy91;
1089 0 : goto yy18;
1090 : }
1091 0 : yy90:
1092 0 : yych = *++YYCURSOR;
1093 0 : if (yych <= '/') goto yy18;
1094 0 : if (yych >= ':') goto yy18;
1095 10 : yy91:
1096 10 : ++YYCURSOR;
1097 10 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1098 10 : yych = *YYCURSOR;
1099 10 : if (yych <= '/') goto yy18;
1100 10 : if (yych <= '9') goto yy91;
1101 10 : if (yych != ';') goto yy18;
1102 10 : ++YYCURSOR;
1103 : #line 427 "ext/standard/var_unserializer.re"
1104 : {
1105 : long id;
1106 :
1107 : *p = YYCURSOR;
1108 : if (!var_hash) return 0;
1109 :
1110 : id = parse_iv(start + 2) - 1;
1111 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1112 : return 0;
1113 : }
1114 :
1115 : if (*rval == *rval_ref) return 0;
1116 :
1117 : if (*rval != NULL) {
1118 : zval_ptr_dtor(rval);
1119 : }
1120 : *rval = *rval_ref;
1121 : (*rval)->refcount++;
1122 : (*rval)->is_ref = 0;
1123 :
1124 : return 1;
1125 : }
1126 : #line 1127 "ext/standard/var_unserializer.c"
1127 89 : yy95:
1128 89 : yych = *++YYCURSOR;
1129 89 : if (yych <= ',') {
1130 2 : if (yych != '+') goto yy18;
1131 : } else {
1132 87 : if (yych <= '-') goto yy96;
1133 87 : if (yych <= '/') goto yy18;
1134 87 : if (yych <= '9') goto yy97;
1135 0 : goto yy18;
1136 : }
1137 0 : yy96:
1138 0 : yych = *++YYCURSOR;
1139 0 : if (yych <= '/') goto yy18;
1140 0 : if (yych >= ':') goto yy18;
1141 87 : yy97:
1142 87 : ++YYCURSOR;
1143 87 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1144 87 : yych = *YYCURSOR;
1145 87 : if (yych <= '/') goto yy18;
1146 85 : if (yych <= '9') goto yy97;
1147 85 : if (yych != ';') goto yy18;
1148 85 : ++YYCURSOR;
1149 : #line 406 "ext/standard/var_unserializer.re"
1150 : {
1151 : long id;
1152 :
1153 : *p = YYCURSOR;
1154 : if (!var_hash) return 0;
1155 :
1156 : id = parse_iv(start + 2) - 1;
1157 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1158 : return 0;
1159 : }
1160 :
1161 : if (*rval != NULL) {
1162 : zval_ptr_dtor(rval);
1163 : }
1164 : *rval = *rval_ref;
1165 : (*rval)->refcount++;
1166 : (*rval)->is_ref = 1;
1167 :
1168 : return 1;
1169 : }
1170 : #line 1171 "ext/standard/var_unserializer.c"
1171 : }
1172 : #line 723 "ext/standard/var_unserializer.re"
1173 :
1174 :
1175 : return 0;
1176 : }
|