php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
mb_gpc.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Rui Hirokawa <hirokawa@php.net> |
14 | Moriyoshi Koizumi <moriyoshi@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18/* {{{ includes */
19#include "php.h"
20#include "php_variables.h"
22#include "mbstring.h"
23#include "ext/standard/url.h"
24
25#include "php_globals.h"
26#include "TSRM.h"
27
28#include "mb_gpc.h"
29/* }}} */
30
32
33/* {{{ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
34 * http input processing */
36{
37 char *res = NULL, *separator=NULL;
38 const char *c_var;
39 zval v_array;
40 int free_buffer=0;
41 const mbfl_encoding *detected;
43
45 php_default_treat_data(arg, str, destArray);
46 return;
47 }
48
49 switch (arg) {
50 case PARSE_POST:
51 case PARSE_GET:
52 case PARSE_COOKIE:
53 array_init(&v_array);
54 switch (arg) {
55 case PARSE_POST:
56 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &v_array);
57 break;
58 case PARSE_GET:
59 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_GET], &v_array);
60 break;
61 case PARSE_COOKIE:
62 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_COOKIE], &v_array);
63 break;
64 }
65 break;
66 default:
67 ZVAL_COPY_VALUE(&v_array, destArray);
68 break;
69 }
70
71 switch (arg) {
72 case PARSE_POST:
73 sapi_handle_post(&v_array);
74 return;
75 case PARSE_GET: /* GET data */
76 c_var = SG(request_info).query_string;
77 if (c_var && *c_var) {
78 res = (char *) estrdup(c_var);
79 free_buffer = 1;
80 }
81 break;
82 case PARSE_COOKIE: /* Cookie data */
83 c_var = SG(request_info).cookie_data;
84 if (c_var && *c_var) {
85 res = (char *) estrdup(c_var);
86 free_buffer = 1;
87 }
88 break;
89 case PARSE_STRING: /* String data */
90 res = str;
91 free_buffer = 1;
92 break;
93 }
94
95 if (!res) {
96 return;
97 }
98
99 switch (arg) {
100 case PARSE_POST:
101 case PARSE_GET:
102 case PARSE_STRING:
103 separator = (char *) estrdup(PG(arg_separator).input);
104 break;
105 case PARSE_COOKIE:
106 separator = ";\0";
107 break;
108 }
109
110 switch (arg) {
111 case PARSE_POST:
113 break;
114 case PARSE_GET:
116 break;
117 case PARSE_COOKIE:
119 break;
120 case PARSE_STRING:
122 break;
123 }
124
125 info.data_type = arg;
126 info.separator = separator;
127 info.report_errors = false;
131
132 MBSTRG(illegalchars) = 0;
133
134 detected = _php_mb_encoding_handler_ex(&info, &v_array, res);
135 MBSTRG(http_input_identify) = detected;
136
137 if (detected) {
138 switch(arg){
139 case PARSE_POST:
141 break;
142 case PARSE_GET:
144 break;
145 case PARSE_COOKIE:
147 break;
148 case PARSE_STRING:
150 break;
151 }
152 }
153
154 if (arg != PARSE_COOKIE) {
155 efree(separator);
156 }
157
158 if (free_buffer) {
159 efree(res);
160 }
161}
162/* }}} */
163
164/* {{{ mbfl_no_encoding _php_mb_encoding_handler_ex() */
166{
167 char *var, *val;
168 char *strtok_buf = NULL, **val_list = NULL;
169 size_t n, num = 1, *len_list = NULL;
170 size_t new_val_len;
171 const mbfl_encoding *from_encoding = NULL;
172
173 if (!res || *res == '\0') {
174 goto out;
175 }
176
177 /* count variables contained in `res`.
178 * separator may contain multiple separator chars; ANY of them demarcate variables */
179 for (char *s1 = res; *s1; s1++) {
180 for (const char *s2 = info->separator; *s2; s2++) {
181 if (*s1 == *s2) {
182 num++;
183 }
184 }
185 }
186 num *= 2; /* need space for variable name and value */
187
188 val_list = (char **)ecalloc(num, sizeof(char *));
189 len_list = (size_t *)ecalloc(num, sizeof(size_t));
190
191 /* split and decode the query */
192 n = 0;
193 var = php_strtok_r(res, info->separator, &strtok_buf);
194 while (var) {
195 val = strchr(var, '=');
196 if (val) { /* have a value */
197 len_list[n] = php_url_decode(var, val-var);
198 val_list[n] = var;
199 n++;
200
201 *val++ = '\0';
202 val_list[n] = val;
203 len_list[n] = php_url_decode(val, strlen(val));
204 } else {
205 len_list[n] = php_url_decode(var, strlen(var));
206 val_list[n] = var;
207 n++;
208
209 val_list[n] = "";
210 len_list[n] = 0;
211 }
212 n++;
213 var = php_strtok_r(NULL, info->separator, &strtok_buf);
214 }
215
216 zend_long max_input_vars = REQUEST_PARSE_BODY_OPTION_GET(max_input_vars, PG(max_input_vars));
217 if (ZEND_SIZE_T_GT_ZEND_LONG(n, max_input_vars * 2)) {
218 php_error_docref(NULL, E_WARNING, "Input variables exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_vars in php.ini.", max_input_vars);
219 goto out;
220 }
221
222 num = n; /* make sure to process initialized vars only */
223
224 /* initialize converter */
225 if (info->num_from_encodings == 0) {
226 from_encoding = &mbfl_encoding_pass;
227 } else if (info->num_from_encodings == 1) {
228 from_encoding = info->from_encodings[0];
229 } else {
230 from_encoding = mb_guess_encoding_for_strings((const unsigned char**)val_list, len_list, num, info->from_encodings, info->num_from_encodings, MBSTRG(strict_detection), false);
231 if (!from_encoding) {
232 if (info->report_errors) {
233 php_error_docref(NULL, E_WARNING, "Unable to detect encoding");
234 }
235 from_encoding = &mbfl_encoding_pass;
236 }
237 }
238
239 /* convert encoding */
240 n = 0;
241 while (n < num) {
242 if (from_encoding != &mbfl_encoding_pass && info->to_encoding != &mbfl_encoding_pass) {
243 unsigned int num_errors = 0;
244 zend_string *converted_var = mb_fast_convert((unsigned char*)val_list[n], len_list[n], from_encoding, info->to_encoding, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode), &num_errors);
245 MBSTRG(illegalchars) += num_errors;
246 n++;
247
248 num_errors = 0;
249 zend_string *converted_val = mb_fast_convert((unsigned char*)val_list[n], len_list[n], from_encoding, info->to_encoding, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode), &num_errors);
250 MBSTRG(illegalchars) += num_errors;
251 n++;
252
253 /* `val` must be a pointer returned by `emalloc` */
254 val = estrndup(ZSTR_VAL(converted_val), ZSTR_LEN(converted_val));
255 if (sapi_module.input_filter(info->data_type, ZSTR_VAL(converted_var), &val, ZSTR_LEN(converted_val), &new_val_len)) {
256 /* add variable to symbol table */
257 php_register_variable_safe(ZSTR_VAL(converted_var), val, new_val_len, array_ptr);
258 }
259 zend_string_free(converted_var);
260 zend_string_free(converted_val);
261 } else {
262 var = val_list[n++];
263 val = estrndup(val_list[n], len_list[n]);
264 if (sapi_module.input_filter(info->data_type, var, &val, len_list[n], &new_val_len)) {
265 php_register_variable_safe(var, val, new_val_len, array_ptr);
266 }
267 n++;
268 }
269 efree(val);
270 }
271
272out:
273 if (val_list != NULL) {
274 efree((void *)val_list);
275 }
276 if (len_list != NULL) {
277 efree((void *)len_list);
278 }
279
280 return from_encoding;
281}
282/* }}} */
283
284/* {{{ SAPI_POST_HANDLER_FUNC(php_mb_post_handler) */
285SAPI_POST_HANDLER_FUNC(php_mb_post_handler)
286{
287 const mbfl_encoding *detected;
289 zend_string *post_data_str = NULL;
290
292
293 info.data_type = PARSE_POST;
294 info.separator = "&";
295 info.report_errors = false;
299
300 php_stream_rewind(SG(request_info).request_body);
301 post_data_str = php_stream_copy_to_mem(SG(request_info).request_body, PHP_STREAM_COPY_ALL, 0);
302 detected = _php_mb_encoding_handler_ex(&info, arg, post_data_str ? ZSTR_VAL(post_data_str) : NULL);
303 if (post_data_str) {
304 zend_string_release_ex(post_data_str, 0);
305 }
306
307 MBSTRG(http_input_identify) = detected;
308 if (detected) {
310 }
311}
312/* }}} */
SAPI_API sapi_module_struct sapi_module
Definition SAPI.c:65
SAPI_API void sapi_handle_post(void *arg)
Definition SAPI.c:161
#define REQUEST_PARSE_BODY_OPTION_GET(name, fallback)
Definition SAPI.h:127
#define SG(v)
Definition SAPI.h:160
#define SAPI_POST_HANDLER_FUNC(post_handler)
Definition SAPI.h:312
#define SAPI_TREAT_DATA_FUNC(treat_data)
Definition SAPI.h:314
strchr(string $haystack, string $needle, bool $before_needle=false)
zend_long n
Definition ffi.c:4979
zend_string * res
Definition ffi.c:4692
zval * arg
Definition ffi.c:3975
zval * val
Definition ffi.c:4262
#define NULL
Definition gdcache.h:45
PHPAPI size_t php_url_decode(char *str, size_t len)
Definition url.c:582
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
const mbfl_encoding * _php_mb_encoding_handler_ex(const php_mb_encoding_handler_info_t *info, zval *array_ptr, char *res)
Definition mb_gpc.c:165
struct _php_mb_encoding_handler_info_t php_mb_encoding_handler_info_t
const mbfl_encoding mbfl_encoding_pass
zend_string * mb_fast_convert(unsigned char *in, size_t in_len, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors)
MBSTRING_API const mbfl_encoding * mb_guess_encoding_for_strings(const unsigned char **strings, size_t *str_lengths, size_t n, const mbfl_encoding **elist, unsigned int elist_size, bool strict, bool order_significant)
Definition mbstring.c:3360
#define MBSTRING_API
Definition mbstring.h:39
size_t http_input_list_size
Definition mbstring.h:84
const mbfl_encoding ** http_input_list
Definition mbstring.h:83
const mbfl_encoding * internal_encoding
Definition mbstring.h:74
uint32_t current_filter_illegal_substchar
Definition mbstring.h:95
const mbfl_encoding * http_input_identify_string
Definition mbstring.h:82
int current_filter_illegal_mode
Definition mbstring.h:94
const mbfl_encoding * http_input_identify_post
Definition mbstring.h:80
#define MBSTRG(v)
Definition mbstring.h:118
const mbfl_encoding * http_input_identify
Definition mbstring.h:78
size_t illegalchars
Definition mbstring.h:99
bool strict_detection
Definition mbstring.h:98
bool encoding_translation
Definition mbstring.h:97
const mbfl_encoding * http_input_identify_get
Definition mbstring.h:79
const mbfl_encoding * http_input_identify_cookie
Definition mbstring.h:81
#define TRACK_VARS_GET
Definition php_globals.h:41
#define TRACK_VARS_POST
Definition php_globals.h:40
#define TRACK_VARS_COOKIE
Definition php_globals.h:42
#define PG(v)
Definition php_globals.h:31
PHPAPI char * php_strtok_r(char *s, const char *delim, char **last)
Definition reentrancy.c:263
#define php_stream_rewind(stream)
#define PHP_STREAM_COPY_ALL
#define php_stream_copy_to_mem(src, maxlen, persistent)
PHPAPI void php_register_variable_safe(const char *var, const char *strval, size_t str_len, zval *track_vars_array)
#define PARSE_STRING
#define PARSE_COOKIE
#define PARSE_GET
#define PARSE_POST
const mbfl_encoding ** from_encodings
Definition mb_gpc.h:26
const mbfl_encoding * to_encoding
Definition mb_gpc.h:25
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)
Definition zend_API.h:270
#define array_init(arg)
Definition zend_API.h:537
#define estrndup(s, length)
Definition zend_alloc.h:165
#define ecalloc(nmemb, size)
Definition zend_alloc.h:158
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
struct _zval_struct zval
strlen(string $string)
zend_string_release_ex(func->internal_function.function_name, 0)
#define E_WARNING
Definition zend_errors.h:24
int32_t zend_long
Definition zend_long.h:42
#define ZEND_LONG_FMT
Definition zend_long.h:87
struct _zend_string zend_string
#define ZEND_SIZE_T_GT_ZEND_LONG(size, zlong)
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define ZVAL_COPY_VALUE(z, v)
out($f, $s)