Back to index

php5  5.3.10
mb_gpc.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Rui Hirokawa <hirokawa@php.net>                              |
00016    |         Moriyoshi Koizumi <moriyoshi@php.net>                        |
00017    +----------------------------------------------------------------------+
00018  */
00019 
00020 /* $Id: mb_gpc.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 /* {{{ includes */
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include "php.h"
00028 #include "php_ini.h"
00029 #include "php_variables.h"
00030 #include "mbstring.h"
00031 #include "ext/standard/php_string.h"
00032 #include "ext/standard/php_mail.h"
00033 #include "ext/standard/url.h"
00034 #include "main/php_output.h"
00035 #include "ext/standard/info.h"
00036 
00037 #include "php_variables.h"
00038 #include "php_globals.h"
00039 #include "rfc1867.h"
00040 #include "php_content_types.h"
00041 #include "SAPI.h"
00042 #include "TSRM.h"
00043 
00044 #include "mb_gpc.h"
00045 /* }}} */
00046 
00047 #if HAVE_MBSTRING
00048 
00049 ZEND_EXTERN_MODULE_GLOBALS(mbstring)
00050 
00051 /* {{{ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
00052  * http input processing */
00053 MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
00054 {
00055        char *res = NULL, *separator=NULL;
00056        const char *c_var;
00057        zval *array_ptr;
00058        int free_buffer=0;
00059        enum mbfl_no_encoding detected;
00060        php_mb_encoding_handler_info_t info;
00061 
00062        if (arg != PARSE_STRING) {
00063               char *value = zend_ini_string("mbstring.internal_encoding", sizeof("mbstring.internal_encoding"), 0);
00064               _php_mb_ini_mbstring_internal_encoding_set(value, value ? strlen(value): 0 TSRMLS_CC);
00065        }
00066 
00067        if (!MBSTRG(encoding_translation)) {
00068               php_default_treat_data(arg, str, destArray TSRMLS_CC);
00069               return;
00070        }
00071 
00072        switch (arg) {
00073               case PARSE_POST:
00074               case PARSE_GET:
00075               case PARSE_COOKIE:
00076                      ALLOC_ZVAL(array_ptr);
00077                      array_init(array_ptr);
00078                      INIT_PZVAL(array_ptr);
00079                      switch (arg) {
00080                             case PARSE_POST:
00081                                    PG(http_globals)[TRACK_VARS_POST] = array_ptr;
00082                                    break;
00083                             case PARSE_GET:
00084                                    PG(http_globals)[TRACK_VARS_GET] = array_ptr;
00085                                    break;
00086                             case PARSE_COOKIE:
00087                                    PG(http_globals)[TRACK_VARS_COOKIE] = array_ptr;
00088                                    break;
00089                      }
00090                      break;
00091               default:
00092                      array_ptr=destArray;
00093                      break;
00094        }
00095 
00096        if (arg==PARSE_POST) { 
00097               sapi_handle_post(array_ptr TSRMLS_CC);
00098               return;
00099        }
00100 
00101        if (arg == PARSE_GET) {            /* GET data */
00102               c_var = SG(request_info).query_string;
00103               if (c_var && *c_var) {
00104                      res = (char *) estrdup(c_var);
00105                      free_buffer = 1;
00106               } else {
00107                      free_buffer = 0;
00108               }
00109        } else if (arg == PARSE_COOKIE) {         /* Cookie data */
00110               c_var = SG(request_info).cookie_data;
00111               if (c_var && *c_var) {
00112                      res = (char *) estrdup(c_var);
00113                      free_buffer = 1;
00114               } else {
00115                      free_buffer = 0;
00116               }
00117        } else if (arg == PARSE_STRING) {         /* String data */
00118               res = str;
00119               free_buffer = 1;
00120        }
00121 
00122        if (!res) {
00123               return;
00124        }
00125 
00126        switch (arg) {
00127        case PARSE_POST:
00128        case PARSE_GET:
00129        case PARSE_STRING:
00130               separator = (char *) estrdup(PG(arg_separator).input);
00131               break;
00132        case PARSE_COOKIE:
00133               separator = ";\0";
00134               break;
00135        }
00136        
00137        switch(arg) {
00138        case PARSE_POST:
00139               MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
00140               break;
00141        case PARSE_GET:
00142               MBSTRG(http_input_identify_get) = mbfl_no_encoding_invalid;
00143               break;
00144        case PARSE_COOKIE:
00145               MBSTRG(http_input_identify_cookie) = mbfl_no_encoding_invalid;
00146               break;
00147        case PARSE_STRING:
00148               MBSTRG(http_input_identify_string) = mbfl_no_encoding_invalid;
00149               break;
00150        }
00151 
00152        info.data_type              = arg;
00153        info.separator              = separator; 
00154        info.force_register_globals = 0;
00155        info.report_errors          = 0;
00156        info.to_encoding            = MBSTRG(internal_encoding);
00157        info.to_language            = MBSTRG(language);
00158        info.from_encodings         = MBSTRG(http_input_list);
00159        info.num_from_encodings     = MBSTRG(http_input_list_size); 
00160        info.from_language          = MBSTRG(language);
00161 
00162        MBSTRG(illegalchars) = 0;
00163 
00164        detected = _php_mb_encoding_handler_ex(&info, array_ptr, res TSRMLS_CC);
00165        MBSTRG(http_input_identify) = detected;
00166 
00167        if (detected != mbfl_no_encoding_invalid) {
00168               switch(arg){
00169               case PARSE_POST:
00170                      MBSTRG(http_input_identify_post) = detected;
00171                      break;
00172               case PARSE_GET:
00173                      MBSTRG(http_input_identify_get) = detected;
00174                      break;
00175               case PARSE_COOKIE:
00176                      MBSTRG(http_input_identify_cookie) = detected;
00177                      break;
00178               case PARSE_STRING:
00179                      MBSTRG(http_input_identify_string) = detected;
00180                      break;
00181               }
00182        }
00183 
00184        if (arg != PARSE_COOKIE) {
00185               efree(separator);
00186        }
00187 
00188        if (free_buffer) {
00189               efree(res);
00190        }
00191 }
00192 /* }}} */
00193 
00194 /* {{{ mbfl_no_encoding _php_mb_encoding_handler_ex() */
00195 enum mbfl_no_encoding _php_mb_encoding_handler_ex(const php_mb_encoding_handler_info_t *info, zval *arg, char *res TSRMLS_DC)
00196 {
00197        char *var, *val;
00198        const char *s1, *s2;
00199        char *strtok_buf = NULL, **val_list = NULL;
00200        zval *array_ptr = (zval *) arg;
00201        int n, num, *len_list = NULL;
00202        unsigned int val_len, new_val_len;
00203        mbfl_string string, resvar, resval;
00204        enum mbfl_no_encoding from_encoding = mbfl_no_encoding_invalid;
00205        mbfl_encoding_detector *identd = NULL; 
00206        mbfl_buffer_converter *convd = NULL;
00207        int prev_rg_state = 0;
00208 
00209        mbfl_string_init_set(&string, info->to_language, info->to_encoding);
00210        mbfl_string_init_set(&resvar, info->to_language, info->to_encoding);
00211        mbfl_string_init_set(&resval, info->to_language, info->to_encoding);
00212 
00213        /* register_globals stuff
00214         * XXX: this feature is going to be deprecated? */
00215 
00216        if (info->force_register_globals && !(prev_rg_state = PG(register_globals))) {
00217               zend_alter_ini_entry("register_globals", sizeof("register_globals"), "1", sizeof("1")-1, PHP_INI_PERDIR, PHP_INI_STAGE_RUNTIME);
00218        }
00219 
00220        if (!res || *res == '\0') {
00221               goto out;
00222        }
00223        
00224        /* count the variables(separators) contained in the "res".
00225         * separator may contain multiple separator chars.
00226         */
00227        num = 1;
00228        for (s1=res; *s1 != '\0'; s1++) {
00229               for (s2=info->separator; *s2 != '\0'; s2++) {
00230                      if (*s1 == *s2) {
00231                             num++;
00232                      }      
00233               }
00234        }
00235        num *= 2; /* need space for variable name and value */
00236        
00237        val_list = (char **)ecalloc(num, sizeof(char *));
00238        len_list = (int *)ecalloc(num, sizeof(int));
00239 
00240        /* split and decode the query */
00241        n = 0;
00242        strtok_buf = NULL;
00243        var = php_strtok_r(res, info->separator, &strtok_buf);
00244        while (var)  {
00245               val = strchr(var, '=');
00246               if (val) { /* have a value */
00247                      len_list[n] = php_url_decode(var, val-var);
00248                      val_list[n] = var;
00249                      n++;
00250                      
00251                      *val++ = '\0';
00252                      val_list[n] = val;
00253                      len_list[n] = php_url_decode(val, strlen(val));
00254               } else {
00255                      len_list[n] = php_url_decode(var, strlen(var));
00256                      val_list[n] = var;
00257                      n++;
00258                      
00259                      val_list[n] = "";
00260                      len_list[n] = 0;
00261               }
00262               n++;
00263               var = php_strtok_r(NULL, info->separator, &strtok_buf);
00264        } 
00265        num = n; /* make sure to process initilized vars only */
00266        
00267        /* initialize converter */
00268        if (info->num_from_encodings <= 0) {
00269               from_encoding = mbfl_no_encoding_pass;
00270        } else if (info->num_from_encodings == 1) {
00271               from_encoding = info->from_encodings[0];
00272        } else {
00273               /* auto detect */
00274               from_encoding = mbfl_no_encoding_invalid;
00275               identd = mbfl_encoding_detector_new((enum mbfl_no_encoding *)info->from_encodings, info->num_from_encodings, MBSTRG(strict_detection));
00276               if (identd) {
00277                      n = 0;
00278                      while (n < num) {
00279                             string.val = (unsigned char *)val_list[n];
00280                             string.len = len_list[n];
00281                             if (mbfl_encoding_detector_feed(identd, &string)) {
00282                                    break;
00283                             }
00284                             n++;
00285                      }
00286                      from_encoding = mbfl_encoding_detector_judge(identd);
00287                      mbfl_encoding_detector_delete(identd);
00288               }
00289               if (from_encoding == mbfl_no_encoding_invalid) {
00290                      if (info->report_errors) {
00291                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect encoding");
00292                      }
00293                      from_encoding = mbfl_no_encoding_pass;
00294               }
00295        }
00296 
00297        convd = NULL;
00298        if (from_encoding != mbfl_no_encoding_pass) {
00299               convd = mbfl_buffer_converter_new(from_encoding, info->to_encoding, 0);
00300               if (convd != NULL) {
00301                      mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
00302                      mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
00303               } else {
00304                      if (info->report_errors) {
00305                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");
00306                      }
00307                      goto out;
00308               }
00309        }
00310 
00311        /* convert encoding */
00312        string.no_encoding = from_encoding;
00313 
00314        n = 0;
00315        while (n < num) {
00316               string.val = (unsigned char *)val_list[n];
00317               string.len = len_list[n];
00318               if (convd != NULL && mbfl_buffer_converter_feed_result(convd, &string, &resvar) != NULL) {
00319                      var = (char *)resvar.val;
00320               } else {
00321                      var = val_list[n];
00322               }
00323               n++;
00324               string.val = val_list[n];
00325               string.len = len_list[n];
00326               if (convd != NULL && mbfl_buffer_converter_feed_result(convd, &string, &resval) != NULL) {
00327                      val = resval.val;
00328                      val_len = resval.len;
00329               } else {
00330                      val = val_list[n];
00331                      val_len = len_list[n];
00332               }
00333               n++;
00334               /* we need val to be emalloc()ed */
00335               val = estrndup(val, val_len);
00336               if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
00337                      /* add variable to symbol table */
00338                      php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
00339               }
00340               efree(val);
00341               
00342               if (convd != NULL){
00343                      mbfl_string_clear(&resvar);
00344                      mbfl_string_clear(&resval);
00345               }
00346        }
00347 
00348 out:
00349        /* register_global stuff */
00350        if (info->force_register_globals && !prev_rg_state) {
00351               zend_alter_ini_entry("register_globals", sizeof("register_globals"), "0", sizeof("0")-1, PHP_INI_PERDIR, PHP_INI_STAGE_RUNTIME);
00352        }
00353 
00354        if (convd != NULL) {
00355               MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
00356               mbfl_buffer_converter_delete(convd);
00357        }
00358        if (val_list != NULL) {
00359               efree((void *)val_list);
00360        }
00361        if (len_list != NULL) {
00362               efree((void *)len_list);
00363        }
00364 
00365        return from_encoding;
00366 }
00367 /* }}} */
00368 
00369 /* {{{ SAPI_POST_HANDLER_FUNC(php_mb_post_handler) */
00370 SAPI_POST_HANDLER_FUNC(php_mb_post_handler)
00371 {
00372        enum mbfl_no_encoding detected;
00373        php_mb_encoding_handler_info_t info;
00374 
00375        MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
00376 
00377        info.data_type              = PARSE_POST;
00378        info.separator              = "&";
00379        info.force_register_globals = 0;
00380        info.report_errors          = 0;
00381        info.to_encoding            = MBSTRG(internal_encoding);
00382        info.to_language            = MBSTRG(language);
00383        info.from_encodings         = MBSTRG(http_input_list);
00384        info.num_from_encodings     = MBSTRG(http_input_list_size); 
00385        info.from_language          = MBSTRG(language);
00386 
00387        detected = _php_mb_encoding_handler_ex(&info, arg, SG(request_info).post_data TSRMLS_CC);
00388 
00389        MBSTRG(http_input_identify) = detected;
00390        if (detected != mbfl_no_encoding_invalid) {
00391               MBSTRG(http_input_identify_post) = detected;
00392        }
00393 }
00394 /* }}} */
00395 
00396 #endif /* HAVE_MBSTRING */
00397 
00398 /*
00399  * Local variables:
00400  * tab-width: 4
00401  * c-basic-offset: 4
00402  * End:
00403  * vim600: fdm=marker
00404  * vim: noet sw=4 ts=4
00405  */
00406