Annotation of embedaddon/php/main/php_variables.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 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: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
16: | Zeev Suraski <zeev@zend.com> |
17: +----------------------------------------------------------------------+
18: */
19:
20: /* $Id: php_variables.c 323031 2012-02-02 17:51:44Z johannes $ */
21:
22: #include <stdio.h>
23: #include "php.h"
24: #include "ext/standard/php_standard.h"
25: #include "ext/standard/credits.h"
26: #include "php_variables.h"
27: #include "php_globals.h"
28: #include "php_content_types.h"
29: #include "SAPI.h"
30: #include "php_logos.h"
31: #include "zend_globals.h"
32:
33: /* for systems that need to override reading of environment variables */
34: void _php_import_environment_variables(zval *array_ptr TSRMLS_DC);
35: PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC) = _php_import_environment_variables;
36:
37: PHPAPI void php_register_variable(char *var, char *strval, zval *track_vars_array TSRMLS_DC)
38: {
39: php_register_variable_safe(var, strval, strlen(strval), track_vars_array TSRMLS_CC);
40: }
41:
42: /* binary-safe version */
43: PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zval *track_vars_array TSRMLS_DC)
44: {
45: zval new_entry;
46: assert(strval != NULL);
47:
48: /* Prepare value */
49: Z_STRLEN(new_entry) = str_len;
50: if (PG(magic_quotes_gpc)) {
51: Z_STRVAL(new_entry) = php_addslashes(strval, Z_STRLEN(new_entry), &Z_STRLEN(new_entry), 0 TSRMLS_CC);
52: } else {
53: Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry));
54: }
55: Z_TYPE(new_entry) = IS_STRING;
56:
57: php_register_variable_ex(var, &new_entry, track_vars_array TSRMLS_CC);
58: }
59:
60: PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array TSRMLS_DC)
61: {
62: char *p = NULL;
63: char *ip; /* index pointer */
64: char *index, *escaped_index = NULL;
65: char *var, *var_orig;
66: int var_len, index_len;
67: zval *gpc_element, **gpc_element_p;
68: zend_bool is_array = 0;
69: HashTable *symtable1 = NULL;
70:
71: assert(var_name != NULL);
72:
73: if (track_vars_array) {
74: symtable1 = Z_ARRVAL_P(track_vars_array);
75: } else if (PG(register_globals)) {
76: if (!EG(active_symbol_table)) {
77: zend_rebuild_symbol_table(TSRMLS_C);
78: }
79: symtable1 = EG(active_symbol_table);
80: }
81: if (!symtable1) {
82: /* Nothing to do */
83: zval_dtor(val);
84: return;
85: }
86:
87: /*
88: * Prepare variable name
89: */
90:
91: var_orig = estrdup(var_name);
92: var = var_orig;
93: /* ignore leading spaces in the variable name */
94: while (*var && *var==' ') {
95: var++;
96: }
97:
98: /* ensure that we don't have spaces or dots in the variable name (not binary safe) */
99: for (p = var; *p; p++) {
100: if (*p == ' ' || *p == '.') {
101: *p='_';
102: } else if (*p == '[') {
103: is_array = 1;
104: ip = p;
105: *p = 0;
106: break;
107: }
108: }
109: var_len = p - var;
110:
111: if (var_len==0) { /* empty variable name, or variable name with a space in it */
112: zval_dtor(val);
113: efree(var_orig);
114: return;
115: }
116:
117: /* GLOBALS hijack attempt, reject parameter */
118: if (symtable1 == EG(active_symbol_table) &&
119: var_len == sizeof("GLOBALS")-1 &&
120: !memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) {
121: zval_dtor(val);
122: efree(var_orig);
123: return;
124: }
125:
126: index = var;
127: index_len = var_len;
128:
129: if (is_array) {
130: int nest_level = 0;
131: while (1) {
132: char *index_s;
133: int new_idx_len = 0;
134:
135: if(++nest_level > PG(max_input_nesting_level)) {
136: HashTable *ht;
137: /* too many levels of nesting */
138:
139: if (track_vars_array) {
140: ht = Z_ARRVAL_P(track_vars_array);
141: zend_hash_del(ht, var, var_len + 1);
142: } else if (PG(register_globals)) {
143: ht = EG(active_symbol_table);
144: zend_hash_del(ht, var, var_len + 1);
145: }
146:
147: zval_dtor(val);
148:
149: /* do not output the error message to the screen,
150: this helps us to to avoid "information disclosure" */
151: if (!PG(display_errors)) {
152: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variable nesting level exceeded %ld. To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level));
153: }
154: efree(var_orig);
155: return;
156: }
157:
158: ip++;
159: index_s = ip;
160: if (isspace(*ip)) {
161: ip++;
162: }
163: if (*ip==']') {
164: index_s = NULL;
165: } else {
166: ip = strchr(ip, ']');
167: if (!ip) {
168: /* PHP variables cannot contain '[' in their names, so we replace the character with a '_' */
169: *(index_s - 1) = '_';
170:
171: index_len = 0;
172: if (index) {
173: index_len = strlen(index);
174: }
175: goto plain_var;
176: return;
177: }
178: *ip = 0;
179: new_idx_len = strlen(index_s);
180: }
181:
182: if (!index) {
183: MAKE_STD_ZVAL(gpc_element);
184: array_init(gpc_element);
185: if (zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p) == FAILURE) {
186: zval_ptr_dtor(&gpc_element);
187: zval_dtor(val);
188: efree(var_orig);
189: return;
190: }
191: } else {
192: if (PG(magic_quotes_gpc)) {
193: escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC);
194: } else {
195: escaped_index = index;
196: }
197: if (zend_symtable_find(symtable1, escaped_index, index_len + 1, (void **) &gpc_element_p) == FAILURE
198: || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
199: if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
200: if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
201: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
202: }
203: MAKE_STD_ZVAL(gpc_element);
204: array_init(gpc_element);
205: zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
206: } else {
207: if (index != escaped_index) {
208: efree(escaped_index);
209: }
210: zval_dtor(val);
211: efree(var_orig);
212: return;
213: }
214: }
215: if (index != escaped_index) {
216: efree(escaped_index);
217: }
218: }
219: symtable1 = Z_ARRVAL_PP(gpc_element_p);
220: /* ip pointed to the '[' character, now obtain the key */
221: index = index_s;
222: index_len = new_idx_len;
223:
224: ip++;
225: if (*ip == '[') {
226: is_array = 1;
227: *ip = 0;
228: } else {
229: goto plain_var;
230: }
231: }
232: } else {
233: plain_var:
234: MAKE_STD_ZVAL(gpc_element);
235: gpc_element->value = val->value;
236: Z_TYPE_P(gpc_element) = Z_TYPE_P(val);
237: if (!index) {
238: if (zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p) == FAILURE) {
239: zval_ptr_dtor(&gpc_element);
240: }
241: } else {
242: if (PG(magic_quotes_gpc)) {
243: escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC);
244: } else {
245: escaped_index = index;
246: }
247: /*
248: * According to rfc2965, more specific paths are listed above the less specific ones.
249: * If we encounter a duplicate cookie name, we should skip it, since it is not possible
250: * to have the same (plain text) cookie name for the same path and we should not overwrite
251: * more specific cookies with the less specific ones.
252: */
253: if (PG(http_globals)[TRACK_VARS_COOKIE] &&
254: symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) &&
255: zend_symtable_exists(symtable1, escaped_index, index_len + 1)) {
256: zval_ptr_dtor(&gpc_element);
257: } else {
258: if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
259: if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
260: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
261: }
262: zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
263: } else {
264: zval_ptr_dtor(&gpc_element);
265: }
266: }
267: if (escaped_index != index) {
268: efree(escaped_index);
269: }
270: }
271: }
272: efree(var_orig);
273: }
274:
275: SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
276: {
277: char *var, *val, *e, *s, *p;
278: zval *array_ptr = (zval *) arg;
279:
280: if (SG(request_info).post_data == NULL) {
281: return;
282: }
283:
284: s = SG(request_info).post_data;
285: e = s + SG(request_info).post_data_length;
286:
287: while (s < e && (p = memchr(s, '&', (e - s)))) {
288: last_value:
289: if ((val = memchr(s, '=', (p - s)))) { /* have a value */
290: unsigned int val_len, new_val_len;
291:
292: var = s;
293:
294: php_url_decode(var, (val - s));
295: val++;
296: val_len = php_url_decode(val, (p - val));
297: val = estrndup(val, val_len);
298: if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
299: php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
300: }
301: efree(val);
302: }
303: s = p + 1;
304: }
305: if (s < e) {
306: p = e;
307: goto last_value;
308: }
309: }
310:
311: SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
312: {
313: /* TODO: check .ini setting here and apply user-defined input filter */
314: if(new_val_len) *new_val_len = val_len;
315: return 1;
316: }
317:
318: SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
319: {
320: char *res = NULL, *var, *val, *separator = NULL;
321: const char *c_var;
322: zval *array_ptr;
323: int free_buffer = 0;
324: char *strtok_buf = NULL;
325:
326: switch (arg) {
327: case PARSE_POST:
328: case PARSE_GET:
329: case PARSE_COOKIE:
330: ALLOC_ZVAL(array_ptr);
331: array_init(array_ptr);
332: INIT_PZVAL(array_ptr);
333: switch (arg) {
334: case PARSE_POST:
335: if (PG(http_globals)[TRACK_VARS_POST]) {
336: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
337: }
338: PG(http_globals)[TRACK_VARS_POST] = array_ptr;
339: break;
340: case PARSE_GET:
341: if (PG(http_globals)[TRACK_VARS_GET]) {
342: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]);
343: }
344: PG(http_globals)[TRACK_VARS_GET] = array_ptr;
345: break;
346: case PARSE_COOKIE:
347: if (PG(http_globals)[TRACK_VARS_COOKIE]) {
348: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]);
349: }
350: PG(http_globals)[TRACK_VARS_COOKIE] = array_ptr;
351: break;
352: }
353: break;
354: default:
355: array_ptr = destArray;
356: break;
357: }
358:
359: if (arg == PARSE_POST) {
360: sapi_handle_post(array_ptr TSRMLS_CC);
361: return;
362: }
363:
364: if (arg == PARSE_GET) { /* GET data */
365: c_var = SG(request_info).query_string;
366: if (c_var && *c_var) {
367: res = (char *) estrdup(c_var);
368: free_buffer = 1;
369: } else {
370: free_buffer = 0;
371: }
372: } else if (arg == PARSE_COOKIE) { /* Cookie data */
373: c_var = SG(request_info).cookie_data;
374: if (c_var && *c_var) {
375: res = (char *) estrdup(c_var);
376: free_buffer = 1;
377: } else {
378: free_buffer = 0;
379: }
380: } else if (arg == PARSE_STRING) { /* String data */
381: res = str;
382: free_buffer = 1;
383: }
384:
385: if (!res) {
386: return;
387: }
388:
389: switch (arg) {
390: case PARSE_GET:
391: case PARSE_STRING:
392: separator = (char *) estrdup(PG(arg_separator).input);
393: break;
394: case PARSE_COOKIE:
395: separator = ";\0";
396: break;
397: }
398:
399: var = php_strtok_r(res, separator, &strtok_buf);
400:
401: while (var) {
402: val = strchr(var, '=');
403:
404: if (arg == PARSE_COOKIE) {
405: /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */
406: while (isspace(*var)) {
407: var++;
408: }
409: if (var == val || *var == '\0') {
410: goto next_cookie;
411: }
412: }
413:
414: if (val) { /* have a value */
415: int val_len;
416: unsigned int new_val_len;
417:
418: *val++ = '\0';
419: php_url_decode(var, strlen(var));
420: val_len = php_url_decode(val, strlen(val));
421: val = estrndup(val, val_len);
422: if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
423: php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
424: }
425: efree(val);
426: } else {
427: int val_len;
428: unsigned int new_val_len;
429:
430: php_url_decode(var, strlen(var));
431: val_len = 0;
432: val = estrndup("", val_len);
433: if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
434: php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
435: }
436: efree(val);
437: }
438: next_cookie:
439: var = php_strtok_r(NULL, separator, &strtok_buf);
440: }
441:
442: if (arg != PARSE_COOKIE) {
443: efree(separator);
444: }
445:
446: if (free_buffer) {
447: efree(res);
448: }
449: }
450:
451: void _php_import_environment_variables(zval *array_ptr TSRMLS_DC)
452: {
453: char buf[128];
454: char **env, *p, *t = buf;
455: size_t alloc_size = sizeof(buf);
456: unsigned long nlen; /* ptrdiff_t is not portable */
457:
458: /* turn off magic_quotes while importing environment variables */
459: int magic_quotes_gpc = PG(magic_quotes_gpc);
460: PG(magic_quotes_gpc) = 0;
461:
462: for (env = environ; env != NULL && *env != NULL; env++) {
463: p = strchr(*env, '=');
464: if (!p) { /* malformed entry? */
465: continue;
466: }
467: nlen = p - *env;
468: if (nlen >= alloc_size) {
469: alloc_size = nlen + 64;
470: t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size));
471: }
472: memcpy(t, *env, nlen);
473: t[nlen] = '\0';
474: php_register_variable(t, p + 1, array_ptr TSRMLS_CC);
475: }
476: if (t != buf && t != NULL) {
477: efree(t);
478: }
479: PG(magic_quotes_gpc) = magic_quotes_gpc;
480: }
481:
482: zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC)
483: {
484: zend_printf("%s\n", name);
485: return 0; /* don't rearm */
486: }
487:
488: /* {{{ php_build_argv
489: */
490: static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
491: {
492: zval *arr, *argc, *tmp;
493: int count = 0;
494: char *ss, *space;
495:
496: if (!(PG(register_globals) || SG(request_info).argc || track_vars_array)) {
497: return;
498: }
499:
500: ALLOC_INIT_ZVAL(arr);
501: array_init(arr);
502:
503: /* Prepare argv */
504: if (SG(request_info).argc) { /* are we in cli sapi? */
505: int i;
506: for (i = 0; i < SG(request_info).argc; i++) {
507: ALLOC_ZVAL(tmp);
508: Z_TYPE_P(tmp) = IS_STRING;
509: Z_STRLEN_P(tmp) = strlen(SG(request_info).argv[i]);
510: Z_STRVAL_P(tmp) = estrndup(SG(request_info).argv[i], Z_STRLEN_P(tmp));
511: INIT_PZVAL(tmp);
512: if (zend_hash_next_index_insert(Z_ARRVAL_P(arr), &tmp, sizeof(zval *), NULL) == FAILURE) {
513: if (Z_TYPE_P(tmp) == IS_STRING) {
514: efree(Z_STRVAL_P(tmp));
515: }
516: }
517: }
518: } else if (s && *s) {
519: ss = s;
520: while (ss) {
521: space = strchr(ss, '+');
522: if (space) {
523: *space = '\0';
524: }
525: /* auto-type */
526: ALLOC_ZVAL(tmp);
527: Z_TYPE_P(tmp) = IS_STRING;
528: Z_STRLEN_P(tmp) = strlen(ss);
529: Z_STRVAL_P(tmp) = estrndup(ss, Z_STRLEN_P(tmp));
530: INIT_PZVAL(tmp);
531: count++;
532: if (zend_hash_next_index_insert(Z_ARRVAL_P(arr), &tmp, sizeof(zval *), NULL) == FAILURE) {
533: if (Z_TYPE_P(tmp) == IS_STRING) {
534: efree(Z_STRVAL_P(tmp));
535: }
536: }
537: if (space) {
538: *space = '+';
539: ss = space + 1;
540: } else {
541: ss = space;
542: }
543: }
544: }
545:
546: /* prepare argc */
547: ALLOC_INIT_ZVAL(argc);
548: if (SG(request_info).argc) {
549: Z_LVAL_P(argc) = SG(request_info).argc;
550: } else {
551: Z_LVAL_P(argc) = count;
552: }
553: Z_TYPE_P(argc) = IS_LONG;
554:
555: if (PG(register_globals) || SG(request_info).argc) {
556: Z_ADDREF_P(arr);
557: Z_ADDREF_P(argc);
558: zend_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL);
559: zend_hash_add(&EG(symbol_table), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL);
560: }
561: if (track_vars_array) {
562: Z_ADDREF_P(arr);
563: Z_ADDREF_P(argc);
564: zend_hash_update(Z_ARRVAL_P(track_vars_array), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL);
565: zend_hash_update(Z_ARRVAL_P(track_vars_array), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL);
566: }
567: zval_ptr_dtor(&arr);
568: zval_ptr_dtor(&argc);
569: }
570: /* }}} */
571:
572: /* {{{ php_handle_special_queries
573: */
574: PHPAPI int php_handle_special_queries(TSRMLS_D)
575: {
576: if (PG(expose_php) && SG(request_info).query_string && SG(request_info).query_string[0] == '=') {
577: if (php_info_logos(SG(request_info).query_string + 1 TSRMLS_CC)) {
578: return 1;
579: } else if (!strcmp(SG(request_info).query_string + 1, PHP_CREDITS_GUID)) {
580: php_print_credits(PHP_CREDITS_ALL TSRMLS_CC);
581: return 1;
582: }
583: }
584: return 0;
585: }
586: /* }}} */
587:
588: /* {{{ php_register_server_variables
589: */
590: static inline void php_register_server_variables(TSRMLS_D)
591: {
592: zval *array_ptr = NULL;
593: /* turn off magic_quotes while importing server variables */
594: int magic_quotes_gpc = PG(magic_quotes_gpc);
595:
596: ALLOC_ZVAL(array_ptr);
597: array_init(array_ptr);
598: INIT_PZVAL(array_ptr);
599: if (PG(http_globals)[TRACK_VARS_SERVER]) {
600: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]);
601: }
602: PG(http_globals)[TRACK_VARS_SERVER] = array_ptr;
603: PG(magic_quotes_gpc) = 0;
604:
605: /* Server variables */
606: if (sapi_module.register_server_variables) {
607: sapi_module.register_server_variables(array_ptr TSRMLS_CC);
608: }
609:
610: /* PHP Authentication support */
611: if (SG(request_info).auth_user) {
612: php_register_variable("PHP_AUTH_USER", SG(request_info).auth_user, array_ptr TSRMLS_CC);
613: }
614: if (SG(request_info).auth_password) {
615: php_register_variable("PHP_AUTH_PW", SG(request_info).auth_password, array_ptr TSRMLS_CC);
616: }
617: if (SG(request_info).auth_digest) {
618: php_register_variable("PHP_AUTH_DIGEST", SG(request_info).auth_digest, array_ptr TSRMLS_CC);
619: }
620: /* store request init time */
621: {
622: zval new_entry;
623: Z_TYPE(new_entry) = IS_LONG;
624: Z_LVAL(new_entry) = sapi_get_request_time(TSRMLS_C);
625: php_register_variable_ex("REQUEST_TIME", &new_entry, array_ptr TSRMLS_CC);
626: }
627:
628: PG(magic_quotes_gpc) = magic_quotes_gpc;
629: }
630: /* }}} */
631:
632: /* {{{ php_autoglobal_merge
633: */
634: static void php_autoglobal_merge(HashTable *dest, HashTable *src TSRMLS_DC)
635: {
636: zval **src_entry, **dest_entry;
637: char *string_key;
638: uint string_key_len;
639: ulong num_key;
640: HashPosition pos;
641: int key_type;
642: int globals_check = (PG(register_globals) && (dest == (&EG(symbol_table))));
643:
644: zend_hash_internal_pointer_reset_ex(src, &pos);
645: while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) {
646: key_type = zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos);
647: if (Z_TYPE_PP(src_entry) != IS_ARRAY
648: || (key_type == HASH_KEY_IS_STRING && zend_hash_find(dest, string_key, string_key_len, (void **) &dest_entry) != SUCCESS)
649: || (key_type == HASH_KEY_IS_LONG && zend_hash_index_find(dest, num_key, (void **)&dest_entry) != SUCCESS)
650: || Z_TYPE_PP(dest_entry) != IS_ARRAY
651: ) {
652: Z_ADDREF_PP(src_entry);
653: if (key_type == HASH_KEY_IS_STRING) {
654: /* if register_globals is on and working with main symbol table, prevent overwriting of GLOBALS */
655: if (!globals_check || string_key_len != sizeof("GLOBALS") || memcmp(string_key, "GLOBALS", sizeof("GLOBALS") - 1)) {
656: zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
657: } else {
658: Z_DELREF_PP(src_entry);
659: }
660: } else {
661: zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL);
662: }
663: } else {
664: SEPARATE_ZVAL(dest_entry);
665: php_autoglobal_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry) TSRMLS_CC);
666: }
667: zend_hash_move_forward_ex(src, &pos);
668: }
669: }
670: /* }}} */
671:
672: static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC);
673: static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC);
674: static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRMLS_DC);
675:
676: /* {{{ php_hash_environment
677: */
678: int php_hash_environment(TSRMLS_D)
679: {
680: char *p;
681: unsigned char _gpc_flags[5] = {0, 0, 0, 0, 0};
682: zend_bool jit_initialization = (PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays));
683: struct auto_global_record {
684: char *name;
685: uint name_len;
686: char *long_name;
687: uint long_name_len;
688: zend_bool jit_initialization;
689: } auto_global_records[] = {
690: { "_POST", sizeof("_POST"), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), 0 },
691: { "_GET", sizeof("_GET"), "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), 0 },
692: { "_COOKIE", sizeof("_COOKIE"), "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), 0 },
693: { "_SERVER", sizeof("_SERVER"), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), 1 },
694: { "_ENV", sizeof("_ENV"), "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), 1 },
695: { "_FILES", sizeof("_FILES"), "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), 0 },
696: };
697: size_t num_track_vars = sizeof(auto_global_records)/sizeof(struct auto_global_record);
698: size_t i;
699:
700: /* jit_initialization = 0; */
701: for (i=0; i<num_track_vars; i++) {
702: PG(http_globals)[i] = NULL;
703: }
704:
705: for (p=PG(variables_order); p && *p; p++) {
706: switch(*p) {
707: case 'p':
708: case 'P':
709: if (!_gpc_flags[0] && !SG(headers_sent) && SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) {
710: sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); /* POST Data */
711: _gpc_flags[0] = 1;
712: if (PG(register_globals)) {
713: php_autoglobal_merge(&EG(symbol_table), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC);
714: }
715: }
716: break;
717: case 'c':
718: case 'C':
719: if (!_gpc_flags[1]) {
720: sapi_module.treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC); /* Cookie Data */
721: _gpc_flags[1] = 1;
722: if (PG(register_globals)) {
723: php_autoglobal_merge(&EG(symbol_table), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC);
724: }
725: }
726: break;
727: case 'g':
728: case 'G':
729: if (!_gpc_flags[2]) {
730: sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); /* GET Data */
731: _gpc_flags[2] = 1;
732: if (PG(register_globals)) {
733: php_autoglobal_merge(&EG(symbol_table), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC);
734: }
735: }
736: break;
737: case 'e':
738: case 'E':
739: if (!jit_initialization && !_gpc_flags[3]) {
740: zend_auto_global_disable_jit("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
741: php_auto_globals_create_env("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
742: _gpc_flags[3] = 1;
743: if (PG(register_globals)) {
744: php_autoglobal_merge(&EG(symbol_table), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV]) TSRMLS_CC);
745: }
746: }
747: break;
748: case 's':
749: case 'S':
750: if (!jit_initialization && !_gpc_flags[4]) {
751: zend_auto_global_disable_jit("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
752: php_register_server_variables(TSRMLS_C);
753: _gpc_flags[4] = 1;
754: if (PG(register_globals)) {
755: php_autoglobal_merge(&EG(symbol_table), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]) TSRMLS_CC);
756: }
757: }
758: break;
759: }
760: }
761:
762: /* argv/argc support */
763: if (PG(register_argc_argv)) {
764: php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
765: }
766:
767: for (i=0; i<num_track_vars; i++) {
768: if (jit_initialization && auto_global_records[i].jit_initialization) {
769: continue;
770: }
771: if (!PG(http_globals)[i]) {
772: ALLOC_ZVAL(PG(http_globals)[i]);
773: array_init(PG(http_globals)[i]);
774: INIT_PZVAL(PG(http_globals)[i]);
775: }
776:
777: Z_ADDREF_P(PG(http_globals)[i]);
778: zend_hash_update(&EG(symbol_table), auto_global_records[i].name, auto_global_records[i].name_len, &PG(http_globals)[i], sizeof(zval *), NULL);
779: if (PG(register_long_arrays)) {
780: zend_hash_update(&EG(symbol_table), auto_global_records[i].long_name, auto_global_records[i].long_name_len, &PG(http_globals)[i], sizeof(zval *), NULL);
781: Z_ADDREF_P(PG(http_globals)[i]);
782: }
783: }
784:
785: /* Create _REQUEST */
786: if (!jit_initialization) {
787: zend_auto_global_disable_jit("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
788: php_auto_globals_create_request("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
789: }
790:
791: return SUCCESS;
792: }
793: /* }}} */
794:
795: static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC)
796: {
797: if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) {
798: php_register_server_variables(TSRMLS_C);
799:
800: if (PG(register_argc_argv)) {
801: if (SG(request_info).argc) {
802: zval **argc, **argv;
803:
804: if (zend_hash_find(&EG(symbol_table), "argc", sizeof("argc"), (void**)&argc) == SUCCESS &&
805: zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void**)&argv) == SUCCESS) {
806: Z_ADDREF_PP(argc);
807: Z_ADDREF_PP(argv);
808: zend_hash_update(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), argv, sizeof(zval *), NULL);
809: zend_hash_update(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "argc", sizeof("argc"), argc, sizeof(zval *), NULL);
810: }
811: } else {
812: php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
813: }
814: }
815:
816: } else {
817: zval *server_vars=NULL;
818: ALLOC_ZVAL(server_vars);
819: array_init(server_vars);
820: INIT_PZVAL(server_vars);
821: if (PG(http_globals)[TRACK_VARS_SERVER]) {
822: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]);
823: }
824: PG(http_globals)[TRACK_VARS_SERVER] = server_vars;
825: }
826:
827: zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL);
828: Z_ADDREF_P(PG(http_globals)[TRACK_VARS_SERVER]);
829:
830: if (PG(register_long_arrays)) {
831: zend_hash_update(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL);
832: Z_ADDREF_P(PG(http_globals)[TRACK_VARS_SERVER]);
833: }
834:
835: return 0; /* don't rearm */
836: }
837:
838: static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC)
839: {
840: zval *env_vars = NULL;
841: ALLOC_ZVAL(env_vars);
842: array_init(env_vars);
843: INIT_PZVAL(env_vars);
844: if (PG(http_globals)[TRACK_VARS_ENV]) {
845: zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]);
846: }
847: PG(http_globals)[TRACK_VARS_ENV] = env_vars;
848:
849: if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) {
850: php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC);
851: }
852:
853: zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL);
854: Z_ADDREF_P(PG(http_globals)[TRACK_VARS_ENV]);
855:
856: if (PG(register_long_arrays)) {
857: zend_hash_update(&EG(symbol_table), "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL);
858: Z_ADDREF_P(PG(http_globals)[TRACK_VARS_ENV]);
859: }
860:
861: return 0; /* don't rearm */
862: }
863:
864: static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRMLS_DC)
865: {
866: zval *form_variables;
867: unsigned char _gpc_flags[3] = {0, 0, 0};
868: char *p;
869:
870: ALLOC_ZVAL(form_variables);
871: array_init(form_variables);
872: INIT_PZVAL(form_variables);
873:
874: if(PG(request_order) != NULL) {
875: p = PG(request_order);
876: } else {
877: p = PG(variables_order);
878: }
879:
880: for (; p && *p; p++) {
881: switch (*p) {
882: case 'g':
883: case 'G':
884: if (!_gpc_flags[0]) {
885: php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC);
886: _gpc_flags[0] = 1;
887: }
888: break;
889: case 'p':
890: case 'P':
891: if (!_gpc_flags[1]) {
892: php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC);
893: _gpc_flags[1] = 1;
894: }
895: break;
896: case 'c':
897: case 'C':
898: if (!_gpc_flags[2]) {
899: php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC);
900: _gpc_flags[2] = 1;
901: }
902: break;
903: }
904: }
905:
906: zend_hash_update(&EG(symbol_table), "_REQUEST", sizeof("_REQUEST"), &form_variables, sizeof(zval *), NULL);
907: return 0;
908: }
909:
910: void php_startup_auto_globals(TSRMLS_D)
911: {
912: zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC);
913: zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC);
914: zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL TSRMLS_CC);
915: zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server TSRMLS_CC);
916: zend_register_auto_global("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env TSRMLS_CC);
917: zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request TSRMLS_CC);
918: zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC);
919: }
920:
921: /*
922: * Local variables:
923: * tab-width: 4
924: * c-basic-offset: 4
925: * End:
926: * vim600: sw=4 ts=4 fdm=marker
927: * vim<600: sw=4 ts=4
928: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>