root/main/php_variables.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_register_variable
  2. php_register_variable_safe
  3. php_register_variable_ex
  4. add_post_var
  5. add_post_vars
  6. SAPI_POST_HANDLER_FUNC
  7. SAPI_INPUT_FILTER_FUNC
  8. SAPI_TREAT_DATA_FUNC
  9. _php_import_environment_variables
  10. php_std_auto_global_callback
  11. php_build_argv
  12. php_register_server_variables
  13. php_autoglobal_merge
  14. php_hash_environment
  15. php_auto_globals_create_get
  16. php_auto_globals_create_post
  17. php_auto_globals_create_cookie
  18. php_auto_globals_create_files
  19. php_auto_globals_create_server
  20. php_auto_globals_create_env
  21. php_auto_globals_create_request
  22. php_startup_auto_globals

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

/* [<][>][^][v][top][bottom][index][help] */