PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main - php_variables.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 358 396 90.4 %
Date: 2015-08-04 Functions: 20 22 90.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 04 Aug 2015 09:11:18 +0000 (4 hours ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.