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: 427 472 90.5 %
Date: 2014-08-04 Functions: 20 22 90.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:19 +0000 (25 days ago)

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