1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Jani Lehtimäki <jkl@njet.net> |
16 : | Thies C. Arntzen <thies@thieso.net> |
17 : | Sascha Schumann <sascha@schumann.cx> |
18 : +----------------------------------------------------------------------+
19 : */
20 :
21 : /* $Id: var.c 287123 2009-08-11 22:46:07Z stas $ */
22 :
23 : /* {{{ includes
24 : */
25 : #include <stdio.h>
26 : #include <stdlib.h>
27 : #include <errno.h>
28 : #include "php.h"
29 : #include "php_string.h"
30 : #include "php_var.h"
31 : #include "php_smart_str.h"
32 : #include "basic_functions.h"
33 : #include "php_incomplete_class.h"
34 :
35 : #define COMMON (Z_ISREF_PP(struc) ? "&" : "")
36 : /* }}} */
37 :
38 : static void php_var_dump_unicode(UChar *ustr, int length, int verbose, char *quote, int escape TSRMLS_DC) /* {{{ */
39 60705 : {
40 : UChar32 c;
41 : int i;
42 60705 : UErrorCode status = U_ZERO_ERROR;
43 : int clen;
44 60705 : char *out = NULL;
45 :
46 60705 : if (length == 0) {
47 3135 : ZEND_PUTS(quote);
48 3135 : ZEND_PUTS(quote);
49 3135 : return;
50 : }
51 :
52 57570 : zend_unicode_to_string_ex(ZEND_U_CONVERTER(UG(output_encoding_conv)), &out, &clen, ustr, length, &status);
53 57570 : if (U_FAILURE(status)) {
54 0 : php_printf("problem converting string from Unicode: %s\n", u_errorName(status));
55 0 : efree(out);
56 0 : return;
57 : }
58 :
59 57570 : ZEND_PUTS(quote);
60 57570 : if (escape) {
61 : char *str;
62 : int str_len;
63 :
64 91 : str = php_addcslashes(out, clen, &str_len, 0, "'\\", 2 TSRMLS_CC);
65 91 : PHPWRITE(str, str_len);
66 91 : efree(str);
67 : } else {
68 57479 : PHPWRITE(out, clen);
69 : }
70 57570 : ZEND_PUTS(quote);
71 57570 : if (verbose) {
72 158 : ZEND_PUTS(" {");
73 : /* output the code points (not code units) */
74 158 : if (length>=0) {
75 : /* s is not NUL-terminated */
76 990 : for (i = 0; i < length; /* U16_NEXT post-increments */) {
77 674 : U16_NEXT(ustr, i, length, c);
78 674 : php_printf(" %04x", c);
79 : }
80 : } else {
81 : /* s is NUL-terminated */
82 0 : for (i = 0; /* condition in loop body */; /* U16_NEXT post-increments */) {
83 0 : U16_NEXT(ustr, i, length, c);
84 0 : if (c == 0) {
85 0 : break;
86 : }
87 0 : php_printf(" %04x", c);
88 0 : }
89 : }
90 158 : php_printf(" }");
91 : }
92 57570 : efree(out);
93 : }
94 : /* }}} */
95 :
96 : static int php_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
97 61394 : {
98 : int level;
99 : int verbose;
100 :
101 61394 : level = va_arg(args, int);
102 61394 : verbose = va_arg(args, int);
103 :
104 61394 : if (hash_key->nKeyLength == 0) { /* numeric key */
105 44528 : php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
106 : } else { /* string key */
107 16866 : php_printf("%*c[", level + 1, ' ');
108 16866 : if (hash_key->type == IS_STRING) {
109 6324 : php_printf("\"");
110 6324 : PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
111 6324 : php_printf("\"");
112 10542 : } else if (hash_key->type == IS_UNICODE) {
113 10542 : php_printf("u");
114 10542 : php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, verbose, "\"", 0 TSRMLS_CC);
115 : }
116 16866 : php_printf("]=>\n");
117 : }
118 61394 : php_var_dump(zv, level + 2, verbose TSRMLS_CC);
119 61394 : return 0;
120 : }
121 : /* }}} */
122 :
123 : static int php_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
124 6330 : {
125 : int level;
126 : zstr prop_name, class_name;
127 : int verbose;
128 :
129 6330 : level = va_arg(args, int);
130 6330 : verbose = va_arg(args, int);
131 :
132 6330 : if (hash_key->nKeyLength == 0) { /* numeric key */
133 99 : php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
134 : } else { /* string key */
135 6231 : int is_unicode = hash_key->type == IS_UNICODE;
136 :
137 6231 : int unmangle = zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength-1, &class_name, &prop_name);
138 6231 : php_printf("%*c[", level + 1, ' ');
139 :
140 7218 : if (class_name.s && unmangle == SUCCESS) {
141 987 : if (class_name.s[0] == '*') {
142 324 : php_printf("%s\"%R\":protected", is_unicode ? "u" : "", hash_key->type, prop_name);
143 : } else {
144 663 : php_printf("%s\"%R\":%s\"%R\":private", is_unicode ? "u" : "", hash_key->type, prop_name, is_unicode ? "u" : "", hash_key->type, class_name);
145 : }
146 : } else {
147 5244 : if (is_unicode) {
148 5209 : php_printf("u");
149 5209 : php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, verbose, "\"", 0 TSRMLS_CC);
150 : } else {
151 35 : php_printf("\"");
152 35 : PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
153 35 : php_printf("\"");
154 : }
155 : }
156 6231 : ZEND_PUTS("]=>\n");
157 : }
158 6330 : php_var_dump(zv, level + 2, verbose TSRMLS_CC);
159 6330 : return 0;
160 : }
161 : /* }}} */
162 :
163 : PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC) /* {{{ */
164 211813 : {
165 : HashTable *myht;
166 : zstr class_name;
167 : zend_uint class_name_len;
168 : int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
169 : int is_temp;
170 :
171 211813 : if (level > 1) {
172 67724 : php_printf("%*c", level - 1, ' ');
173 : }
174 :
175 211813 : switch (Z_TYPE_PP(struc)) {
176 : case IS_BOOL:
177 43106 : php_printf("%sbool(%s)\n", COMMON, Z_LVAL_PP(struc) ? "true" : "false");
178 43105 : break;
179 : case IS_NULL:
180 18032 : php_printf("%sNULL\n", COMMON);
181 18032 : break;
182 : case IS_LONG:
183 59656 : php_printf("%sint(%ld)\n", COMMON, Z_LVAL_PP(struc));
184 59656 : break;
185 : case IS_DOUBLE:
186 5352 : php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc));
187 5352 : break;
188 : case IS_STRING:
189 14264 : php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
190 14264 : PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
191 14264 : PUTS("\"\n");
192 14264 : break;
193 : case IS_UNICODE:
194 44696 : php_printf("%sunicode(%d) ", COMMON, u_countChar32((*struc)->value.ustr.val, (*struc)->value.ustr.len));
195 44696 : php_var_dump_unicode((*struc)->value.ustr.val, (*struc)->value.ustr.len, verbose, "\"", 0 TSRMLS_CC);
196 44696 : PUTS("\n");
197 44696 : break;
198 : case IS_ARRAY:
199 22349 : myht = Z_ARRVAL_PP(struc);
200 22349 : if (myht->nApplyCount > 1) {
201 110 : PUTS("*RECURSION*\n");
202 110 : return;
203 : }
204 22239 : php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
205 22239 : php_element_dump_func = php_array_element_dump;
206 22239 : is_temp = 0;
207 22239 : goto head_done;
208 : case IS_OBJECT:
209 3553 : myht = Z_OBJDEBUG_PP(struc, is_temp);
210 3553 : if (myht && myht->nApplyCount > 1) {
211 91 : PUTS("*RECURSION*\n");
212 91 : return;
213 : }
214 :
215 3462 : Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
216 3462 : php_printf("%sobject(%v)#%d (%d) {\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0);
217 3462 : efree(class_name.v);
218 3462 : php_element_dump_func = php_object_property_dump;
219 25701 : head_done:
220 25701 : if (myht) {
221 25693 : zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_element_dump_func, 2, level, verbose);
222 25693 : if (is_temp) {
223 204 : zend_hash_destroy(myht);
224 204 : efree(myht);
225 : }
226 : }
227 25701 : if (level > 1) {
228 5935 : php_printf("%*c", level-1, ' ');
229 : }
230 25701 : PUTS("}\n");
231 25701 : break;
232 : case IS_RESOURCE: {
233 : char *type_name;
234 :
235 805 : type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
236 805 : php_printf("%sresource(%ld) of type (%s)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown");
237 805 : break;
238 : }
239 : default:
240 0 : php_printf("%sUNKNOWN:0\n", COMMON);
241 : break;
242 : }
243 : }
244 : /* }}} */
245 :
246 : /* {{{ proto void var_dump(mixed var) U
247 : Dumps a string representation of variable to output */
248 : PHP_FUNCTION(var_dump)
249 142722 : {
250 142722 : zval ***args = NULL;
251 : int argc;
252 : int i;
253 :
254 142722 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
255 1 : return;
256 : }
257 :
258 286809 : for (i = 0; i < argc; i++) {
259 144089 : php_var_dump(args[i], 1, 0 TSRMLS_CC);
260 : }
261 142720 : efree(args);
262 : }
263 : /* }}} */
264 :
265 : /* {{{ proto void var_inspect(mixed var) U
266 : Dumps a string representation of variable to output (verbose form) */
267 : PHP_FUNCTION(var_inspect)
268 0 : {
269 0 : zval ***args = NULL;
270 : int argc;
271 : int i;
272 :
273 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
274 0 : return;
275 : }
276 :
277 0 : for (i = 0; i < argc; i++) {
278 0 : php_var_dump(args[i], 1, 1 TSRMLS_CC);
279 : }
280 0 : efree(args);
281 : }
282 : /* }}} */
283 :
284 : static int zval_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
285 143 : {
286 : int level;
287 :
288 143 : level = va_arg(args, int);
289 :
290 143 : if (hash_key->nKeyLength == 0) { /* numeric key */
291 54 : php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
292 : } else { /* string key */
293 : /* XXX: perphaps when we are inside the class we should permit access to
294 : * private & protected values
295 : */
296 89 : if (va_arg(args, int) &&
297 : ((hash_key->type == IS_STRING && hash_key->arKey.s[0] == 0) ||
298 : (hash_key->type == IS_UNICODE && hash_key->arKey.u[0] == 0))
299 : ) {
300 0 : return 0;
301 : }
302 89 : php_printf("%*c[", level + 1, ' ');
303 89 : if (hash_key->type == IS_STRING) {
304 0 : php_printf("\"");
305 0 : PHPWRITE(hash_key->arKey.s, hash_key->nKeyLength - 1);
306 0 : php_printf("\"");
307 89 : } else if (hash_key->type == IS_UNICODE) {
308 89 : php_printf("u");
309 89 : php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, 1, "\"", 0 TSRMLS_CC);
310 : }
311 89 : php_printf("]=>\n");
312 : }
313 143 : php_debug_zval_dump(zv, level + 2, 1 TSRMLS_CC);
314 143 : return 0;
315 : }
316 : /* }}} */
317 :
318 : static int zval_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
319 242 : {
320 : int level;
321 : zstr prop_name, class_name;
322 : int verbose;
323 :
324 242 : level = va_arg(args, int);
325 242 : verbose = va_arg(args, int);
326 :
327 242 : if (hash_key->nKeyLength == 0) { /* numeric key */
328 0 : php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
329 : } else { /* string key */
330 242 : int is_unicode = hash_key->type == IS_UNICODE;
331 :
332 242 : zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
333 242 : php_printf("%*c[", level + 1, ' ');
334 :
335 242 : if (class_name.s) {
336 78 : if (class_name.s[0]=='*') {
337 39 : php_printf("%s\"%R\":protected", is_unicode ? "u" : "", hash_key->type, prop_name);
338 : } else {
339 39 : php_printf("%s\"%R\":%s\"%R\":private", is_unicode ? "u" : "", hash_key->type, prop_name, is_unicode ? "u" : "", hash_key->type, class_name);
340 : }
341 : } else {
342 164 : php_printf("%s\"%R\"", is_unicode ? "u" : "", hash_key->type, prop_name);
343 : }
344 242 : ZEND_PUTS("]=>\n");
345 : }
346 242 : php_debug_zval_dump(zv, level + 2, 1 TSRMLS_CC);
347 242 : return 0;
348 : }
349 : /* }}} */
350 :
351 : PHPAPI void php_debug_zval_dump(zval **struc, int level, int verbose TSRMLS_DC) /* {{{ */
352 683 : {
353 683 : HashTable *myht = NULL;
354 : zstr class_name;
355 : zend_uint class_name_len;
356 : zend_class_entry *ce;
357 : int (*zval_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
358 683 : int is_temp = 0;
359 :
360 683 : if (level > 1) {
361 385 : php_printf("%*c", level - 1, ' ');
362 : }
363 :
364 683 : switch (Z_TYPE_PP(struc)) {
365 : case IS_BOOL:
366 12 : php_printf("%sbool(%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc)?"true":"false", Z_REFCOUNT_PP(struc));
367 12 : break;
368 : case IS_NULL:
369 25 : php_printf("%sNULL refcount(%u)\n", COMMON, Z_REFCOUNT_PP(struc));
370 25 : break;
371 : case IS_LONG:
372 386 : php_printf("%slong(%ld) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), Z_REFCOUNT_PP(struc));
373 386 : break;
374 : case IS_DOUBLE:
375 38 : php_printf("%sdouble(%.*G) refcount(%u)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc), Z_REFCOUNT_PP(struc));
376 38 : break;
377 : case IS_STRING:
378 0 : php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
379 0 : PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
380 0 : php_printf("\" refcount(%u)\n", Z_REFCOUNT_PP(struc));
381 0 : break;
382 : case IS_UNICODE:
383 77 : php_printf("%sunicode(%d) ", COMMON, u_countChar32((*struc)->value.ustr.val, (*struc)->value.ustr.len));
384 77 : php_var_dump_unicode((*struc)->value.ustr.val, (*struc)->value.ustr.len, verbose, "\"", 0 TSRMLS_CC);
385 77 : php_printf(" refcount(%u)\n", Z_REFCOUNT_PP(struc));
386 77 : break;
387 : case IS_ARRAY:
388 77 : myht = Z_ARRVAL_PP(struc);
389 77 : if (myht->nApplyCount > 1) {
390 0 : PUTS("*RECURSION*\n");
391 0 : return;
392 : }
393 77 : php_printf("%sarray(%d) refcount(%u){\n", COMMON, zend_hash_num_elements(myht), Z_REFCOUNT_PP(struc));
394 77 : zval_element_dump_func = zval_array_element_dump;
395 77 : goto head_done;
396 : case IS_OBJECT:
397 66 : myht = Z_OBJDEBUG_PP(struc, is_temp);
398 66 : if (myht && myht->nApplyCount > 1) {
399 24 : PUTS("*RECURSION*\n");
400 24 : return;
401 : }
402 42 : ce = Z_OBJCE_PP(struc);
403 42 : Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
404 42 : php_printf("%sobject(%v)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc));
405 42 : efree(class_name.v);
406 42 : zval_element_dump_func = zval_object_property_dump;
407 119 : head_done:
408 119 : if (myht) {
409 119 : zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) zval_element_dump_func, 1, level, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1));
410 119 : if (is_temp) {
411 1 : zend_hash_destroy(myht);
412 1 : efree(myht);
413 : }
414 : }
415 119 : if (level > 1) {
416 79 : php_printf("%*c", level - 1, ' ');
417 : }
418 119 : PUTS("}\n");
419 119 : break;
420 : case IS_RESOURCE: {
421 : char *type_name;
422 :
423 2 : type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
424 2 : php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown", Z_REFCOUNT_PP(struc));
425 2 : break;
426 : }
427 : default:
428 0 : php_printf("%sUNKNOWN:0\n", COMMON);
429 : break;
430 : }
431 : }
432 : /* }}} */
433 :
434 : /* {{{ proto void debug_zval_dump(mixed var) U
435 : Dumps a string representation of an internal zend value to output. */
436 : PHP_FUNCTION(debug_zval_dump)
437 205 : {
438 205 : zval ***args = NULL;
439 : int argc;
440 : int i;
441 :
442 205 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
443 1 : return;
444 : }
445 :
446 502 : for (i = 0; i < argc; i++) {
447 298 : php_debug_zval_dump(args[i], 1, 1 TSRMLS_CC);
448 : }
449 204 : efree(args);
450 : }
451 : /* }}} */
452 :
453 : static int php_array_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
454 1313 : {
455 : int level;
456 :
457 1313 : level = va_arg(args, int);
458 :
459 1313 : if (hash_key->nKeyLength == 0) { /* numeric key */
460 596 : php_printf("%*c%ld => ", level + 1, ' ', hash_key->h);
461 : } else { /* string key */
462 717 : php_printf("%*c'", level + 1, ' ');
463 717 : if (hash_key->type == IS_UNICODE) {
464 92 : php_var_dump_unicode(hash_key->arKey.u, hash_key->nKeyLength-1, 0, "", 1 TSRMLS_CC);
465 : } else {
466 : char *key, *tmp_str;
467 : int key_len, tmp_len;
468 625 : key = php_addcslashes(hash_key->arKey.s, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC);
469 625 : tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL);
470 625 : PHPWRITE(tmp_str, tmp_len);
471 625 : efree(key);
472 625 : efree(tmp_str);
473 : }
474 717 : php_printf("' => ");
475 : }
476 1313 : php_var_export(zv, level + 2 TSRMLS_CC);
477 1309 : PUTS (",\n");
478 1309 : return 0;
479 : }
480 : /* }}} */
481 :
482 : static int php_object_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
483 283 : {
484 : int level;
485 : zstr prop_name, class_name;
486 :
487 283 : level = va_arg(args, int);
488 :
489 283 : php_printf("%*c", level + 1, ' ');
490 283 : if (hash_key->nKeyLength != 0) {
491 280 : zend_u_unmangle_property_name(hash_key->type, hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
492 280 : php_printf(" '%R' => ", hash_key->type, prop_name);
493 : } else {
494 3 : php_printf(" %ld => ", hash_key->h);
495 : }
496 283 : php_var_export(zv, level + 2 TSRMLS_CC);
497 280 : PUTS (",\n");
498 280 : return 0;
499 : }
500 : /* }}} */
501 :
502 : static void php_unicode_export(UChar *ustr, int ustr_len TSRMLS_DC) /* {{{ */
503 479 : {
504 : UChar32 cp;
505 479 : int i = 0;
506 : char buf[10];
507 : int buf_len;
508 479 : int state = 0; /* 0 = in single quotes, 1 = in double quotes */
509 :
510 : /*
511 : * We export all codepoints > 128 in escaped form to avoid encoding issues
512 : * in case the result is used in a script.
513 : */
514 6600 : while (i < ustr_len) {
515 5642 : U16_NEXT(ustr, i, ustr_len, cp);
516 5642 : switch (cp) {
517 : case 0x0: /* '\0' */
518 19 : if (state == 0) {
519 19 : PHPWRITE("' . \"", 5);
520 19 : state = 1;
521 : }
522 19 : PHPWRITE("\\0", 2);
523 19 : break;
524 :
525 : case 0x27: /* '\'' */
526 1 : if (state == 1) {
527 0 : PHPWRITE("\" . '", 5);
528 0 : state = 0;
529 : }
530 1 : PHPWRITE("\\'", 2);
531 1 : break;
532 :
533 : case 0x5c: /* '\\' */
534 20 : PHPWRITE("\\\\", 2);
535 20 : break;
536 :
537 : default:
538 5602 : if ((uint32_t)cp < 128) {
539 5602 : if (state == 1) {
540 9 : PHPWRITE("\" . '", 5);
541 9 : state = 0;
542 : }
543 5602 : buf[0] = (char) (short) cp;
544 5602 : buf_len = 1;
545 0 : } else if (U_IS_BMP(cp)) {
546 0 : if (state == 0) {
547 0 : PHPWRITE("' . \"", 5);
548 0 : state = 1;
549 : }
550 0 : buf_len = snprintf(buf, sizeof(buf), "\\u%04X", cp);
551 : } else {
552 0 : if (state == 0) {
553 0 : PHPWRITE("' . \"", 5);
554 0 : state = 1;
555 : }
556 0 : buf_len = snprintf(buf, sizeof(buf), "\\u%06X", cp);
557 : }
558 5602 : PHPWRITE(buf, buf_len);
559 : break;
560 : }
561 : }
562 479 : if (state == 1) { /* if we are in double quotes, go back to single */
563 10 : PHPWRITE("\" . '", 5);
564 : }
565 479 : }
566 : /* }}} */
567 :
568 : PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */
569 2902 : {
570 : HashTable *myht;
571 : char *tmp_str, *tmp_str2;
572 : int tmp_len, tmp_len2;
573 : zstr class_name;
574 : zend_uint class_name_len;
575 :
576 2902 : switch (Z_TYPE_PP(struc)) {
577 : case IS_BOOL:
578 48 : php_printf("%s", Z_LVAL_PP(struc) ? "true" : "false");
579 48 : break;
580 : case IS_NULL:
581 203 : php_printf("NULL");
582 203 : break;
583 : case IS_LONG:
584 821 : php_printf("%ld", Z_LVAL_PP(struc));
585 821 : break;
586 : case IS_DOUBLE:
587 117 : php_printf("%.*H", (int) EG(precision), Z_DVAL_PP(struc));
588 117 : break;
589 : case IS_STRING:
590 493 : tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC);
591 493 : tmp_str2 = php_str_to_str_ex(tmp_str, tmp_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len2, 0, NULL);
592 493 : PUTS ("'");
593 493 : PHPWRITE(tmp_str2, tmp_len2);
594 493 : PUTS ("'");
595 493 : efree(tmp_str2);
596 493 : efree(tmp_str);
597 493 : break;
598 : case IS_UNICODE:
599 479 : PUTS ("'");
600 479 : php_unicode_export(Z_USTRVAL_PP(struc), Z_USTRLEN_PP(struc) TSRMLS_CC);
601 479 : PUTS ("'");
602 479 : break;
603 : case IS_ARRAY:
604 527 : myht = Z_ARRVAL_PP(struc);
605 527 : if (level > 1) {
606 110 : php_printf("\n%*c", level - 1, ' ');
607 : }
608 527 : PUTS ("array (\n");
609 527 : zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_array_element_export, 1, level, 0);
610 522 : if (level > 1) {
611 106 : php_printf("%*c", level - 1, ' ');
612 : }
613 522 : PUTS(")");
614 522 : break;
615 : case IS_OBJECT:
616 214 : myht = Z_OBJPROP_PP(struc);
617 214 : if (level > 1) {
618 143 : php_printf("\n%*c", level - 1, ' ');
619 : }
620 214 : Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
621 214 : php_printf ("%v::__set_state(array(\n", class_name);
622 214 : efree(class_name.v);
623 214 : if (myht) {
624 214 : zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_object_element_export, 1, level);
625 : }
626 210 : if (level > 1) {
627 140 : php_printf("%*c", level - 1, ' ');
628 : }
629 210 : php_printf ("))");
630 210 : break;
631 : default:
632 0 : PUTS ("NULL");
633 : break;
634 : }
635 2893 : }
636 : /* }}} */
637 :
638 : /* {{{ proto mixed var_export(mixed var [, bool return]) U
639 : Outputs or returns a string representation of a variable */
640 : PHP_FUNCTION(var_export)
641 1310 : {
642 : zval *var;
643 1310 : zend_bool return_output = 0;
644 :
645 1310 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) {
646 4 : return;
647 : }
648 :
649 1306 : if (return_output) {
650 961 : php_output_start_default(TSRMLS_C);
651 : }
652 :
653 : /* UTODO
654 : * We need to escape non-ASCII chars with \uXXXX format. php_var_export()
655 : * currently uses output_encoding to export Unicode strings. Suppose it's
656 : * set to utf-8. If you use the result of var_export() in non-utf-8 context,
657 : * there may be trouble.
658 : */
659 1306 : php_var_export(&var, 1 TSRMLS_CC);
660 :
661 1304 : if (return_output) {
662 959 : php_output_get_contents(return_value TSRMLS_CC);
663 959 : php_output_discard(TSRMLS_C);
664 : }
665 : }
666 : /* }}} */
667 :
668 : static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC);
669 :
670 : static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old TSRMLS_DC) /* {{{ */
671 29011 : {
672 : ulong var_no;
673 : char id[32], *p;
674 : register int len;
675 :
676 : /* relies on "(long)" being a perfect hash function for data pointers,
677 : * however the actual identity of an object has had to be determined
678 : * by its object handle and the class entry since 5.0. */
679 29214 : if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
680 203 : p = smart_str_print_long(id + sizeof(id) - 1,
681 : (((size_t)Z_OBJCE_P(var) << 5)
682 : | ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5)))
683 : + (long) Z_OBJ_HANDLE_P(var));
684 203 : *(--p) = 'O';
685 203 : len = id + sizeof(id) - 1 - p;
686 : } else {
687 28808 : p = smart_str_print_long(id + sizeof(id) - 1, (long) var);
688 28808 : len = id + sizeof(id) - 1 - p;
689 : }
690 :
691 29011 : if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) {
692 27685 : if (!Z_ISREF_P(var)) {
693 : /* we still need to bump up the counter, since non-refs will
694 : * be counted separately by unserializer */
695 27619 : var_no = -1;
696 27619 : zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL);
697 : }
698 27685 : return FAILURE;
699 : }
700 :
701 : /* +1 because otherwise hash will think we are trying to store NULL pointer */
702 1326 : var_no = zend_hash_num_elements(var_hash) + 1;
703 1326 : zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
704 1326 : return SUCCESS;
705 : }
706 : /* }}} */
707 :
708 : static inline void php_var_serialize_long(smart_str *buf, long val) /* {{{ */
709 6631 : {
710 6631 : smart_str_appendl(buf, "i:", 2);
711 6631 : smart_str_append_long(buf, val);
712 6631 : smart_str_appendc(buf, ';');
713 6631 : }
714 : /* }}} */
715 :
716 : static inline void php_var_serialize_string(smart_str *buf, char *str, int len) /* {{{ */
717 46 : {
718 : static const char hex[] = "0123456789abcdef";
719 : unsigned char c;
720 : int i;
721 :
722 46 : smart_str_appendl(buf, "S:", 2);
723 46 : smart_str_append_long(buf, len);
724 46 : smart_str_appendl(buf, ":\"", 2);
725 :
726 193 : for (i = 0; i < len; i++) {
727 147 : c = (unsigned char) str[i];
728 294 : if (c < 128 && c != 0x5c /*'\\'*/) {
729 147 : smart_str_appendc(buf, c & 0xff);
730 : } else {
731 0 : smart_str_appendc(buf, 0x5c /*'\\'*/);
732 0 : smart_str_appendc(buf, hex[(c >> 4) & 0xf]);
733 0 : smart_str_appendc(buf, hex[(c >> 0) & 0xf]);
734 : }
735 : }
736 :
737 46 : smart_str_appendl(buf, "\";", 2);
738 46 : }
739 : /* }}} */
740 :
741 : static inline void php_var_serialize_ustr(smart_str *buf, UChar *ustr, int len) /* {{{ */
742 41763 : {
743 : static const char hex[] = "0123456789abcdef";
744 : UChar c;
745 : int i;
746 :
747 474004 : for (i = 0; i < len; i++) {
748 432241 : c = ustr[i];
749 864478 : if (c < 128 && c != 0x5c /*'\\'*/) {
750 432237 : smart_str_appendc(buf, c & 0xff);
751 : } else {
752 4 : smart_str_appendc(buf, 0x5c /*'\\'*/);
753 4 : smart_str_appendc(buf, hex[(c >> 12) & 0xf]);
754 4 : smart_str_appendc(buf, hex[(c >> 8) & 0xf]);
755 4 : smart_str_appendc(buf, hex[(c >> 4) & 0xf]);
756 4 : smart_str_appendc(buf, hex[(c >> 0) & 0xf]);
757 : }
758 : }
759 41763 : }
760 : /* }}} */
761 :
762 : static inline void php_var_serialize_unicode(smart_str *buf, UChar *ustr, int len) /* {{{ */
763 41598 : {
764 41598 : smart_str_appendl(buf, "U:", 2);
765 41598 : smart_str_append_long(buf, len);
766 41598 : smart_str_appendl(buf, ":\"", 2);
767 41598 : php_var_serialize_ustr(buf, ustr, len);
768 41598 : smart_str_appendl(buf, "\";", 2);
769 41598 : }
770 : /* }}} */
771 :
772 : static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc TSRMLS_DC) /* {{{ */
773 135 : {
774 135 : PHP_CLASS_ATTRIBUTES;
775 :
776 135 : PHP_SET_CLASS_ATTRIBUTES(struc);
777 135 : smart_str_appendl(buf, "O:", 2);
778 135 : smart_str_append_long(buf, name_len);
779 135 : smart_str_appendl(buf, ":\"", 2);
780 135 : php_var_serialize_ustr(buf, class_name.u, name_len);
781 135 : smart_str_appendl(buf, "\":", 2);
782 135 : PHP_CLEANUP_CLASS_ATTRIBUTES();
783 135 : return incomplete_class;
784 : }
785 : /* }}} */
786 :
787 : static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC) /* {{{ */
788 4 : {
789 : int count;
790 : zend_bool incomplete_class;
791 : zstr star;
792 :
793 4 : star.s = "*";
794 :
795 4 : incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
796 : /* count after serializing name, since php_var_serialize_class_name
797 : * changes the count if the variable is incomplete class */
798 4 : count = zend_hash_num_elements(HASH_OF(retval_ptr));
799 4 : if (incomplete_class) {
800 0 : --count;
801 : }
802 4 : smart_str_append_long(buf, count);
803 4 : smart_str_appendl(buf, ":{", 2);
804 :
805 4 : if (count > 0) {
806 : zstr key;
807 : unsigned int key_len;
808 : zval **d, **name;
809 : ulong index;
810 : HashPosition pos;
811 : int i;
812 : zval nval, *nvalp;
813 :
814 3 : ZVAL_NULL(&nval);
815 3 : nvalp = &nval;
816 :
817 3 : zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
818 :
819 8 : for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
820 11 : i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, &key_len, &index, 0, &pos);
821 :
822 11 : if (i == HASH_KEY_NON_EXISTANT) {
823 3 : break;
824 : }
825 :
826 8 : if (incomplete_class &&
827 : key_len == sizeof(MAGIC_MEMBER) &&
828 : ZEND_U_EQUAL(i, key, key_len-1, MAGIC_MEMBER, sizeof(MAGIC_MEMBER)-1)
829 : ) {
830 0 : continue;
831 : }
832 8 : zend_hash_get_current_data_ex(HASH_OF(retval_ptr), (void **) &name, &pos);
833 :
834 8 : if (Z_TYPE_PP(name) != IS_UNICODE) {
835 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
836 : /* we should still add element even if it's not OK,
837 : * since we already wrote the length of the array before */
838 0 : smart_str_appendl(buf,"N;", 2);
839 0 : continue;
840 : }
841 8 : if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), Z_UNIVAL_PP(name), Z_UNILEN_PP(name) + 1, (void *) &d) == SUCCESS) {
842 4 : if (Z_TYPE_PP(name) == IS_UNICODE) {
843 4 : php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
844 : } else {
845 0 : php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
846 : }
847 4 : php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
848 : } else {
849 : zend_class_entry *ce;
850 4 : ce = zend_get_class_entry(struc TSRMLS_CC);
851 4 : if (ce) {
852 : zstr prot_name, priv_name;
853 : int prop_name_length;
854 :
855 : do {
856 4 : zend_u_mangle_property_name(&priv_name, &prop_name_length, Z_TYPE_PP(name), ce->name, ce->name_length, Z_UNIVAL_PP(name), Z_UNILEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
857 4 : if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) {
858 1 : if (Z_TYPE_PP(name) == IS_UNICODE) {
859 1 : php_var_serialize_unicode(buf, priv_name.u, prop_name_length);
860 : } else {
861 0 : php_var_serialize_string(buf, priv_name.s, prop_name_length);
862 : }
863 1 : pefree(priv_name.v, ce->type & ZEND_INTERNAL_CLASS);
864 1 : php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
865 1 : break;
866 : }
867 3 : pefree(priv_name.v, ce->type & ZEND_INTERNAL_CLASS);
868 3 : zend_u_mangle_property_name(&prot_name, &prop_name_length, Z_TYPE_PP(name), star, 1, Z_UNIVAL_PP(name), Z_UNILEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
869 3 : if (zend_u_hash_find(Z_OBJPROP_P(struc), Z_TYPE_PP(name), prot_name, prop_name_length+1, (void *) &d) == SUCCESS) {
870 1 : if (Z_TYPE_PP(name) == IS_UNICODE) {
871 1 : php_var_serialize_unicode(buf, prot_name.u, prop_name_length);
872 : } else {
873 0 : php_var_serialize_string(buf, prot_name.s, prop_name_length);
874 : }
875 1 : pefree(prot_name.v, ce->type & ZEND_INTERNAL_CLASS);
876 1 : php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
877 1 : break;
878 : }
879 2 : pefree(prot_name.v, ce->type & ZEND_INTERNAL_CLASS);
880 2 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "\"%R\" returned as member variable from __sleep() but does not exist", Z_TYPE_PP(name), Z_UNIVAL_PP(name));
881 2 : if (Z_TYPE_PP(name) == IS_UNICODE) {
882 2 : php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
883 : } else {
884 0 : php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
885 : }
886 2 : php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
887 : } while (0);
888 : } else {
889 0 : if (Z_TYPE_PP(name) == IS_UNICODE) {
890 0 : php_var_serialize_unicode(buf, Z_USTRVAL_PP(name), Z_USTRLEN_PP(name));
891 : } else {
892 0 : php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
893 : }
894 0 : php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
895 : }
896 : }
897 8 : }
898 : }
899 4 : smart_str_appendc(buf, '}');
900 4 : }
901 : /* }}} */
902 :
903 : static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
904 29011 : {
905 : int i;
906 : ulong *var_already;
907 : HashTable *myht;
908 :
909 29011 : if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) {
910 27685 : if (Z_ISREF_P(struc)) {
911 66 : smart_str_appendl(buf, "R:", 2);
912 66 : smart_str_append_long(buf, *var_already);
913 66 : smart_str_appendc(buf, ';');
914 66 : return;
915 27619 : } else if (Z_TYPE_P(struc) == IS_OBJECT) {
916 25 : smart_str_appendl(buf, "r:", 2);
917 25 : smart_str_append_long(buf, *var_already);
918 25 : smart_str_appendc(buf, ';');
919 25 : return;
920 : }
921 : }
922 :
923 28920 : switch (Z_TYPE_P(struc)) {
924 : case IS_BOOL:
925 50 : smart_str_appendl(buf, "b:", 2);
926 50 : smart_str_append_long(buf, Z_LVAL_P(struc));
927 50 : smart_str_appendc(buf, ';');
928 50 : return;
929 :
930 : case IS_NULL:
931 92 : smart_str_appendl(buf, "N;", 2);
932 92 : return;
933 :
934 : case IS_LONG:
935 5107 : php_var_serialize_long(buf, Z_LVAL_P(struc));
936 5107 : return;
937 :
938 : case IS_DOUBLE: {
939 : char *s;
940 :
941 65 : smart_str_appendl(buf, "d:", 2);
942 65 : s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
943 65 : php_gcvt(Z_DVAL_P(struc), PG(serialize_precision), '.', 'E', s);
944 65 : smart_str_appends(buf, s);
945 65 : smart_str_appendc(buf, ';');
946 65 : efree(s);
947 65 : return;
948 : }
949 :
950 : case IS_STRING:
951 34 : php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc));
952 34 : return;
953 :
954 : case IS_UNICODE:
955 14784 : php_var_serialize_unicode(buf, Z_USTRVAL_P(struc), Z_USTRLEN_P(struc));
956 14784 : return;
957 :
958 : case IS_OBJECT: {
959 167 : zval *retval_ptr = NULL;
960 : zval fname;
961 : int res;
962 167 : zend_class_entry *ce = NULL;
963 :
964 167 : if (Z_OBJ_HT_P(struc)->get_class_entry) {
965 167 : ce = Z_OBJCE_P(struc);
966 : }
967 :
968 167 : if (ce && ce->serialize != NULL) {
969 : /* has custom handler */
970 : int serialized_type;
971 : zstr serialized_data;
972 : zend_uint serialized_length;
973 :
974 31 : serialized_data.v = NULL;
975 31 : if (ce->serialize(struc, &serialized_type, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash TSRMLS_CC) == SUCCESS) {
976 26 : smart_str_appendl(buf, "C:", 2);
977 26 : smart_str_append_long(buf, Z_OBJCE_P(struc)->name_length);
978 26 : smart_str_appendl(buf, ":\"", 2);
979 26 : php_var_serialize_ustr(buf, Z_OBJCE_P(struc)->name.u, Z_OBJCE_P(struc)->name_length);
980 26 : smart_str_appendl(buf, "\":", 2);
981 :
982 26 : smart_str_append_long(buf, serialized_length);
983 26 : if (serialized_type == IS_UNICODE) {
984 4 : smart_str_appendl(buf, ":U:{", 4);
985 4 : php_var_serialize_ustr(buf, serialized_data.u, serialized_length);
986 22 : } else if (serialized_type == IS_STRING) {
987 22 : smart_str_appendl(buf, ":{", 2);
988 22 : smart_str_appendl(buf, serialized_data.s, serialized_length);
989 : } else {
990 0 : smart_str_appendc(buf, 'N');
991 : }
992 26 : smart_str_appendc(buf, '}');
993 : } else {
994 5 : smart_str_appendl(buf, "N;", 2);
995 : }
996 31 : if (serialized_data.v) {
997 26 : efree(serialized_data.v);
998 : }
999 31 : return;
1000 : }
1001 :
1002 136 : if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) {
1003 11 : INIT_PZVAL(&fname);
1004 11 : ZVAL_ASCII_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 1);
1005 11 : res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
1006 11 : zval_dtor(&fname);
1007 11 : if (res == SUCCESS && !EG(exception)) {
1008 5 : if (retval_ptr) {
1009 5 : if (HASH_OF(retval_ptr)) {
1010 4 : php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC);
1011 : } else {
1012 1 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
1013 : /* we should still add element even if it's not OK,
1014 : * since we already wrote the length of the array before */
1015 1 : smart_str_appendl(buf,"N;", 2);
1016 : }
1017 5 : zval_ptr_dtor(&retval_ptr);
1018 : }
1019 5 : return;
1020 : }
1021 : }
1022 :
1023 131 : if (retval_ptr) {
1024 0 : zval_ptr_dtor(&retval_ptr);
1025 : }
1026 : /* fall-through */
1027 : }
1028 : case IS_ARRAY: {
1029 8749 : zend_bool incomplete_class = 0;
1030 8749 : if (Z_TYPE_P(struc) == IS_ARRAY) {
1031 8618 : smart_str_appendl(buf, "a:", 2);
1032 8618 : myht = HASH_OF(struc);
1033 : } else {
1034 131 : incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
1035 131 : myht = Z_OBJPROP_P(struc);
1036 : }
1037 : /* count after serializing name, since php_var_serialize_class_name
1038 : * changes the count if the variable is incomplete class */
1039 8749 : i = myht ? zend_hash_num_elements(myht) : 0;
1040 8749 : if (i > 0 && incomplete_class) {
1041 2 : --i;
1042 : }
1043 8749 : smart_str_append_long(buf, i);
1044 8749 : smart_str_appendl(buf, ":{", 2);
1045 8749 : if (i > 0) {
1046 : zstr key;
1047 : zval **data;
1048 : ulong index;
1049 : uint key_len;
1050 : HashPosition pos;
1051 :
1052 8687 : zend_hash_internal_pointer_reset_ex(myht, &pos);
1053 28342 : for (;; zend_hash_move_forward_ex(myht, &pos)) {
1054 37029 : i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
1055 37029 : if (i == HASH_KEY_NON_EXISTANT) {
1056 8687 : break;
1057 : }
1058 :
1059 28342 : if (incomplete_class &&
1060 : key_len == sizeof(MAGIC_MEMBER) &&
1061 : ZEND_U_EQUAL(i, key, key_len - 1, MAGIC_MEMBER, sizeof(MAGIC_MEMBER) - 1)
1062 : ) {
1063 0 : continue;
1064 : }
1065 :
1066 28342 : switch (i) {
1067 : case HASH_KEY_IS_LONG:
1068 1524 : php_var_serialize_long(buf, index);
1069 1524 : break;
1070 : case HASH_KEY_IS_STRING:
1071 12 : php_var_serialize_string(buf, key.s, key_len - 1);
1072 12 : break;
1073 : case HASH_KEY_IS_UNICODE:
1074 26806 : php_var_serialize_unicode(buf, key.u, key_len - 1);
1075 : break;
1076 : }
1077 :
1078 : /* we should still add element even if it's not OK,
1079 : * since we already wrote the length of the array before */
1080 28342 : if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) != SUCCESS
1081 : || !data
1082 : || data == &struc
1083 : || (Z_TYPE_PP(data) == IS_ARRAY && Z_ARRVAL_PP(data)->nApplyCount > 1)
1084 : ) {
1085 0 : smart_str_appendl(buf, "N;", 2);
1086 : } else {
1087 28342 : if (Z_TYPE_PP(data) == IS_ARRAY) {
1088 8453 : Z_ARRVAL_PP(data)->nApplyCount++;
1089 : }
1090 28342 : php_var_serialize_intern(buf, *data, var_hash TSRMLS_CC);
1091 28342 : if (Z_TYPE_PP(data) == IS_ARRAY) {
1092 8453 : Z_ARRVAL_PP(data)->nApplyCount--;
1093 : }
1094 : }
1095 28342 : }
1096 : }
1097 8749 : smart_str_appendc(buf, '}');
1098 8749 : return;
1099 : }
1100 : default:
1101 3 : smart_str_appendl(buf, "i:0;", 4);
1102 3 : return;
1103 : }
1104 : }
1105 : /* }}} */
1106 :
1107 : PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
1108 661 : {
1109 661 : php_var_serialize_intern(buf, *struc, var_hash TSRMLS_CC);
1110 661 : smart_str_0(buf);
1111 661 : }
1112 : /* }}} */
1113 :
1114 : /* {{{ proto string serialize(mixed variable) U
1115 : Returns a string representation of variable (which can later be unserialized) */
1116 : PHP_FUNCTION(serialize)
1117 255 : {
1118 : zval **struc;
1119 : php_serialize_data_t var_hash;
1120 255 : smart_str buf = {0};
1121 :
1122 255 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &struc) == FAILURE) {
1123 2 : return;
1124 : }
1125 :
1126 253 : Z_TYPE_P(return_value) = IS_STRING;
1127 253 : Z_STRVAL_P(return_value) = NULL;
1128 253 : Z_STRLEN_P(return_value) = 0;
1129 :
1130 253 : PHP_VAR_SERIALIZE_INIT(var_hash);
1131 253 : php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
1132 253 : PHP_VAR_SERIALIZE_DESTROY(var_hash);
1133 :
1134 253 : if (buf.c) {
1135 253 : RETVAL_ASCII_STRINGL(buf.c, buf.len, 0);
1136 253 : smart_str_free(&buf);
1137 : } else {
1138 0 : RETURN_NULL();
1139 : }
1140 : }
1141 : /* }}} */
1142 :
1143 : /* {{{ proto mixed unserialize(string variable_representation) U
1144 : Takes a string representation of variable and recreates it */
1145 : PHP_FUNCTION(unserialize)
1146 216 : {
1147 216 : char *buf = NULL;
1148 : int buf_len;
1149 : const unsigned char *p;
1150 : php_unserialize_data_t var_hash;
1151 :
1152 216 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &buf, &buf_len, UG(ascii_conv)) == FAILURE) {
1153 2 : RETURN_FALSE;
1154 : }
1155 :
1156 214 : if (buf_len == 0) {
1157 0 : RETURN_FALSE;
1158 : }
1159 :
1160 214 : p = (const unsigned char*) buf;
1161 214 : PHP_VAR_UNSERIALIZE_INIT(var_hash);
1162 214 : if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) {
1163 15 : PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
1164 15 : zval_dtor(return_value);
1165 15 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
1166 15 : RETURN_FALSE;
1167 : }
1168 199 : PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
1169 : }
1170 : /* }}} */
1171 :
1172 : /* {{{ proto int memory_get_usage([real_usage]) U
1173 : Returns the allocated by PHP memory */
1174 3 : PHP_FUNCTION(memory_get_usage) {
1175 3 : zend_bool real_usage = 0;
1176 :
1177 3 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
1178 0 : RETURN_FALSE;
1179 : }
1180 :
1181 3 : RETURN_LONG(zend_memory_usage(real_usage TSRMLS_CC));
1182 : }
1183 : /* }}} */
1184 :
1185 : /* {{{ proto int memory_get_peak_usage([real_usage]) U
1186 : Returns the peak allocated by PHP memory */
1187 1 : PHP_FUNCTION(memory_get_peak_usage) {
1188 1 : zend_bool real_usage = 0;
1189 :
1190 1 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
1191 0 : RETURN_FALSE;
1192 : }
1193 :
1194 1 : RETURN_LONG(zend_memory_peak_usage(real_usage TSRMLS_CC));
1195 : }
1196 : /* }}} */
1197 :
1198 : /*
1199 : * Local variables:
1200 : * tab-width: 4
1201 : * c-basic-offset: 4
1202 : * End:
1203 : * vim600: sw=4 ts=4 fdm=marker
1204 : * vim<600: sw=4 ts=4
1205 : */
|