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