1 : /* Generated by re2c 0.13.5 on Wed Apr 8 09:34:35 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 278451 2009-04-08 18:10:46Z rasmus $ */
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 : Z_ADDREF_PP(rval);
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 : datalen = parse_iv2((*p) + 2, p);
328 :
329 : (*p) += 2;
330 :
331 : if (datalen < 0 || (*p) + datalen >= max) {
332 : zend_error(E_WARNING, "Insufficient data for unserializing - %ld required, %ld present", datalen, (long)(max - (*p)));
333 : return 0;
334 : }
335 :
336 : if (ce->unserialize == NULL) {
337 : zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
338 : object_init_ex(*rval, ce);
339 : } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
340 : return 0;
341 : }
342 :
343 : (*p) += datalen;
344 :
345 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
346 : }
347 :
348 : static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
349 : {
350 : long elements;
351 :
352 : elements = parse_iv2((*p) + 2, p);
353 :
354 : (*p) += 2;
355 :
356 : object_init_ex(*rval, ce);
357 : return elements;
358 : }
359 :
360 : static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
361 : {
362 : zval *retval_ptr = NULL;
363 : zval fname;
364 :
365 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements)) {
366 : return 0;
367 : }
368 :
369 : if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
370 : zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
371 : INIT_PZVAL(&fname);
372 : ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
373 : call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
374 : }
375 :
376 : if (retval_ptr)
377 : zval_ptr_dtor(&retval_ptr);
378 :
379 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
380 :
381 : }
382 :
383 : PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
384 : {
385 : const unsigned char *cursor, *limit, *marker, *start;
386 : zval **rval_ref;
387 :
388 : limit = cursor = *p;
389 :
390 : if (var_hash && cursor[0] != 'R') {
391 : var_push(var_hash, rval);
392 : }
393 :
394 : start = cursor;
395 :
396 :
397 :
398 :
399 : #line 400 "ext/standard/var_unserializer.c"
400 : {
401 : YYCTYPE yych;
402 : static const unsigned char yybm[] = {
403 : 0, 0, 0, 0, 0, 0, 0, 0,
404 : 0, 0, 0, 0, 0, 0, 0, 0,
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 : 128, 128, 128, 128, 128, 128, 128, 128,
410 : 128, 128, 0, 0, 0, 0, 0, 0,
411 : 0, 0, 0, 0, 0, 0, 0, 0,
412 : 0, 0, 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 : };
436 :
437 2161 : if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
438 2161 : yych = *YYCURSOR;
439 2161 : switch (yych) {
440 : case 'C':
441 177 : case 'O': goto yy13;
442 61 : case 'N': goto yy5;
443 92 : case 'R': goto yy2;
444 1 : case 'S': goto yy10;
445 240 : case 'a': goto yy11;
446 33 : case 'b': goto yy6;
447 53 : case 'd': goto yy8;
448 755 : case 'i': goto yy7;
449 0 : case 'o': goto yy12;
450 25 : case 'r': goto yy4;
451 683 : case 's': goto yy9;
452 0 : case '}': goto yy14;
453 41 : default: goto yy16;
454 : }
455 92 : yy2:
456 92 : yych = *(YYMARKER = ++YYCURSOR);
457 92 : if (yych == ':') goto yy95;
458 103 : yy3:
459 : #line 722 "ext/standard/var_unserializer.re"
460 : { return 0; }
461 : #line 462 "ext/standard/var_unserializer.c"
462 25 : yy4:
463 25 : yych = *(YYMARKER = ++YYCURSOR);
464 25 : if (yych == ':') goto yy89;
465 1 : goto yy3;
466 61 : yy5:
467 61 : yych = *++YYCURSOR;
468 61 : if (yych == ';') goto yy87;
469 0 : goto yy3;
470 33 : yy6:
471 33 : yych = *(YYMARKER = ++YYCURSOR);
472 33 : if (yych == ':') goto yy83;
473 0 : goto yy3;
474 755 : yy7:
475 755 : yych = *(YYMARKER = ++YYCURSOR);
476 755 : if (yych == ':') goto yy77;
477 12 : goto yy3;
478 53 : yy8:
479 53 : yych = *(YYMARKER = ++YYCURSOR);
480 53 : if (yych == ':') goto yy53;
481 2 : goto yy3;
482 683 : yy9:
483 683 : yych = *(YYMARKER = ++YYCURSOR);
484 683 : if (yych == ':') goto yy46;
485 1 : goto yy3;
486 1 : yy10:
487 1 : yych = *(YYMARKER = ++YYCURSOR);
488 1 : if (yych == ':') goto yy39;
489 0 : goto yy3;
490 240 : yy11:
491 240 : yych = *(YYMARKER = ++YYCURSOR);
492 240 : if (yych == ':') goto yy32;
493 23 : goto yy3;
494 0 : yy12:
495 0 : yych = *(YYMARKER = ++YYCURSOR);
496 0 : if (yych == ':') goto yy25;
497 0 : goto yy3;
498 177 : yy13:
499 177 : yych = *(YYMARKER = ++YYCURSOR);
500 177 : if (yych == ':') goto yy17;
501 0 : goto yy3;
502 0 : yy14:
503 0 : ++YYCURSOR;
504 : #line 716 "ext/standard/var_unserializer.re"
505 : {
506 : /* this is the case where we have less data than planned */
507 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
508 : return 0; /* not sure if it should be 0 or 1 here? */
509 : }
510 : #line 511 "ext/standard/var_unserializer.c"
511 41 : yy16:
512 41 : yych = *++YYCURSOR;
513 41 : goto yy3;
514 177 : yy17:
515 177 : yych = *++YYCURSOR;
516 177 : if (yybm[0+yych] & 128) {
517 177 : goto yy20;
518 : }
519 0 : if (yych == '+') goto yy19;
520 21 : yy18:
521 21 : YYCURSOR = YYMARKER;
522 21 : goto yy3;
523 0 : yy19:
524 0 : yych = *++YYCURSOR;
525 0 : if (yybm[0+yych] & 128) {
526 0 : goto yy20;
527 : }
528 0 : goto yy18;
529 198 : yy20:
530 198 : ++YYCURSOR;
531 198 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
532 198 : yych = *YYCURSOR;
533 198 : if (yybm[0+yych] & 128) {
534 21 : goto yy20;
535 : }
536 177 : if (yych != ':') goto yy18;
537 177 : yych = *++YYCURSOR;
538 177 : if (yych != '"') goto yy18;
539 177 : ++YYCURSOR;
540 : #line 599 "ext/standard/var_unserializer.re"
541 : {
542 : size_t len, len2, len3, maxlen;
543 : long elements;
544 : char *class_name;
545 : zend_class_entry *ce;
546 : zend_class_entry **pce;
547 : int incomplete_class = 0;
548 :
549 : int custom_object = 0;
550 :
551 : zval *user_func;
552 : zval *retval_ptr;
553 : zval **args[1];
554 : zval *arg_func_name;
555 :
556 : if (*start == 'C') {
557 : custom_object = 1;
558 : }
559 :
560 : INIT_PZVAL(*rval);
561 : len2 = len = parse_uiv(start + 2);
562 : maxlen = max - YYCURSOR;
563 : if (maxlen < len || len == 0) {
564 : *p = start + 2;
565 : return 0;
566 : }
567 :
568 : class_name = (char*)YYCURSOR;
569 :
570 : YYCURSOR += len;
571 :
572 : if (*(YYCURSOR) != '"') {
573 : *p = YYCURSOR;
574 : return 0;
575 : }
576 : if (*(YYCURSOR+1) != ':') {
577 : *p = YYCURSOR+1;
578 : return 0;
579 : }
580 :
581 : 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\\");
582 : if (len3 != len)
583 : {
584 : *p = YYCURSOR + len3 - len;
585 : return 0;
586 : }
587 :
588 : class_name = estrndup(class_name, len);
589 :
590 : do {
591 : /* Try to find class directly */
592 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
593 : ce = *pce;
594 : break;
595 : }
596 :
597 : /* Check for unserialize callback */
598 : if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
599 : incomplete_class = 1;
600 : ce = PHP_IC_ENTRY;
601 : break;
602 : }
603 :
604 : /* Call unserialize callback */
605 : MAKE_STD_ZVAL(user_func);
606 : ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
607 : args[0] = &arg_func_name;
608 : MAKE_STD_ZVAL(arg_func_name);
609 : ZVAL_STRING(arg_func_name, class_name, 1);
610 : if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
611 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
612 : incomplete_class = 1;
613 : ce = PHP_IC_ENTRY;
614 : zval_ptr_dtor(&user_func);
615 : zval_ptr_dtor(&arg_func_name);
616 : break;
617 : }
618 : if (retval_ptr) {
619 : zval_ptr_dtor(&retval_ptr);
620 : }
621 :
622 : /* The callback function may have defined the class */
623 : if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
624 : ce = *pce;
625 : } else {
626 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
627 : incomplete_class = 1;
628 : ce = PHP_IC_ENTRY;
629 : }
630 :
631 : zval_ptr_dtor(&user_func);
632 : zval_ptr_dtor(&arg_func_name);
633 : break;
634 : } while (1);
635 :
636 : *p = YYCURSOR;
637 :
638 : if (custom_object) {
639 : int ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
640 :
641 : if (ret && incomplete_class) {
642 : php_store_class_name(*rval, class_name, len2);
643 : }
644 : efree(class_name);
645 : return ret;
646 : }
647 :
648 : elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
649 :
650 : if (incomplete_class) {
651 : php_store_class_name(*rval, class_name, len2);
652 : }
653 : efree(class_name);
654 :
655 : return object_common2(UNSERIALIZE_PASSTHRU, elements);
656 : }
657 : #line 658 "ext/standard/var_unserializer.c"
658 0 : yy25:
659 0 : yych = *++YYCURSOR;
660 0 : if (yych <= ',') {
661 0 : if (yych != '+') goto yy18;
662 : } else {
663 0 : if (yych <= '-') goto yy26;
664 0 : if (yych <= '/') goto yy18;
665 0 : if (yych <= '9') goto yy27;
666 0 : goto yy18;
667 : }
668 0 : yy26:
669 0 : yych = *++YYCURSOR;
670 0 : if (yych <= '/') goto yy18;
671 0 : if (yych >= ':') goto yy18;
672 0 : yy27:
673 0 : ++YYCURSOR;
674 0 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
675 0 : yych = *YYCURSOR;
676 0 : if (yych <= '/') goto yy18;
677 0 : if (yych <= '9') goto yy27;
678 0 : if (yych >= ';') goto yy18;
679 0 : yych = *++YYCURSOR;
680 0 : if (yych != '"') goto yy18;
681 0 : ++YYCURSOR;
682 : #line 591 "ext/standard/var_unserializer.re"
683 : {
684 :
685 : INIT_PZVAL(*rval);
686 :
687 : return object_common2(UNSERIALIZE_PASSTHRU,
688 : object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
689 : }
690 : #line 691 "ext/standard/var_unserializer.c"
691 217 : yy32:
692 217 : yych = *++YYCURSOR;
693 217 : if (yych == '+') goto yy33;
694 217 : if (yych <= '/') goto yy18;
695 216 : if (yych <= '9') goto yy34;
696 0 : goto yy18;
697 0 : yy33:
698 0 : yych = *++YYCURSOR;
699 0 : if (yych <= '/') goto yy18;
700 0 : if (yych >= ':') goto yy18;
701 217 : yy34:
702 217 : ++YYCURSOR;
703 217 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
704 217 : yych = *YYCURSOR;
705 217 : if (yych <= '/') goto yy18;
706 216 : if (yych <= '9') goto yy34;
707 215 : if (yych >= ';') goto yy18;
708 215 : yych = *++YYCURSOR;
709 215 : if (yych != '{') goto yy18;
710 214 : ++YYCURSOR;
711 : #line 571 "ext/standard/var_unserializer.re"
712 : {
713 : long elements = parse_iv(start + 2);
714 : /* use iv() not uiv() in order to check data range */
715 : *p = YYCURSOR;
716 :
717 : if (elements < 0) {
718 : return 0;
719 : }
720 :
721 : INIT_PZVAL(*rval);
722 :
723 : array_init_size(*rval, elements);
724 :
725 : if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) {
726 : return 0;
727 : }
728 :
729 : return finish_nested_data(UNSERIALIZE_PASSTHRU);
730 : }
731 : #line 732 "ext/standard/var_unserializer.c"
732 1 : yy39:
733 1 : yych = *++YYCURSOR;
734 1 : if (yych == '+') goto yy40;
735 1 : if (yych <= '/') goto yy18;
736 1 : if (yych <= '9') goto yy41;
737 0 : goto yy18;
738 0 : yy40:
739 0 : yych = *++YYCURSOR;
740 0 : if (yych <= '/') goto yy18;
741 0 : if (yych >= ':') goto yy18;
742 3 : yy41:
743 3 : ++YYCURSOR;
744 3 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
745 3 : yych = *YYCURSOR;
746 3 : if (yych <= '/') goto yy18;
747 3 : if (yych <= '9') goto yy41;
748 1 : if (yych >= ';') goto yy18;
749 1 : yych = *++YYCURSOR;
750 1 : if (yych != '"') goto yy18;
751 1 : ++YYCURSOR;
752 : #line 542 "ext/standard/var_unserializer.re"
753 : {
754 : size_t len, maxlen;
755 : char *str;
756 :
757 : len = parse_uiv(start + 2);
758 : maxlen = max - YYCURSOR;
759 : if (maxlen < len) {
760 : *p = start + 2;
761 : return 0;
762 : }
763 :
764 : if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
765 : return 0;
766 : }
767 :
768 : if (*(YYCURSOR) != '"') {
769 : efree(str);
770 : *p = YYCURSOR;
771 : return 0;
772 : }
773 :
774 : YYCURSOR += 2;
775 : *p = YYCURSOR;
776 :
777 : INIT_PZVAL(*rval);
778 : ZVAL_STRINGL(*rval, str, len, 0);
779 : return 1;
780 : }
781 : #line 782 "ext/standard/var_unserializer.c"
782 682 : yy46:
783 682 : yych = *++YYCURSOR;
784 682 : if (yych == '+') goto yy47;
785 682 : if (yych <= '/') goto yy18;
786 681 : if (yych <= '9') goto yy48;
787 0 : goto yy18;
788 0 : yy47:
789 0 : yych = *++YYCURSOR;
790 0 : if (yych <= '/') goto yy18;
791 0 : if (yych >= ':') goto yy18;
792 764 : yy48:
793 764 : ++YYCURSOR;
794 764 : if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
795 764 : yych = *YYCURSOR;
796 764 : if (yych <= '/') goto yy18;
797 764 : if (yych <= '9') goto yy48;
798 681 : if (yych >= ';') goto yy18;
799 681 : yych = *++YYCURSOR;
800 681 : if (yych != '"') goto yy18;
801 681 : ++YYCURSOR;
802 : #line 514 "ext/standard/var_unserializer.re"
803 : {
804 : size_t len, maxlen;
805 : char *str;
806 :
807 : len = parse_uiv(start + 2);
808 : maxlen = max - YYCURSOR;
809 : if (maxlen < len) {
810 : *p = start + 2;
811 : return 0;
812 : }
813 :
814 : str = (char*)YYCURSOR;
815 :
816 : YYCURSOR += len;
817 :
818 : if (*(YYCURSOR) != '"') {
819 : *p = YYCURSOR;
820 : return 0;
821 : }
822 :
823 : YYCURSOR += 2;
824 : *p = YYCURSOR;
825 :
826 : INIT_PZVAL(*rval);
827 : ZVAL_STRINGL(*rval, str, len, 1);
828 : return 1;
829 : }
830 : #line 831 "ext/standard/var_unserializer.c"
831 51 : yy53:
832 51 : yych = *++YYCURSOR;
833 51 : if (yych <= '/') {
834 12 : if (yych <= ',') {
835 0 : if (yych == '+') goto yy57;
836 0 : goto yy18;
837 : } else {
838 12 : if (yych <= '-') goto yy55;
839 0 : if (yych <= '.') goto yy60;
840 0 : goto yy18;
841 : }
842 : } else {
843 39 : if (yych <= 'I') {
844 38 : if (yych <= '9') goto yy58;
845 1 : if (yych <= 'H') goto yy18;
846 1 : goto yy56;
847 : } else {
848 1 : if (yych != 'N') goto yy18;
849 : }
850 : }
851 1 : yych = *++YYCURSOR;
852 1 : if (yych == 'A') goto yy76;
853 0 : goto yy18;
854 12 : yy55:
855 12 : yych = *++YYCURSOR;
856 12 : if (yych <= '/') {
857 0 : if (yych == '.') goto yy60;
858 0 : goto yy18;
859 : } else {
860 12 : if (yych <= '9') goto yy58;
861 1 : if (yych != 'I') goto yy18;
862 : }
863 2 : yy56:
864 2 : yych = *++YYCURSOR;
865 2 : if (yych == 'N') goto yy72;
866 0 : goto yy18;
867 0 : yy57:
868 0 : yych = *++YYCURSOR;
869 0 : if (yych == '.') goto yy60;
870 0 : if (yych <= '/') goto yy18;
871 0 : if (yych >= ':') goto yy18;
872 150 : yy58:
873 150 : ++YYCURSOR;
874 150 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
875 150 : yych = *YYCURSOR;
876 150 : if (yych <= ':') {
877 141 : if (yych <= '.') {
878 39 : if (yych <= '-') goto yy18;
879 39 : goto yy70;
880 : } else {
881 102 : if (yych <= '/') goto yy18;
882 102 : if (yych <= '9') goto yy58;
883 0 : goto yy18;
884 : }
885 : } else {
886 9 : if (yych <= 'E') {
887 9 : if (yych <= ';') goto yy63;
888 0 : if (yych <= 'D') goto yy18;
889 0 : goto yy65;
890 : } else {
891 0 : if (yych == 'e') goto yy65;
892 0 : goto yy18;
893 : }
894 : }
895 0 : yy60:
896 0 : yych = *++YYCURSOR;
897 0 : if (yych <= '/') goto yy18;
898 0 : if (yych >= ':') goto yy18;
899 0 : yy61:
900 0 : ++YYCURSOR;
901 0 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
902 0 : yych = *YYCURSOR;
903 0 : if (yych <= ';') {
904 0 : if (yych <= '/') goto yy18;
905 0 : if (yych <= '9') goto yy61;
906 0 : if (yych <= ':') goto yy18;
907 : } else {
908 0 : if (yych <= 'E') {
909 0 : if (yych <= 'D') goto yy18;
910 0 : goto yy65;
911 : } else {
912 0 : if (yych == 'e') goto yy65;
913 0 : goto yy18;
914 : }
915 : }
916 48 : yy63:
917 48 : ++YYCURSOR;
918 : #line 504 "ext/standard/var_unserializer.re"
919 : {
920 : #if SIZEOF_LONG == 4
921 : use_double:
922 : #endif
923 : *p = YYCURSOR;
924 : INIT_PZVAL(*rval);
925 : ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
926 : return 1;
927 : }
928 : #line 929 "ext/standard/var_unserializer.c"
929 8 : yy65:
930 8 : yych = *++YYCURSOR;
931 8 : if (yych <= ',') {
932 0 : if (yych != '+') goto yy18;
933 : } else {
934 8 : if (yych <= '-') goto yy66;
935 0 : if (yych <= '/') goto yy18;
936 0 : if (yych <= '9') goto yy67;
937 0 : goto yy18;
938 : }
939 8 : yy66:
940 8 : yych = *++YYCURSOR;
941 8 : if (yych <= ',') {
942 0 : if (yych == '+') goto yy69;
943 0 : goto yy18;
944 : } else {
945 8 : if (yych <= '-') goto yy69;
946 8 : if (yych <= '/') goto yy18;
947 8 : if (yych >= ':') goto yy18;
948 : }
949 9 : yy67:
950 9 : ++YYCURSOR;
951 9 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
952 9 : yych = *YYCURSOR;
953 9 : if (yych <= '/') goto yy18;
954 9 : if (yych <= '9') goto yy67;
955 8 : if (yych == ';') goto yy63;
956 0 : goto yy18;
957 0 : yy69:
958 0 : yych = *++YYCURSOR;
959 0 : if (yych <= '/') goto yy18;
960 0 : if (yych <= '9') goto yy67;
961 0 : goto yy18;
962 1965 : yy70:
963 1965 : ++YYCURSOR;
964 1965 : if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
965 1965 : yych = *YYCURSOR;
966 1965 : if (yych <= ';') {
967 1957 : if (yych <= '/') goto yy18;
968 1957 : if (yych <= '9') goto yy70;
969 31 : if (yych <= ':') goto yy18;
970 31 : goto yy63;
971 : } else {
972 8 : if (yych <= 'E') {
973 8 : if (yych <= 'D') goto yy18;
974 8 : goto yy65;
975 : } else {
976 0 : if (yych == 'e') goto yy65;
977 0 : goto yy18;
978 : }
979 : }
980 2 : yy72:
981 2 : yych = *++YYCURSOR;
982 2 : if (yych != 'F') goto yy18;
983 3 : yy73:
984 3 : yych = *++YYCURSOR;
985 3 : if (yych != ';') goto yy18;
986 3 : ++YYCURSOR;
987 : #line 489 "ext/standard/var_unserializer.re"
988 : {
989 : *p = YYCURSOR;
990 : INIT_PZVAL(*rval);
991 :
992 : if (!strncmp(start + 2, "NAN", 3)) {
993 : ZVAL_DOUBLE(*rval, php_get_nan());
994 : } else if (!strncmp(start + 2, "INF", 3)) {
995 : ZVAL_DOUBLE(*rval, php_get_inf());
996 : } else if (!strncmp(start + 2, "-INF", 4)) {
997 : ZVAL_DOUBLE(*rval, -php_get_inf());
998 : }
999 :
1000 : return 1;
1001 : }
1002 : #line 1003 "ext/standard/var_unserializer.c"
1003 1 : yy76:
1004 1 : yych = *++YYCURSOR;
1005 1 : if (yych == 'N') goto yy73;
1006 0 : goto yy18;
1007 743 : yy77:
1008 743 : yych = *++YYCURSOR;
1009 743 : if (yych <= ',') {
1010 6 : if (yych != '+') goto yy18;
1011 : } else {
1012 737 : if (yych <= '-') goto yy78;
1013 727 : if (yych <= '/') goto yy18;
1014 727 : if (yych <= '9') goto yy79;
1015 0 : goto yy18;
1016 : }
1017 10 : yy78:
1018 10 : yych = *++YYCURSOR;
1019 10 : if (yych <= '/') goto yy18;
1020 10 : if (yych >= ':') goto yy18;
1021 913 : yy79:
1022 913 : ++YYCURSOR;
1023 913 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1024 913 : yych = *YYCURSOR;
1025 913 : if (yych <= '/') goto yy18;
1026 906 : if (yych <= '9') goto yy79;
1027 730 : if (yych != ';') goto yy18;
1028 730 : ++YYCURSOR;
1029 : #line 462 "ext/standard/var_unserializer.re"
1030 : {
1031 : #if SIZEOF_LONG == 4
1032 : int digits = YYCURSOR - start - 3;
1033 :
1034 : if (start[2] == '-' || start[2] == '+') {
1035 : digits--;
1036 : }
1037 :
1038 : /* Use double for large long values that were serialized on a 64-bit system */
1039 : if (digits >= MAX_LENGTH_OF_LONG - 1) {
1040 : if (digits == MAX_LENGTH_OF_LONG - 1) {
1041 : int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
1042 :
1043 : if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
1044 : goto use_double;
1045 : }
1046 : } else {
1047 : goto use_double;
1048 : }
1049 : }
1050 : #endif
1051 : *p = YYCURSOR;
1052 : INIT_PZVAL(*rval);
1053 : ZVAL_LONG(*rval, parse_iv(start + 2));
1054 : return 1;
1055 : }
1056 : #line 1057 "ext/standard/var_unserializer.c"
1057 33 : yy83:
1058 33 : yych = *++YYCURSOR;
1059 33 : if (yych <= '/') goto yy18;
1060 33 : if (yych >= '2') goto yy18;
1061 33 : yych = *++YYCURSOR;
1062 33 : if (yych != ';') goto yy18;
1063 33 : ++YYCURSOR;
1064 : #line 455 "ext/standard/var_unserializer.re"
1065 : {
1066 : *p = YYCURSOR;
1067 : INIT_PZVAL(*rval);
1068 : ZVAL_BOOL(*rval, parse_iv(start + 2));
1069 : return 1;
1070 : }
1071 : #line 1072 "ext/standard/var_unserializer.c"
1072 61 : yy87:
1073 61 : ++YYCURSOR;
1074 : #line 448 "ext/standard/var_unserializer.re"
1075 : {
1076 : *p = YYCURSOR;
1077 : INIT_PZVAL(*rval);
1078 : ZVAL_NULL(*rval);
1079 : return 1;
1080 : }
1081 : #line 1082 "ext/standard/var_unserializer.c"
1082 24 : yy89:
1083 24 : yych = *++YYCURSOR;
1084 24 : if (yych <= ',') {
1085 0 : if (yych != '+') goto yy18;
1086 : } else {
1087 24 : if (yych <= '-') goto yy90;
1088 24 : if (yych <= '/') goto yy18;
1089 24 : if (yych <= '9') goto yy91;
1090 0 : goto yy18;
1091 : }
1092 0 : yy90:
1093 0 : yych = *++YYCURSOR;
1094 0 : if (yych <= '/') goto yy18;
1095 0 : if (yych >= ':') goto yy18;
1096 24 : yy91:
1097 24 : ++YYCURSOR;
1098 24 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1099 24 : yych = *YYCURSOR;
1100 24 : if (yych <= '/') goto yy18;
1101 24 : if (yych <= '9') goto yy91;
1102 24 : if (yych != ';') goto yy18;
1103 24 : ++YYCURSOR;
1104 : #line 425 "ext/standard/var_unserializer.re"
1105 : {
1106 : long id;
1107 :
1108 : *p = YYCURSOR;
1109 : if (!var_hash) return 0;
1110 :
1111 : id = parse_iv(start + 2) - 1;
1112 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1113 : return 0;
1114 : }
1115 :
1116 : if (*rval == *rval_ref) return 0;
1117 :
1118 : if (*rval != NULL) {
1119 : zval_ptr_dtor(rval);
1120 : }
1121 : *rval = *rval_ref;
1122 : Z_ADDREF_PP(rval);
1123 : Z_UNSET_ISREF_PP(rval);
1124 :
1125 : return 1;
1126 : }
1127 : #line 1128 "ext/standard/var_unserializer.c"
1128 90 : yy95:
1129 90 : yych = *++YYCURSOR;
1130 90 : if (yych <= ',') {
1131 2 : if (yych != '+') goto yy18;
1132 : } else {
1133 88 : if (yych <= '-') goto yy96;
1134 88 : if (yych <= '/') goto yy18;
1135 88 : if (yych <= '9') goto yy97;
1136 0 : goto yy18;
1137 : }
1138 0 : yy96:
1139 0 : yych = *++YYCURSOR;
1140 0 : if (yych <= '/') goto yy18;
1141 0 : if (yych >= ':') goto yy18;
1142 88 : yy97:
1143 88 : ++YYCURSOR;
1144 88 : if (YYLIMIT <= YYCURSOR) YYFILL(1);
1145 88 : yych = *YYCURSOR;
1146 88 : if (yych <= '/') goto yy18;
1147 86 : if (yych <= '9') goto yy97;
1148 86 : if (yych != ';') goto yy18;
1149 86 : ++YYCURSOR;
1150 : #line 404 "ext/standard/var_unserializer.re"
1151 : {
1152 : long id;
1153 :
1154 : *p = YYCURSOR;
1155 : if (!var_hash) return 0;
1156 :
1157 : id = parse_iv(start + 2) - 1;
1158 : if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
1159 : return 0;
1160 : }
1161 :
1162 : if (*rval != NULL) {
1163 : zval_ptr_dtor(rval);
1164 : }
1165 : *rval = *rval_ref;
1166 : Z_ADDREF_PP(rval);
1167 : Z_SET_ISREF_PP(rval);
1168 :
1169 : return 1;
1170 : }
1171 : #line 1172 "ext/standard/var_unserializer.c"
1172 : }
1173 : #line 724 "ext/standard/var_unserializer.re"
1174 :
1175 :
1176 : return 0;
1177 : }
|