Annotation of embedaddon/php/main/php_variables.c, revision 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>