/src/php-src/main/php_variables.c
Line | Count | Source (jump to first uncovered line) |
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 | | | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | |
14 | | | Zeev Suraski <zeev@php.net> | |
15 | | +----------------------------------------------------------------------+ |
16 | | */ |
17 | | |
18 | | #include <stdio.h> |
19 | | #include "php.h" |
20 | | #include "ext/standard/php_standard.h" |
21 | | #include "ext/standard/credits.h" |
22 | | #include "zend_smart_str.h" |
23 | | #include "php_variables.h" |
24 | | #include "php_globals.h" |
25 | | #include "php_content_types.h" |
26 | | #include "SAPI.h" |
27 | | #include "zend_globals.h" |
28 | | #include "zend_exceptions.h" |
29 | | |
30 | | /* for systems that need to override reading of environment variables */ |
31 | | static void _php_import_environment_variables(zval *array_ptr); |
32 | | static void _php_load_environment_variables(zval *array_ptr); |
33 | | PHPAPI void (*php_import_environment_variables)(zval *array_ptr) = _php_import_environment_variables; |
34 | | PHPAPI void (*php_load_environment_variables)(zval *array_ptr) = _php_load_environment_variables; |
35 | | |
36 | | PHPAPI void php_register_variable(const char *var, const char *strval, zval *track_vars_array) |
37 | 156k | { |
38 | 156k | php_register_variable_safe(var, strval, strlen(strval), track_vars_array); |
39 | 156k | } |
40 | | |
41 | | /* binary-safe version */ |
42 | | PHPAPI void php_register_variable_safe(const char *var, const char *strval, size_t str_len, zval *track_vars_array) |
43 | 156k | { |
44 | 156k | zval new_entry; |
45 | 156k | assert(strval != NULL); |
46 | | |
47 | 156k | ZVAL_STRINGL_FAST(&new_entry, strval, str_len); |
48 | | |
49 | 156k | php_register_variable_ex(var, &new_entry, track_vars_array); |
50 | 156k | } |
51 | | |
52 | | static zend_always_inline void php_register_variable_quick(const char *name, size_t name_len, zval *val, HashTable *ht) |
53 | 8.65k | { |
54 | 8.65k | zend_string *key = zend_string_init_interned(name, name_len, 0); |
55 | | |
56 | 8.65k | zend_hash_update_ind(ht, key, val); |
57 | 8.65k | zend_string_release_ex(key, 0); |
58 | 8.65k | } |
59 | | |
60 | | PHPAPI void php_register_known_variable(const char *var_name, size_t var_name_len, zval *value, zval *track_vars_array) |
61 | 0 | { |
62 | 0 | HashTable *symbol_table = NULL; |
63 | |
|
64 | 0 | ZEND_ASSERT(var_name != NULL); |
65 | 0 | ZEND_ASSERT(var_name_len != 0); |
66 | 0 | ZEND_ASSERT(track_vars_array != NULL && Z_TYPE_P(track_vars_array) == IS_ARRAY); |
67 | | |
68 | 0 | symbol_table = Z_ARRVAL_P(track_vars_array); |
69 | |
|
70 | 0 | #if ZEND_DEBUG |
71 | | /* Verify the name is valid for a PHP variable */ |
72 | 0 | ZEND_ASSERT(!(var_name_len == strlen("GLOBALS") && !memcmp(var_name, "GLOBALS", strlen("GLOBALS")))); |
73 | 0 | ZEND_ASSERT(!(var_name_len == strlen("this") && !memcmp(var_name, "this", strlen("this")))); |
74 | | |
75 | | /* Assert that the variable name is not numeric */ |
76 | 0 | zend_ulong idx; |
77 | 0 | ZEND_ASSERT(!ZEND_HANDLE_NUMERIC_STR(var_name, var_name_len, idx)); |
78 | | /* ensure that we don't have null bytes, spaces, dots, or array bracket in the variable name (not binary safe) */ |
79 | 0 | const char *p = var_name; |
80 | 0 | for (size_t l = 0; l < var_name_len; l++) { |
81 | 0 | ZEND_ASSERT(*p != '\0' && *p != ' ' && *p != '.' && *p != '['); |
82 | 0 | p++; |
83 | 0 | } |
84 | | |
85 | | /* Do not allow to register cookies this way */ |
86 | 0 | ZEND_ASSERT(Z_TYPE(PG(http_globals)[TRACK_VARS_COOKIE]) == IS_UNDEF || |
87 | 0 | Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]) != symbol_table); |
88 | 0 | #endif |
89 | | |
90 | 0 | php_register_variable_quick(var_name, var_name_len, value, symbol_table); |
91 | 0 | } |
92 | | |
93 | | /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- |
94 | | * Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ |
95 | | static bool php_is_forbidden_variable_name(const char *mangled_name, size_t mangled_name_len, const char *pre_mangled_name) |
96 | 5 | { |
97 | 5 | if (mangled_name_len >= sizeof("__Host-")-1 && strncmp(mangled_name, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(pre_mangled_name, "__Host-", sizeof("__Host-")-1) != 0) { |
98 | 0 | return true; |
99 | 0 | } |
100 | | |
101 | 5 | if (mangled_name_len >= sizeof("__Secure-")-1 && strncmp(mangled_name, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(pre_mangled_name, "__Secure-", sizeof("__Secure-")-1) != 0) { |
102 | 0 | return true; |
103 | 0 | } |
104 | | |
105 | 5 | return false; |
106 | 5 | } |
107 | | |
108 | | PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *track_vars_array) |
109 | 156k | { |
110 | 156k | char *p = NULL; |
111 | 156k | char *ip = NULL; /* index pointer */ |
112 | 156k | char *index; |
113 | 156k | char *var, *var_orig; |
114 | 156k | size_t var_len, index_len; |
115 | 156k | zval gpc_element, *gpc_element_p; |
116 | 156k | bool is_array = 0; |
117 | 156k | HashTable *symtable1 = NULL; |
118 | 156k | ALLOCA_FLAG(use_heap) |
119 | | |
120 | 156k | assert(var_name != NULL); |
121 | | |
122 | 156k | if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) { |
123 | 5 | symtable1 = Z_ARRVAL_P(track_vars_array); |
124 | 5 | } |
125 | | |
126 | 156k | if (!symtable1) { |
127 | | /* Nothing to do */ |
128 | 156k | zval_ptr_dtor_nogc(val); |
129 | 156k | return; |
130 | 156k | } |
131 | | |
132 | | |
133 | | /* ignore leading spaces in the variable name */ |
134 | 5 | while (*var_name==' ') { |
135 | 0 | var_name++; |
136 | 0 | } |
137 | | |
138 | | /* |
139 | | * Prepare variable name |
140 | | */ |
141 | 5 | var_len = strlen(var_name); |
142 | 5 | var = var_orig = do_alloca(var_len + 1, use_heap); |
143 | 5 | memcpy(var_orig, var_name, var_len + 1); |
144 | | |
145 | | /* ensure that we don't have spaces or dots in the variable name (not binary safe) */ |
146 | 20 | for (p = var; *p; p++) { |
147 | 15 | if (*p == ' ' || *p == '.') { |
148 | 0 | *p='_'; |
149 | 15 | } else if (*p == '[') { |
150 | 0 | is_array = 1; |
151 | 0 | ip = p; |
152 | 0 | *p = 0; |
153 | 0 | break; |
154 | 0 | } |
155 | 15 | } |
156 | 5 | var_len = p - var; |
157 | | |
158 | 5 | if (var_len==0) { /* empty variable name, or variable name with a space in it */ |
159 | 0 | zval_ptr_dtor_nogc(val); |
160 | 0 | free_alloca(var_orig, use_heap); |
161 | 0 | return; |
162 | 0 | } |
163 | | |
164 | 5 | if (var_len == sizeof("this")-1 && EG(current_execute_data)) { |
165 | 0 | zend_execute_data *ex = EG(current_execute_data); |
166 | |
|
167 | 0 | while (ex) { |
168 | 0 | if (ex->func && ZEND_USER_CODE(ex->func->common.type)) { |
169 | 0 | if ((ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) |
170 | 0 | && ex->symbol_table == symtable1) { |
171 | 0 | if (memcmp(var, "this", sizeof("this")-1) == 0) { |
172 | 0 | zend_throw_error(NULL, "Cannot re-assign $this"); |
173 | 0 | zval_ptr_dtor_nogc(val); |
174 | 0 | free_alloca(var_orig, use_heap); |
175 | 0 | return; |
176 | 0 | } |
177 | 0 | } |
178 | 0 | break; |
179 | 0 | } |
180 | 0 | ex = ex->prev_execute_data; |
181 | 0 | } |
182 | 0 | } |
183 | | |
184 | | /* GLOBALS hijack attempt, reject parameter */ |
185 | 5 | if (symtable1 == &EG(symbol_table) && |
186 | 5 | var_len == sizeof("GLOBALS")-1 && |
187 | 5 | !memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) { |
188 | 0 | zval_ptr_dtor_nogc(val); |
189 | 0 | free_alloca(var_orig, use_heap); |
190 | 0 | return; |
191 | 0 | } |
192 | | |
193 | 5 | index = var; |
194 | 5 | index_len = var_len; |
195 | | |
196 | 5 | if (is_array) { |
197 | 0 | int nest_level = 0; |
198 | 0 | while (1) { |
199 | 0 | char *index_s; |
200 | 0 | size_t new_idx_len = 0; |
201 | |
|
202 | 0 | if(++nest_level > PG(max_input_nesting_level)) { |
203 | 0 | HashTable *ht; |
204 | | /* too many levels of nesting */ |
205 | |
|
206 | 0 | if (track_vars_array) { |
207 | 0 | ht = Z_ARRVAL_P(track_vars_array); |
208 | 0 | zend_symtable_str_del(ht, var, var_len); |
209 | 0 | } |
210 | |
|
211 | 0 | zval_ptr_dtor_nogc(val); |
212 | | |
213 | | /* do not output the error message to the screen, |
214 | | this helps us to avoid "information disclosure" */ |
215 | 0 | if (!PG(display_errors)) { |
216 | 0 | 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)); |
217 | 0 | } |
218 | 0 | free_alloca(var_orig, use_heap); |
219 | 0 | return; |
220 | 0 | } |
221 | | |
222 | 0 | ip++; |
223 | 0 | index_s = ip; |
224 | 0 | if (isspace(*ip)) { |
225 | 0 | ip++; |
226 | 0 | } |
227 | 0 | if (*ip==']') { |
228 | 0 | index_s = NULL; |
229 | 0 | } else { |
230 | 0 | ip = strchr(ip, ']'); |
231 | 0 | if (!ip) { |
232 | | /* not an index; un-terminate the var name */ |
233 | 0 | *(index_s - 1) = '_'; |
234 | | /* PHP variables cannot contain ' ', '.', '[' in their names, so we replace the characters with a '_' */ |
235 | 0 | for (p = index_s; *p; p++) { |
236 | 0 | if (*p == ' ' || *p == '.' || *p == '[') { |
237 | 0 | *p = '_'; |
238 | 0 | } |
239 | 0 | } |
240 | |
|
241 | 0 | index_len = 0; |
242 | 0 | if (index) { |
243 | 0 | index_len = strlen(index); |
244 | 0 | } |
245 | 0 | goto plain_var; |
246 | 0 | return; |
247 | 0 | } |
248 | 0 | *ip = 0; |
249 | 0 | new_idx_len = strlen(index_s); |
250 | 0 | } |
251 | | |
252 | 0 | if (!index) { |
253 | 0 | array_init(&gpc_element); |
254 | 0 | if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) { |
255 | 0 | zend_array_destroy(Z_ARR(gpc_element)); |
256 | 0 | zval_ptr_dtor_nogc(val); |
257 | 0 | free_alloca(var_orig, use_heap); |
258 | 0 | return; |
259 | 0 | } |
260 | 0 | } else { |
261 | 0 | if (php_is_forbidden_variable_name(index, index_len, var_name)) { |
262 | 0 | zval_ptr_dtor_nogc(val); |
263 | 0 | free_alloca(var_orig, use_heap); |
264 | 0 | return; |
265 | 0 | } |
266 | | |
267 | 0 | gpc_element_p = zend_symtable_str_find(symtable1, index, index_len); |
268 | 0 | if (!gpc_element_p) { |
269 | 0 | zval tmp; |
270 | 0 | array_init(&tmp); |
271 | 0 | gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp); |
272 | 0 | } else { |
273 | 0 | if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) { |
274 | 0 | gpc_element_p = Z_INDIRECT_P(gpc_element_p); |
275 | 0 | } |
276 | 0 | if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) { |
277 | 0 | zval_ptr_dtor_nogc(gpc_element_p); |
278 | 0 | array_init(gpc_element_p); |
279 | 0 | } else { |
280 | 0 | SEPARATE_ARRAY(gpc_element_p); |
281 | 0 | } |
282 | 0 | } |
283 | 0 | } |
284 | 0 | symtable1 = Z_ARRVAL_P(gpc_element_p); |
285 | | /* ip pointed to the '[' character, now obtain the key */ |
286 | 0 | index = index_s; |
287 | 0 | index_len = new_idx_len; |
288 | |
|
289 | 0 | ip++; |
290 | 0 | if (*ip == '[') { |
291 | 0 | is_array = 1; |
292 | 0 | *ip = 0; |
293 | 0 | } else { |
294 | 0 | goto plain_var; |
295 | 0 | } |
296 | 0 | } |
297 | 5 | } else { |
298 | 5 | plain_var: |
299 | 5 | if (!index) { |
300 | 0 | if (zend_hash_next_index_insert(symtable1, val) == NULL) { |
301 | 0 | zval_ptr_dtor_nogc(val); |
302 | 0 | } |
303 | 5 | } else { |
304 | 5 | if (php_is_forbidden_variable_name(index, index_len, var_name)) { |
305 | 0 | zval_ptr_dtor_nogc(val); |
306 | 0 | free_alloca(var_orig, use_heap); |
307 | 0 | return; |
308 | 0 | } |
309 | | |
310 | 5 | zend_ulong idx; |
311 | | |
312 | | /* |
313 | | * According to rfc2965, more specific paths are listed above the less specific ones. |
314 | | * If we encounter a duplicate cookie name, we should skip it, since it is not possible |
315 | | * to have the same (plain text) cookie name for the same path and we should not overwrite |
316 | | * more specific cookies with the less specific ones. |
317 | | */ |
318 | 5 | if (Z_TYPE(PG(http_globals)[TRACK_VARS_COOKIE]) != IS_UNDEF && |
319 | 5 | symtable1 == Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]) && |
320 | 5 | zend_symtable_str_exists(symtable1, index, index_len)) { |
321 | 0 | zval_ptr_dtor_nogc(val); |
322 | 5 | } else if (ZEND_HANDLE_NUMERIC_STR(index, index_len, idx)) { |
323 | 0 | zend_hash_index_update(symtable1, idx, val); |
324 | 5 | } else { |
325 | 5 | php_register_variable_quick(index, index_len, val, symtable1); |
326 | 5 | } |
327 | 5 | } |
328 | 5 | } |
329 | 5 | free_alloca(var_orig, use_heap); |
330 | 5 | } |
331 | | |
332 | | typedef struct post_var_data { |
333 | | smart_str str; |
334 | | char *ptr; |
335 | | char *end; |
336 | | uint64_t cnt; |
337 | | |
338 | | /* Bytes in ptr that have already been scanned for '&' */ |
339 | | size_t already_scanned; |
340 | | } post_var_data_t; |
341 | | |
342 | | static bool add_post_var(zval *arr, post_var_data_t *var, bool eof) |
343 | 0 | { |
344 | 0 | char *start, *ksep, *vsep, *val; |
345 | 0 | size_t klen, vlen; |
346 | 0 | size_t new_vlen; |
347 | |
|
348 | 0 | if (var->ptr >= var->end) { |
349 | 0 | return 0; |
350 | 0 | } |
351 | | |
352 | 0 | start = var->ptr + var->already_scanned; |
353 | 0 | vsep = memchr(start, '&', var->end - start); |
354 | 0 | if (!vsep) { |
355 | 0 | if (!eof) { |
356 | 0 | var->already_scanned = var->end - var->ptr; |
357 | 0 | return 0; |
358 | 0 | } else { |
359 | 0 | vsep = var->end; |
360 | 0 | } |
361 | 0 | } |
362 | | |
363 | 0 | ksep = memchr(var->ptr, '=', vsep - var->ptr); |
364 | 0 | if (ksep) { |
365 | 0 | *ksep = '\0'; |
366 | | /* "foo=bar&" or "foo=&" */ |
367 | 0 | klen = ksep - var->ptr; |
368 | 0 | vlen = vsep - ++ksep; |
369 | 0 | } else { |
370 | 0 | ksep = ""; |
371 | | /* "foo&" */ |
372 | 0 | klen = vsep - var->ptr; |
373 | 0 | vlen = 0; |
374 | 0 | } |
375 | |
|
376 | 0 | php_url_decode(var->ptr, klen); |
377 | |
|
378 | 0 | val = estrndup(ksep, vlen); |
379 | 0 | if (vlen) { |
380 | 0 | vlen = php_url_decode(val, vlen); |
381 | 0 | } |
382 | |
|
383 | 0 | if (sapi_module.input_filter(PARSE_POST, var->ptr, &val, vlen, &new_vlen)) { |
384 | 0 | php_register_variable_safe(var->ptr, val, new_vlen, arr); |
385 | 0 | } |
386 | 0 | efree(val); |
387 | |
|
388 | 0 | var->ptr = vsep + (vsep != var->end); |
389 | 0 | var->already_scanned = 0; |
390 | 0 | return 1; |
391 | 0 | } |
392 | | |
393 | | static inline int add_post_vars(zval *arr, post_var_data_t *vars, bool eof) |
394 | 0 | { |
395 | 0 | uint64_t max_vars = REQUEST_PARSE_BODY_OPTION_GET(max_input_vars, PG(max_input_vars)); |
396 | |
|
397 | 0 | vars->ptr = ZSTR_VAL(vars->str.s); |
398 | 0 | vars->end = ZSTR_VAL(vars->str.s) + ZSTR_LEN(vars->str.s); |
399 | 0 | while (add_post_var(arr, vars, eof)) { |
400 | 0 | if (++vars->cnt > max_vars) { |
401 | 0 | php_error_docref(NULL, E_WARNING, |
402 | 0 | "Input variables exceeded %" PRIu64 ". " |
403 | 0 | "To increase the limit change max_input_vars in php.ini.", |
404 | 0 | max_vars); |
405 | 0 | return FAILURE; |
406 | 0 | } |
407 | 0 | } |
408 | | |
409 | 0 | if (!eof && ZSTR_VAL(vars->str.s) != vars->ptr) { |
410 | 0 | memmove(ZSTR_VAL(vars->str.s), vars->ptr, ZSTR_LEN(vars->str.s) = vars->end - vars->ptr); |
411 | 0 | } |
412 | 0 | return SUCCESS; |
413 | 0 | } |
414 | | |
415 | | #ifdef PHP_WIN32 |
416 | | #define SAPI_POST_HANDLER_BUFSIZ 16384 |
417 | | #else |
418 | 0 | # define SAPI_POST_HANDLER_BUFSIZ BUFSIZ |
419 | | #endif |
420 | | SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) |
421 | 0 | { |
422 | 0 | zval *arr = (zval *) arg; |
423 | 0 | php_stream *s = SG(request_info).request_body; |
424 | 0 | post_var_data_t post_data; |
425 | |
|
426 | 0 | if (s && SUCCESS == php_stream_rewind(s)) { |
427 | 0 | memset(&post_data, 0, sizeof(post_data)); |
428 | |
|
429 | 0 | while (!php_stream_eof(s)) { |
430 | 0 | char buf[SAPI_POST_HANDLER_BUFSIZ] = {0}; |
431 | 0 | ssize_t len = php_stream_read(s, buf, SAPI_POST_HANDLER_BUFSIZ); |
432 | |
|
433 | 0 | if (len > 0) { |
434 | 0 | smart_str_appendl(&post_data.str, buf, len); |
435 | |
|
436 | 0 | if (SUCCESS != add_post_vars(arr, &post_data, 0)) { |
437 | 0 | smart_str_free(&post_data.str); |
438 | 0 | return; |
439 | 0 | } |
440 | 0 | } |
441 | | |
442 | 0 | if (len != SAPI_POST_HANDLER_BUFSIZ){ |
443 | 0 | break; |
444 | 0 | } |
445 | 0 | } |
446 | | |
447 | 0 | if (post_data.str.s) { |
448 | 0 | add_post_vars(arr, &post_data, 1); |
449 | 0 | smart_str_free(&post_data.str); |
450 | 0 | } |
451 | 0 | } |
452 | 0 | } |
453 | | #undef SAPI_POST_HANDLER_BUFSIZ |
454 | | |
455 | | SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) |
456 | 5 | { |
457 | | /* TODO: check .ini setting here and apply user-defined input filter */ |
458 | 5 | if(new_val_len) *new_val_len = val_len; |
459 | 5 | return 1; |
460 | 5 | } |
461 | | |
462 | | SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) |
463 | 600k | { |
464 | 600k | char *res = NULL, *var, *val, *separator = NULL; |
465 | 600k | const char *c_var; |
466 | 600k | zval array; |
467 | 600k | int free_buffer = 0; |
468 | 600k | char *strtok_buf = NULL; |
469 | 600k | zend_long count = 0; |
470 | | |
471 | 600k | ZVAL_UNDEF(&array); |
472 | 600k | switch (arg) { |
473 | 0 | case PARSE_POST: |
474 | 300k | case PARSE_GET: |
475 | 600k | case PARSE_COOKIE: |
476 | 600k | array_init(&array); |
477 | 600k | switch (arg) { |
478 | 0 | case PARSE_POST: |
479 | 0 | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_POST]); |
480 | 0 | ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &array); |
481 | 0 | break; |
482 | 300k | case PARSE_GET: |
483 | 300k | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_GET]); |
484 | 300k | ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_GET], &array); |
485 | 300k | break; |
486 | 300k | case PARSE_COOKIE: |
487 | 300k | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_COOKIE]); |
488 | 300k | ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_COOKIE], &array); |
489 | 300k | break; |
490 | 600k | } |
491 | 600k | break; |
492 | 600k | default: |
493 | 5 | ZVAL_COPY_VALUE(&array, destArray); |
494 | 5 | break; |
495 | 600k | } |
496 | | |
497 | 600k | if (arg == PARSE_POST) { |
498 | 0 | sapi_handle_post(&array); |
499 | 0 | return; |
500 | 0 | } |
501 | | |
502 | 600k | if (arg == PARSE_GET) { /* GET data */ |
503 | 300k | c_var = SG(request_info).query_string; |
504 | 300k | if (c_var && *c_var) { |
505 | 0 | res = (char *) estrdup(c_var); |
506 | 0 | free_buffer = 1; |
507 | 300k | } else { |
508 | 300k | free_buffer = 0; |
509 | 300k | } |
510 | 300k | } else if (arg == PARSE_COOKIE) { /* Cookie data */ |
511 | 300k | c_var = SG(request_info).cookie_data; |
512 | 300k | if (c_var && *c_var) { |
513 | 0 | res = (char *) estrdup(c_var); |
514 | 0 | free_buffer = 1; |
515 | 300k | } else { |
516 | 300k | free_buffer = 0; |
517 | 300k | } |
518 | 300k | } else if (arg == PARSE_STRING) { /* String data */ |
519 | 5 | res = str; |
520 | 5 | free_buffer = 1; |
521 | 5 | } |
522 | | |
523 | 600k | if (!res) { |
524 | 600k | return; |
525 | 600k | } |
526 | | |
527 | 5 | switch (arg) { |
528 | 0 | case PARSE_GET: |
529 | 5 | case PARSE_STRING: |
530 | 5 | separator = ZSTR_VAL(PG(arg_separator).input); |
531 | 5 | break; |
532 | 0 | case PARSE_COOKIE: |
533 | 0 | separator = ";\0"; |
534 | 0 | break; |
535 | 5 | } |
536 | | |
537 | 5 | var = php_strtok_r(res, separator, &strtok_buf); |
538 | | |
539 | 10 | while (var) { |
540 | 5 | size_t val_len; |
541 | 5 | size_t new_val_len; |
542 | | |
543 | 5 | val = strchr(var, '='); |
544 | | |
545 | 5 | if (arg == PARSE_COOKIE) { |
546 | | /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */ |
547 | 0 | while (isspace(*var)) { |
548 | 0 | var++; |
549 | 0 | } |
550 | 0 | if (var == val || *var == '\0') { |
551 | 0 | goto next_cookie; |
552 | 0 | } |
553 | 0 | } |
554 | | |
555 | 5 | zend_long max_input_vars = REQUEST_PARSE_BODY_OPTION_GET(max_input_vars, PG(max_input_vars)); |
556 | 5 | if (++count > max_input_vars) { |
557 | 0 | 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); |
558 | 0 | break; |
559 | 0 | } |
560 | | |
561 | 5 | if (val) { /* have a value */ |
562 | | |
563 | 5 | *val++ = '\0'; |
564 | | |
565 | 5 | if (arg == PARSE_COOKIE) { |
566 | 0 | val_len = php_raw_url_decode(val, strlen(val)); |
567 | 5 | } else { |
568 | 5 | val_len = php_url_decode(val, strlen(val)); |
569 | 5 | } |
570 | 5 | } else { |
571 | 0 | val = ""; |
572 | 0 | val_len = 0; |
573 | 0 | } |
574 | | |
575 | 5 | val = estrndup(val, val_len); |
576 | 5 | if (arg != PARSE_COOKIE) { |
577 | 5 | php_url_decode(var, strlen(var)); |
578 | 5 | } |
579 | 5 | if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { |
580 | 5 | php_register_variable_safe(var, val, new_val_len, &array); |
581 | 5 | } |
582 | 5 | efree(val); |
583 | 5 | next_cookie: |
584 | 5 | var = php_strtok_r(NULL, separator, &strtok_buf); |
585 | 5 | } |
586 | | |
587 | 5 | if (free_buffer) { |
588 | 5 | efree(res); |
589 | 5 | } |
590 | 5 | } |
591 | | |
592 | | static zend_always_inline int valid_environment_name(const char *name, const char *end) |
593 | 8.51k | { |
594 | 8.51k | const char *s; |
595 | | |
596 | 99.5k | for (s = name; s < end; s++) { |
597 | 91.0k | if (*s == ' ' || *s == '.' || *s == '[') { |
598 | 0 | return 0; |
599 | 0 | } |
600 | 91.0k | } |
601 | 8.51k | return 1; |
602 | 8.51k | } |
603 | | |
604 | | static zend_always_inline void import_environment_variable(HashTable *ht, char *env) |
605 | 8.51k | { |
606 | 8.51k | char *p; |
607 | 8.51k | size_t name_len, len; |
608 | 8.51k | zval val; |
609 | 8.51k | zend_ulong idx; |
610 | | |
611 | 8.51k | p = strchr(env, '='); |
612 | 8.51k | if (!p |
613 | 8.51k | || p == env |
614 | 8.51k | || !valid_environment_name(env, p)) { |
615 | | /* malformed entry? */ |
616 | 0 | return; |
617 | 0 | } |
618 | 8.51k | name_len = p - env; |
619 | 8.51k | p++; |
620 | 8.51k | len = strlen(p); |
621 | 8.51k | ZVAL_STRINGL_FAST(&val, p, len); |
622 | 8.51k | if (ZEND_HANDLE_NUMERIC_STR(env, name_len, idx)) { |
623 | 0 | zend_hash_index_update(ht, idx, &val); |
624 | 8.51k | } else { |
625 | 8.51k | php_register_variable_quick(env, name_len, &val, ht); |
626 | 8.51k | } |
627 | 8.51k | } |
628 | | |
629 | | static void _php_import_environment_variables(zval *array_ptr) |
630 | 230 | { |
631 | 230 | tsrm_env_lock(); |
632 | | |
633 | 230 | #ifndef PHP_WIN32 |
634 | 8.74k | for (char **env = environ; env != NULL && *env != NULL; env++) { |
635 | 8.51k | import_environment_variable(Z_ARRVAL_P(array_ptr), *env); |
636 | 8.51k | } |
637 | | #else |
638 | | wchar_t *environmentw = GetEnvironmentStringsW(); |
639 | | for (wchar_t *envw = environmentw; envw != NULL && *envw; envw += wcslen(envw) + 1) { |
640 | | char *env = php_win32_cp_w_to_any(envw); |
641 | | if (env != NULL) { |
642 | | import_environment_variable(Z_ARRVAL_P(array_ptr), env); |
643 | | free(env); |
644 | | } |
645 | | } |
646 | | FreeEnvironmentStringsW(environmentw); |
647 | | #endif |
648 | | |
649 | 230 | tsrm_env_unlock(); |
650 | 230 | } |
651 | | |
652 | | static void _php_load_environment_variables(zval *array_ptr) |
653 | 0 | { |
654 | 0 | php_import_environment_variables(array_ptr); |
655 | 0 | } |
656 | | |
657 | | /* {{{ php_build_argv */ |
658 | | PHPAPI void php_build_argv(const char *s, zval *track_vars_array) |
659 | 300k | { |
660 | 300k | zval arr, argc, tmp; |
661 | 300k | int count = 0; |
662 | | |
663 | 300k | if (!(SG(request_info).argc || track_vars_array)) { |
664 | 0 | return; |
665 | 0 | } |
666 | | |
667 | 300k | array_init(&arr); |
668 | | |
669 | | /* Prepare argv */ |
670 | 300k | if (SG(request_info).argc) { /* are we in cli sapi? */ |
671 | 0 | int i; |
672 | 0 | for (i = 0; i < SG(request_info).argc; i++) { |
673 | 0 | ZVAL_STRING(&tmp, SG(request_info).argv[i]); |
674 | 0 | if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) { |
675 | 0 | zend_string_efree(Z_STR(tmp)); |
676 | 0 | } |
677 | 0 | } |
678 | 300k | } else if (s && *s) { |
679 | 0 | while (1) { |
680 | 0 | const char *space = strchr(s, '+'); |
681 | | /* auto-type */ |
682 | 0 | ZVAL_STRINGL(&tmp, s, space ? space - s : strlen(s)); |
683 | 0 | count++; |
684 | 0 | if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) { |
685 | 0 | zend_string_efree(Z_STR(tmp)); |
686 | 0 | } |
687 | 0 | if (!space) { |
688 | 0 | break; |
689 | 0 | } |
690 | 0 | s = space + 1; |
691 | 0 | } |
692 | 0 | } |
693 | | |
694 | | /* prepare argc */ |
695 | 300k | if (SG(request_info).argc) { |
696 | 0 | ZVAL_LONG(&argc, SG(request_info).argc); |
697 | 300k | } else { |
698 | 300k | ZVAL_LONG(&argc, count); |
699 | 300k | } |
700 | | |
701 | 300k | if (SG(request_info).argc) { |
702 | 0 | Z_ADDREF(arr); |
703 | 0 | zend_hash_update(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGV), &arr); |
704 | 0 | zend_hash_update(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGC), &argc); |
705 | 0 | } |
706 | 300k | if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) { |
707 | 71 | Z_ADDREF(arr); |
708 | 71 | zend_hash_update(Z_ARRVAL_P(track_vars_array), ZSTR_KNOWN(ZEND_STR_ARGV), &arr); |
709 | 71 | zend_hash_update(Z_ARRVAL_P(track_vars_array), ZSTR_KNOWN(ZEND_STR_ARGC), &argc); |
710 | 71 | } |
711 | 300k | zval_ptr_dtor_nogc(&arr); |
712 | 300k | } |
713 | | /* }}} */ |
714 | | |
715 | | /* {{{ php_register_server_variables */ |
716 | | static inline void php_register_server_variables(void) |
717 | 71 | { |
718 | 71 | zval tmp; |
719 | 71 | zval *arr = &PG(http_globals)[TRACK_VARS_SERVER]; |
720 | 71 | HashTable *ht; |
721 | | |
722 | 71 | zval_ptr_dtor_nogc(arr); |
723 | 71 | array_init(arr); |
724 | | |
725 | | /* Server variables */ |
726 | 71 | if (sapi_module.register_server_variables) { |
727 | 71 | sapi_module.register_server_variables(arr); |
728 | 71 | } |
729 | 71 | ht = Z_ARRVAL_P(arr); |
730 | | |
731 | | /* PHP Authentication support */ |
732 | 71 | if (SG(request_info).auth_user) { |
733 | 0 | ZVAL_STRING(&tmp, SG(request_info).auth_user); |
734 | 0 | php_register_variable_quick("PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1, &tmp, ht); |
735 | 0 | } |
736 | 71 | if (SG(request_info).auth_password) { |
737 | 0 | ZVAL_STRING(&tmp, SG(request_info).auth_password); |
738 | 0 | php_register_variable_quick("PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1, &tmp, ht); |
739 | 0 | } |
740 | 71 | if (SG(request_info).auth_digest) { |
741 | 0 | ZVAL_STRING(&tmp, SG(request_info).auth_digest); |
742 | 0 | php_register_variable_quick("PHP_AUTH_DIGEST", sizeof("PHP_AUTH_DIGEST")-1, &tmp, ht); |
743 | 0 | } |
744 | | |
745 | | /* store request init time */ |
746 | 71 | ZVAL_DOUBLE(&tmp, sapi_get_request_time()); |
747 | 71 | php_register_variable_quick("REQUEST_TIME_FLOAT", sizeof("REQUEST_TIME_FLOAT")-1, &tmp, ht); |
748 | 71 | ZVAL_LONG(&tmp, zend_dval_to_lval(Z_DVAL(tmp))); |
749 | 71 | php_register_variable_quick("REQUEST_TIME", sizeof("REQUEST_TIME")-1, &tmp, ht); |
750 | 71 | } |
751 | | /* }}} */ |
752 | | |
753 | | /* {{{ php_autoglobal_merge */ |
754 | | static void php_autoglobal_merge(HashTable *dest, HashTable *src) |
755 | 15 | { |
756 | 15 | zval *src_entry, *dest_entry; |
757 | 15 | zend_string *string_key; |
758 | 15 | zend_ulong num_key; |
759 | 15 | int globals_check = (dest == (&EG(symbol_table))); |
760 | | |
761 | 15 | ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { |
762 | 15 | if (Z_TYPE_P(src_entry) != IS_ARRAY |
763 | 0 | || (string_key && (dest_entry = zend_hash_find(dest, string_key)) == NULL) |
764 | 0 | || (string_key == NULL && (dest_entry = zend_hash_index_find(dest, num_key)) == NULL) |
765 | 0 | || Z_TYPE_P(dest_entry) != IS_ARRAY) { |
766 | 0 | Z_TRY_ADDREF_P(src_entry); |
767 | 0 | if (string_key) { |
768 | 0 | if (!globals_check || !zend_string_equals_literal(string_key, "GLOBALS")) { |
769 | 0 | zend_hash_update(dest, string_key, src_entry); |
770 | 0 | } else { |
771 | 0 | Z_TRY_DELREF_P(src_entry); |
772 | 0 | } |
773 | 0 | } else { |
774 | 0 | zend_hash_index_update(dest, num_key, src_entry); |
775 | 0 | } |
776 | 0 | } else { |
777 | 0 | SEPARATE_ARRAY(dest_entry); |
778 | 0 | php_autoglobal_merge(Z_ARRVAL_P(dest_entry), Z_ARRVAL_P(src_entry)); |
779 | 0 | } |
780 | 15 | } ZEND_HASH_FOREACH_END(); |
781 | 15 | } |
782 | | /* }}} */ |
783 | | |
784 | | /* {{{ php_hash_environment */ |
785 | | PHPAPI int php_hash_environment(void) |
786 | 300k | { |
787 | 300k | memset(PG(http_globals), 0, sizeof(PG(http_globals))); |
788 | 300k | zend_activate_auto_globals(); |
789 | 300k | if (PG(register_argc_argv)) { |
790 | 300k | php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]); |
791 | 300k | } |
792 | 300k | return SUCCESS; |
793 | 300k | } |
794 | | /* }}} */ |
795 | | |
796 | | static bool php_auto_globals_create_get(zend_string *name) |
797 | 300k | { |
798 | 300k | if (PG(variables_order) && (strchr(PG(variables_order),'G') || strchr(PG(variables_order),'g'))) { |
799 | 300k | sapi_module.treat_data(PARSE_GET, NULL, NULL); |
800 | 300k | } else { |
801 | 0 | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_GET]); |
802 | 0 | array_init(&PG(http_globals)[TRACK_VARS_GET]); |
803 | 0 | } |
804 | | |
805 | 300k | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_GET]); |
806 | 300k | Z_ADDREF(PG(http_globals)[TRACK_VARS_GET]); |
807 | | |
808 | 300k | return 0; /* don't rearm */ |
809 | 300k | } |
810 | | |
811 | | static bool php_auto_globals_create_post(zend_string *name) |
812 | 300k | { |
813 | 300k | if (PG(variables_order) && |
814 | 300k | (strchr(PG(variables_order),'P') || strchr(PG(variables_order),'p')) && |
815 | 300k | !SG(headers_sent) && |
816 | 300k | SG(request_info).request_method && |
817 | 300k | !strcasecmp(SG(request_info).request_method, "POST")) { |
818 | 0 | sapi_module.treat_data(PARSE_POST, NULL, NULL); |
819 | 300k | } else { |
820 | 300k | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_POST]); |
821 | 300k | array_init(&PG(http_globals)[TRACK_VARS_POST]); |
822 | 300k | } |
823 | | |
824 | 300k | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_POST]); |
825 | 300k | Z_ADDREF(PG(http_globals)[TRACK_VARS_POST]); |
826 | | |
827 | 300k | return 0; /* don't rearm */ |
828 | 300k | } |
829 | | |
830 | | static bool php_auto_globals_create_cookie(zend_string *name) |
831 | 300k | { |
832 | 300k | if (PG(variables_order) && (strchr(PG(variables_order),'C') || strchr(PG(variables_order),'c'))) { |
833 | 300k | sapi_module.treat_data(PARSE_COOKIE, NULL, NULL); |
834 | 300k | } else { |
835 | 0 | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_COOKIE]); |
836 | 0 | array_init(&PG(http_globals)[TRACK_VARS_COOKIE]); |
837 | 0 | } |
838 | | |
839 | 300k | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_COOKIE]); |
840 | 300k | Z_ADDREF(PG(http_globals)[TRACK_VARS_COOKIE]); |
841 | | |
842 | 300k | return 0; /* don't rearm */ |
843 | 300k | } |
844 | | |
845 | | static bool php_auto_globals_create_files(zend_string *name) |
846 | 300k | { |
847 | 300k | if (Z_TYPE(PG(http_globals)[TRACK_VARS_FILES]) == IS_UNDEF) { |
848 | 300k | array_init(&PG(http_globals)[TRACK_VARS_FILES]); |
849 | 300k | } |
850 | | |
851 | 300k | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_FILES]); |
852 | 300k | Z_ADDREF(PG(http_globals)[TRACK_VARS_FILES]); |
853 | | |
854 | 300k | return 0; /* don't rearm */ |
855 | 300k | } |
856 | | |
857 | | /* Ugly hack to fix HTTP_PROXY issue, see bug #72573 */ |
858 | | static void check_http_proxy(HashTable *var_table) |
859 | 230 | { |
860 | 230 | if (zend_hash_str_exists(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1)) { |
861 | 0 | char *local_proxy = getenv("HTTP_PROXY"); |
862 | |
|
863 | 0 | if (!local_proxy) { |
864 | 0 | zend_hash_str_del(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1); |
865 | 0 | } else { |
866 | 0 | zval local_zval; |
867 | 0 | ZVAL_STRING(&local_zval, local_proxy); |
868 | 0 | zend_hash_str_update(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1, &local_zval); |
869 | 0 | } |
870 | 0 | } |
871 | 230 | } |
872 | | |
873 | | static bool php_auto_globals_create_server(zend_string *name) |
874 | 71 | { |
875 | 71 | if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) { |
876 | 71 | php_register_server_variables(); |
877 | | |
878 | 71 | if (PG(register_argc_argv)) { |
879 | 71 | if (SG(request_info).argc) { |
880 | 0 | zval *argc, *argv; |
881 | |
|
882 | 0 | if ((argc = zend_hash_find_ex_ind(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGC), 1)) != NULL && |
883 | 0 | (argv = zend_hash_find_ex_ind(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGV), 1)) != NULL) { |
884 | 0 | Z_ADDREF_P(argv); |
885 | 0 | zend_hash_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), ZSTR_KNOWN(ZEND_STR_ARGV), argv); |
886 | 0 | zend_hash_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), ZSTR_KNOWN(ZEND_STR_ARGC), argc); |
887 | 0 | } |
888 | 71 | } else { |
889 | 71 | php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]); |
890 | 71 | } |
891 | 71 | } |
892 | | |
893 | 71 | } else { |
894 | 0 | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_SERVER]); |
895 | 0 | array_init(&PG(http_globals)[TRACK_VARS_SERVER]); |
896 | 0 | zend_hash_real_init_mixed(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])); |
897 | 0 | } |
898 | | |
899 | 71 | check_http_proxy(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])); |
900 | 71 | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_SERVER]); |
901 | 71 | Z_ADDREF(PG(http_globals)[TRACK_VARS_SERVER]); |
902 | | |
903 | | /* TODO: TRACK_VARS_SERVER is modified in a number of places (e.g. phar) past this point, |
904 | | * where rc>1 due to the $_SERVER global. Ideally this shouldn't happen, but for now we |
905 | | * ignore this issue, as it would probably require larger changes. */ |
906 | 71 | HT_ALLOW_COW_VIOLATION(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])); |
907 | | |
908 | 71 | return 0; /* don't rearm */ |
909 | 71 | } |
910 | | |
911 | | static bool php_auto_globals_create_env(zend_string *name) |
912 | 159 | { |
913 | 159 | zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_ENV]); |
914 | 159 | array_init(&PG(http_globals)[TRACK_VARS_ENV]); |
915 | | |
916 | 159 | if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) { |
917 | 159 | php_import_environment_variables(&PG(http_globals)[TRACK_VARS_ENV]); |
918 | 159 | } |
919 | | |
920 | 159 | check_http_proxy(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])); |
921 | 159 | zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_ENV]); |
922 | 159 | Z_ADDREF(PG(http_globals)[TRACK_VARS_ENV]); |
923 | | |
924 | 159 | return 0; /* don't rearm */ |
925 | 159 | } |
926 | | |
927 | | static bool php_auto_globals_create_request(zend_string *name) |
928 | 5 | { |
929 | 5 | zval form_variables; |
930 | 5 | unsigned char _gpc_flags[3] = {0, 0, 0}; |
931 | 5 | char *p; |
932 | | |
933 | 5 | array_init(&form_variables); |
934 | | |
935 | 5 | if (PG(request_order) != NULL) { |
936 | 0 | p = PG(request_order); |
937 | 5 | } else { |
938 | 5 | p = PG(variables_order); |
939 | 5 | } |
940 | | |
941 | 30 | for (; p && *p; p++) { |
942 | 25 | switch (*p) { |
943 | 0 | case 'g': |
944 | 5 | case 'G': |
945 | 5 | if (!_gpc_flags[0]) { |
946 | 5 | php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_GET])); |
947 | 5 | _gpc_flags[0] = 1; |
948 | 5 | } |
949 | 5 | break; |
950 | 0 | case 'p': |
951 | 5 | case 'P': |
952 | 5 | if (!_gpc_flags[1]) { |
953 | 5 | php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_POST])); |
954 | 5 | _gpc_flags[1] = 1; |
955 | 5 | } |
956 | 5 | break; |
957 | 0 | case 'c': |
958 | 5 | case 'C': |
959 | 5 | if (!_gpc_flags[2]) { |
960 | 5 | php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE])); |
961 | 5 | _gpc_flags[2] = 1; |
962 | 5 | } |
963 | 5 | break; |
964 | 25 | } |
965 | 25 | } |
966 | | |
967 | 5 | zend_hash_update(&EG(symbol_table), name, &form_variables); |
968 | 5 | return 0; |
969 | 5 | } |
970 | | |
971 | | void php_startup_auto_globals(void) |
972 | 16 | { |
973 | 16 | zend_register_auto_global(zend_string_init_interned("_GET", sizeof("_GET")-1, 1), 0, php_auto_globals_create_get); |
974 | 16 | zend_register_auto_global(zend_string_init_interned("_POST", sizeof("_POST")-1, 1), 0, php_auto_globals_create_post); |
975 | 16 | zend_register_auto_global(zend_string_init_interned("_COOKIE", sizeof("_COOKIE")-1, 1), 0, php_auto_globals_create_cookie); |
976 | 16 | zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER), PG(auto_globals_jit), php_auto_globals_create_server); |
977 | 16 | zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_ENV), PG(auto_globals_jit), php_auto_globals_create_env); |
978 | 16 | zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_REQUEST), PG(auto_globals_jit), php_auto_globals_create_request); |
979 | 16 | zend_register_auto_global(zend_string_init_interned("_FILES", sizeof("_FILES")-1, 1), 0, php_auto_globals_create_files); |
980 | 16 | } |