diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/SAPI.h | 2 | ||||
-rw-r--r-- | main/main.c | 160 | ||||
-rw-r--r-- | main/php_globals.h | 1 | ||||
-rw-r--r-- | main/php_variables.c | 317 | ||||
-rw-r--r-- | main/php_variables.h | 47 | ||||
-rw-r--r-- | main/rfc1867.c | 2 |
6 files changed, 419 insertions, 110 deletions
diff --git a/main/SAPI.h b/main/SAPI.h index d5ebcdc62f..7500b3ee20 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -147,6 +147,8 @@ struct _sapi_module_struct { int (*read_post)(char *buffer, uint count_bytes SLS_DC); char *(*read_cookies)(SLS_D); + void (*register_server_variables)(zval *track_vars_array ELS_DC SLS_DC PLS_DC); + void (*default_post_reader)(char *content_type_dup SLS_DC); }; diff --git a/main/main.c b/main/main.c index 0bee112546..d8568e973d 100644 --- a/main/main.c +++ b/main/main.c @@ -50,7 +50,7 @@ #include "fopen-wrappers.h" #include "ext/standard/php_standard.h" #include "snprintf.h" -#include "php_gpce.h" +#include "php_variables.h" #if WIN32|WINNT #include <io.h> #include <fcntl.h> @@ -251,8 +251,9 @@ PHP_INI_BEGIN() #endif STD_PHP_INI_BOOLEAN("gpc_globals", "1", PHP_INI_ALL, OnUpdateBool, gpc_globals, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("gpc_order", "GPC", PHP_INI_ALL, OnUpdateStringUnempty, gpc_order, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("arg_separator", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("gpc_order", "GPC", PHP_INI_ALL, OnUpdateStringUnempty, gpc_order, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("variables_order", NULL, PHP_INI_ALL, OnUpdateStringUnempty, variables_order, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("arg_separator", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("ignore_user_abort", "1", PHP_INI_ALL, OnUpdateBool, ignore_user_abort, php_core_globals, core_globals) PHP_INI_END() @@ -702,24 +703,10 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC) } if (SG(request_info).auth_user) { - zval *auth_user; - - MAKE_STD_ZVAL(auth_user); - auth_user->type = IS_STRING; - auth_user->value.str.val = SG(request_info).auth_user; - auth_user->value.str.len = strlen(auth_user->value.str.val); - - zend_hash_update(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), &auth_user, sizeof(zval *), NULL); + php_register_variable(SG(request_info).auth_user, "PHP_AUTH_USER", NULL ELS_CC PLS_CC); } if (SG(request_info).auth_password) { - zval *auth_password; - - MAKE_STD_ZVAL(auth_password); - auth_password->type = IS_STRING; - auth_password->value.str.val = SG(request_info).auth_password; - auth_password->value.str.len = strlen(auth_password->value.str.val); - - zend_hash_update(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), &auth_password, sizeof(zval *), NULL); + php_register_variable(SG(request_info).auth_password, "PHP_AUTH_PW", NULL ELS_CC PLS_CC); } return SUCCESS; @@ -1009,14 +996,35 @@ void php_module_shutdown() } -/* in 3.1 some of this should move into sapi */ -static int zend_hash_environment(PLS_D ELS_DC SLS_DC) +static inline void php_register_server_variables(ELS_D SLS_DC PLS_DC) +{ + zval *array_ptr=NULL; + + if (PG(track_vars)) { + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); + INIT_PZVAL(array_ptr); + zend_hash_add(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_ENV_VARS"), &array_ptr, sizeof(pval *),NULL); + } + sapi_module.register_server_variables(array_ptr ELS_CC SLS_CC PLS_CC); +} + + +static int zend_hash_environment(ELS_D SLS_DC PLS_DC) { - char **env, *p, *t; + char *p; unsigned char _gpc_flags[3] = {0,0,0}; - pval *tmp; - - p = PG(gpc_order); + zend_bool have_variables_order; + + if (PG(variables_order)) { + p = PG(variables_order); + have_variables_order=1; + } else { + p = PG(gpc_order); + have_variables_order=0; + php_import_environment_variables(ELS_C PLS_CC); + } + while(*p) { switch(*p++) { case 'p': @@ -1040,94 +1048,27 @@ static int zend_hash_environment(PLS_D ELS_DC SLS_DC) _gpc_flags[2]=1; } break; + case 'e': + case 'E': + if (have_variables_order) { + php_import_environment_variables(ELS_C PLS_CC); + } else { + php_error(E_CORE_WARNING, "Unsupported 'e' element (environment) used in gpc_order - use variables_order instead"); + } + break; + case 's': + case 'S': + if (sapi_module.register_server_variables) { + php_register_server_variables(ELS_C SLS_CC PLS_CC); + } + break; } } - - for (env = environ; env != NULL && *env != NULL; env++) { - p = strchr(*env, '='); - if (!p) { /* malformed entry? */ - continue; - } - t = estrndup(*env, p - *env); - ALLOC_ZVAL(tmp); - tmp->value.str.len = strlen(p + 1); - tmp->value.str.val = estrndup(p + 1, tmp->value.str.len); - tmp->type = IS_STRING; - INIT_PZVAL(tmp); - /* environmental variables never take precedence over get/post/cookie variables */ - zend_hash_add(&EG(symbol_table), t, p - *env + 1, &tmp, sizeof(pval *), NULL); - efree(t); - } -#if APACHE - { - pval **tmp_ptr; - register int i; - array_header *arr = table_elts(((request_rec *) SG(server_context))->subprocess_env); - table_entry *elts = (table_entry *) arr->elts; - int len; - - for (i = 0; i < arr->nelts; i++) { - len = strlen(elts[i].key); - t = elts[i].key; - ALLOC_ZVAL(tmp); - if (elts[i].val) { - tmp->value.str.len = strlen(elts[i].val); - tmp->value.str.val = estrndup(elts[i].val, tmp->value.str.len); - } else { - tmp->value.str.len = 0; - tmp->value.str.val = empty_string; - } - INIT_PZVAL(tmp); - tmp->type = IS_STRING; - zend_hash_update(&EG(symbol_table), t, strlen(t)+1, &tmp, sizeof(pval *), NULL); - } - /* insert special variables */ - if (zend_hash_find(&EG(symbol_table), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &tmp_ptr) == SUCCESS) { - (*tmp_ptr)->refcount++; - zend_hash_update(&EG(symbol_table), "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), tmp_ptr, sizeof(pval *), NULL); - } - ALLOC_ZVAL(tmp); - tmp->value.str.len = strlen(((request_rec *) SG(server_context))->uri); - tmp->value.str.val = estrndup(((request_rec *) SG(server_context))->uri, tmp->value.str.len); - INIT_PZVAL(tmp); - tmp->type = IS_STRING; - zend_hash_update(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void *) &tmp, sizeof(pval *), NULL); + if (!have_variables_order) { + php_register_server_variables(ELS_C SLS_CC PLS_CC); } -#else - { - /* Build the special-case PHP_SELF variable for the CGI version */ - char *pi; -#if FORCE_CGI_REDIRECT - pi = SG(request_info).request_uri; - ALLOC_ZVAL(tmp); - tmp->value.str.val = emalloc(((pi)?strlen(pi):0) + 1); - tmp->value.str.len = php_sprintf(tmp->value.str.val, "%s", (pi ? pi : "")); /* SAFE */ - tmp->type = IS_STRING; - INIT_PZVAL(tmp); -#else - int l = 0; - char *sn; - sn = request_info.script_name; - pi = SG(request_info).request_uri; - if (sn) - l += strlen(sn); - if (pi) - l += strlen(pi); - if (pi && sn && !strcmp(pi, sn)) { - l -= strlen(pi); - pi = NULL; - } - ALLOC_ZVAL(tmp); - tmp->value.str.val = emalloc(l + 1); - tmp->value.str.len = php_sprintf(tmp->value.str.val, "%s%s", (sn ? sn : ""), (pi ? pi : "")); /* SAFE */ - tmp->type = IS_STRING; - INIT_PZVAL(tmp); -#endif - zend_hash_update(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void *) & tmp, sizeof(pval *), NULL); - } -#endif /* need argc/argv support as well */ @@ -1136,6 +1077,7 @@ static int zend_hash_environment(PLS_D ELS_DC SLS_DC) return SUCCESS; } + void _php_build_argv(char *s ELS_DC) { pval *arr, *tmp; @@ -1193,6 +1135,7 @@ PHPAPI void php_execute_script(zend_file_handle *primary_file CLS_DC ELS_DC PLS_ zend_file_handle prepend_file, append_file; SLS_FETCH(); + zend_hash_environment(ELS_C SLS_CC PLS_CC); zend_activate_modules(); if (SG(request_info).query_string && SG(request_info).query_string[0]=='=' && PG(expose_php)) { @@ -1240,7 +1183,6 @@ PHPAPI void php_execute_script(zend_file_handle *primary_file CLS_DC ELS_DC PLS_ } EG(main_op_array) = zend_compile_files(0 CLS_CC, 3, prepend_file_p, primary_file, append_file_p); if (EG(main_op_array)) { - zend_hash_environment(PLS_C ELS_CC SLS_CC); EG(active_op_array) = EG(main_op_array); zend_execute(EG(main_op_array) ELS_CC); } diff --git a/main/php_globals.h b/main/php_globals.h index 809b36ae53..8bb5792c82 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -81,6 +81,7 @@ struct _php_core_globals { char *arg_separator; char *gpc_order; + char *variables_order; zend_bool expose_php; diff --git a/main/php_variables.c b/main/php_variables.c new file mode 100644 index 0000000000..b4355b4ee8 --- /dev/null +++ b/main/php_variables.c @@ -0,0 +1,317 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ +/* $Id: */ + +#include <stdio.h> +#include "php.h" +#include "ext/standard/php_standard.h" +#include "php_variables.h" +#include "php_globals.h" +#include "SAPI.h" + +#include "zend_globals.h" + + +PHPAPI void php_register_variable(char *val, char *var, pval *track_vars_array ELS_DC PLS_DC) +{ + char *p = NULL; + char *ip; /* index pointer */ + char *index; + int var_len, val_len, index_len; + zval *gpc_element, **gpc_element_p, **top_gpc_p=NULL; + zend_bool is_array; + zend_bool free_index; + HashTable *symtable1=NULL; + HashTable *symtable2=NULL; + + if (PG(gpc_globals)) { + symtable1 = EG(active_symbol_table); + } + if (track_vars_array) { + if (symtable1) { + symtable2 = track_vars_array->value.ht; + } else { + symtable1 = track_vars_array->value.ht; + } + } + if (!symtable1) { + /* we don't need track_vars, and we're not setting GPC globals either. */ + return; + } + + /* + * Prepare variable name + */ + ip = strchr(var, '['); + if (ip) { + is_array = 1; + *ip = 0; + } else { + is_array = 0; + } + /* ignore leading spaces in the variable name */ + while (*var && *var==' ') { + var++; + } + var_len = strlen(var); + if (var_len==0) { /* empty variable name, or variable name with a space in it */ + return; + } + /* ensure that we don't have spaces or dots in the variable name (not binary safe) */ + for (p=var; *p; p++) { + switch(*p) { + case ' ': + case '.': + *p='_'; + break; + } + } + + /* Prepare value */ + val_len = strlen(val); + if (PG(magic_quotes_gpc)) { + val = php_addslashes(val, val_len, &val_len, 0); + } else { + val = estrndup(val, val_len); + } + + index = var; + index_len = var_len; + free_index = 0; + + while (1) { + if (is_array) { + char *escaped_index; + + if (!index) { + MAKE_STD_ZVAL(gpc_element); + array_init(gpc_element); + zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } else { + if (PG(magic_quotes_gpc) && (index!=var)) { + /* no need to addslashes() the index if it's the main variable name */ + escaped_index = php_addslashes(index, index_len, &index_len, 0); + } else { + escaped_index = index; + } + if (zend_hash_find(symtable1, escaped_index, index_len+1, (void **) &gpc_element_p)==FAILURE + || (*gpc_element_p)->type != IS_ARRAY) { + MAKE_STD_ZVAL(gpc_element); + array_init(gpc_element); + zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } + if (index!=escaped_index) { + efree(escaped_index); + } + } + if (!top_gpc_p) { + top_gpc_p = gpc_element_p; + } + symtable1 = (*gpc_element_p)->value.ht; + /* ip pointed to the '[' character, now obtain the key */ + index = ++ip; + index_len = 0; + if (*ip=='\n' || *ip=='\r' || *ip=='\t' || *ip==' ') { + ip++; + } + if (*ip==']') { + index = NULL; + } else { + ip = strchr(ip, ']'); + if (!ip) { + php_error(E_WARNING, "Missing ] in %s variable", var); + return; + } + *ip = 0; + index_len = strlen(index); + } + ip++; + if (*ip=='[') { + is_array = 1; + *ip = 0; + } else { + is_array = 0; + } + } else { + MAKE_STD_ZVAL(gpc_element); + gpc_element->value.str.val = val; + gpc_element->value.str.len = val_len; + gpc_element->type = IS_STRING; + if (!index) { + zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } else { + zend_hash_update(symtable1, index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } + if (!top_gpc_p) { + top_gpc_p = gpc_element_p; + } + break; + } + } + + if (top_gpc_p) { + (*top_gpc_p)->is_ref = 1; + if (symtable2) { + zend_hash_update(symtable2, var, var_len+1, top_gpc_p, sizeof(zval *), NULL); + (*top_gpc_p)->refcount++; + } + } +} + + +void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC) +{ + char *res = NULL, *var, *val; + pval *array_ptr; + int free_buffer=0; + char *strtok_buf = NULL; + + switch (arg) { + case PARSE_POST: + case PARSE_GET: + case PARSE_COOKIE: + if (PG(track_vars)) { + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); + INIT_PZVAL(array_ptr); + switch (arg) { + case PARSE_POST: + zend_hash_add(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), &array_ptr, sizeof(pval *),NULL); + break; + case PARSE_GET: + zend_hash_add(&EG(symbol_table), "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), &array_ptr, sizeof(pval *),NULL); + break; + case PARSE_COOKIE: + zend_hash_add(&EG(symbol_table), "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), &array_ptr, sizeof(pval *),NULL); + break; + } + } else { + array_ptr=NULL; + } + break; + default: + array_ptr=NULL; + break; + } + + if (arg == PARSE_POST) { /* POST data */ + res = SG(request_info).post_data; + free_buffer = 0; + } else if (arg == PARSE_GET) { /* GET data */ + var = SG(request_info).query_string; + if (var && *var) { + res = (char *) estrdup(var); + free_buffer = 1; + } else { + free_buffer = 0; + } + } else if (arg == PARSE_COOKIE) { /* Cookie data */ + var = SG(request_info).cookie_data; + if (var && *var) { + res = (char *) estrdup(var); + free_buffer = 1; + } else { + free_buffer = 0; + } + } else if (arg == PARSE_STRING) { /* String data */ + res = str; + free_buffer = 1; + } + if (!res) { + return; + } + +#if HAVE_FDFLIB + if((NULL != SG(request_info).content_type) && (0 == strcmp(SG(request_info).content_type, "application/vnd.fdf"))) { + pval *tmp; + + ALLOC_ZVAL(tmp); + tmp->value.str.len = SG(request_info).post_data_length; + tmp->value.str.val = estrndup(SG(request_info).post_data, SG(request_info).post_data_length); + tmp->type = IS_STRING; + INIT_PZVAL(tmp); + zend_hash_add(&EG(symbol_table), "HTTP_FDF_DATA", sizeof("HTTP_FDF_DATA"), &tmp, sizeof(pval *),NULL); + + } else { +#endif + if (arg == PARSE_COOKIE) { + var = strtok_r(res, ";", &strtok_buf); + } else if (arg == PARSE_POST) { + var = strtok_r(res, "&", &strtok_buf); + } else { + var = strtok_r(res, PG(arg_separator), &strtok_buf); + } + + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ + *val++ = '\0'; + /* FIXME: XXX: not binary safe, discards returned length */ + php_url_decode(var, strlen(var)); + php_url_decode(val, strlen(val)); + php_register_variable(val, var, array_ptr ELS_CC PLS_CC); + } + if (arg == PARSE_COOKIE) { + var = strtok_r(NULL, ";", &strtok_buf); + } else if (arg == PARSE_POST) { + var = strtok_r(NULL, "&", &strtok_buf); + } else { + var = strtok_r(NULL, PG(arg_separator), &strtok_buf); + } + } +#if HAVE_FDFLIB + } +#endif + if (free_buffer) { + efree(res); + } +} + + + +void php_import_environment_variables(ELS_D PLS_DC) +{ + char **env, *p, *t; + zval *array_ptr=NULL; + + if (PG(track_vars)) { + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); + INIT_PZVAL(array_ptr); + zend_hash_add(&EG(symbol_table), "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), &array_ptr, sizeof(pval *),NULL); + } + + for (env = environ; env != NULL && *env != NULL; env++) { + p = strchr(*env, '='); + if (!p) { /* malformed entry? */ + continue; + } + t = estrndup(*env, p - *env); + php_register_variable(p+1, t, array_ptr ELS_CC PLS_CC); + efree(t); + } +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/main/php_variables.h b/main/php_variables.h new file mode 100644 index 0000000000..826f77dc76 --- /dev/null +++ b/main/php_variables.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifndef _PHP_VARIABLES_H +#define _PHP_VARIABLES_H + +#include "php.h" +#include "SAPI.h" + +#define PARSE_POST 0 +#define PARSE_GET 1 +#define PARSE_COOKIE 2 +#define PARSE_STRING 3 + +void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC); +void php_import_environment_variables(ELS_D PLS_DC); +PHPAPI void php_register_variable(char *val, char *var, pval *track_vars_array ELS_DC PLS_DC); + +#endif /* _PHP_VARIABLES_H */ diff --git a/main/rfc1867.c b/main/rfc1867.c index f4337c3f8b..e418fe0606 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -23,7 +23,7 @@ #include "ext/standard/file.h" /* for php_file_le_uploads() */ #include "zend_globals.h" #include "php_globals.h" -#include "php_gpce.h" +#include "php_variables.h" #include "rfc1867.h" |