cvs: php-src(PHP_5_3) / php.ini-dist php.ini-recommended /ext/standard basic_functions.c basic_functions.h browscap.c /ext/standard/tests/file
parse_ini_file.phpt /ext/standard/tests/general_functions parse_ini_basic.data parse_ini_basic.phpt parse_ini_booleans.data parse_ini_booleans.phpt
parse_ini_file.phpt /main main.c php_globals.h php_ini.c php_ini.h /sapi/cgi cgi_main.c ZendEngine2 zend_globals.h zend_ini.h zend_ini_parser.y
zend_ini_scanner.h zend_ini_scanner.l

From: Date: Fri, 28 Sep 2007 02:05:10 +0000
Subject: cvs: php-src(PHP_5_3) / php.ini-dist php.ini-recommended /ext/standard basic_functions.c basic_functions.h browscap.c /ext/standard/tests/file
parse_ini_file.phpt /ext/standard/tests/general_functions parse_ini_basic.data parse_ini_basic.phpt parse_ini_booleans.data parse_ini_booleans.phpt
parse_ini_file.phpt /main main.c php_globals.h php_ini.c php_ini.h /sapi/cgi cgi_main.c ZendEngine2 zend_globals.h zend_ini.h zend_ini_parser.y
zend_ini_scanner.h zend_ini_scanner.l
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-46324@lists.php.net to get a copy of this message
jani Fri Sep 28 02:05:10 2007 UTC Added files: (Branch: PHP_5_3) /php-src/ext/standard/tests/general_functions parse_ini_basic.data parse_ini_basic.phpt parse_ini_booleans.data parse_ini_booleans.phpt Modified files: /php-src php.ini-dist php.ini-recommended /ZendEngine2 zend_globals.h zend_ini.h zend_ini_parser.y zend_ini_scanner.h zend_ini_scanner.l /php-src/ext/standard basic_functions.c basic_functions.h browscap.c /php-src/ext/standard/tests/file parse_ini_file.phpt /php-src/ext/standard/tests/general_functions parse_ini_file.phpt /php-src/main main.c php_globals.h php_ini.c php_ini.h /php-src/sapi/cgi cgi_main.c Log: MFH: - Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI. - Added support for special [PATH=/opt/httpd/www.example.com/] sections in php.ini. All directives set in these sections will not be able to be overridden in user-defined ini-files or during runtime in the specified path. - Improved php.ini handling: . Added better error reporting for syntax errors in php.ini files . Allowed "ini-variables" to be used almost everywhere ini php.ini files . Allowed using alphanumeric/variable indexes in "array" ini options . Fixed get_cfg_var() to be able to return "array" ini options - Fixed bug #27372 (parse error loading browscap.ini at apache startup) - Fixed bug #42069 (parse_ini_file() allows using some non-alpha numeric characters)

http://cvs.php.net/viewvc.cgi/php-src/php.ini-dist?r1=1.231.2.10.2.22&r2=1.231.2.10.2.22.2.1&diff_format=u Index: php-src/php.ini-dist diff -u php-src/php.ini-dist:1.231.2.10.2.22 php-src/php.ini-dist:1.231.2.10.2.22.2.1 --- php-src/php.ini-dist:1.231.2.10.2.22 Tue Aug 21 23:24:18 2007 +++ php-src/php.ini-dist Fri Sep 28 02:05:08 2007 @@ -63,6 +63,17 @@ ; defaults (that is, if no php.ini is used, or if you delete these lines, ; the builtin defaults will be identical). +;;;;;;;;;;;;;;;;;;;; +; php.ini Options ; +;;;;;;;;;;;;;;;;;;;; +; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" +;user_ini.filename = ".user.ini" + +; To disable this feature set this option to empty value +;user_ini.filename = + +; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) +;user_ini.cache_ttl = 300 ;;;;;;;;;;;;;;;;;;;; ; Language Options ; http://cvs.php.net/viewvc.cgi/php-src/php.ini-recommended?r1=1.179.2.11.2.23&r2=1.179.2.11.2.23.2.1&diff_format=u Index: php-src/php.ini-recommended diff -u php-src/php.ini-recommended:1.179.2.11.2.23 php-src/php.ini-recommended:1.179.2.11.2.23.2.1 --- php-src/php.ini-recommended:1.179.2.11.2.23 Tue Aug 21 23:24:18 2007 +++ php-src/php.ini-recommended Fri Sep 28 02:05:08 2007 @@ -113,6 +113,18 @@ ; since short tags may not be supported on the target server. ;;;;;;;;;;;;;;;;;;;; +; php.ini Options ; +;;;;;;;;;;;;;;;;;;;; +; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" +;user_ini.filename = ".user.ini" + +; To disable this feature set this option to empty value +;user_ini.filename = + +; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) +;user_ini.cache_ttl = 300 + +;;;;;;;;;;;;;;;;;;;; ; Language Options ; ;;;;;;;;;;;;;;;;;;;; http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_globals.h?r1=1.141.2.3.2.7&r2=1.141.2.3.2.7.2.1&diff_format=u Index: ZendEngine2/zend_globals.h diff -u ZendEngine2/zend_globals.h:1.141.2.3.2.7 ZendEngine2/zend_globals.h:1.141.2.3.2.7.2.1 --- ZendEngine2/zend_globals.h:1.141.2.3.2.7 Mon Jan 1 09:35:46 2007 +++ ZendEngine2/zend_globals.h Fri Sep 28 02:05:08 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_globals.h,v 1.141.2.3.2.7 2007/01/01 09:35:46 sebastian Exp $ */ +/* $Id: zend_globals.h,v 1.141.2.3.2.7.2.1 2007/09/28 02:05:08 jani Exp $ */ #ifndef ZEND_GLOBALS_H #define ZEND_GLOBALS_H @@ -265,6 +265,9 @@ int yy_start_stack_depth; int *yy_start_stack; + /* For ini scanner. Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */ + int scanner_mode; + #ifdef ZEND_MULTIBYTE /* original (unfiltered) script */ char *script_org; http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_ini.h?r1=1.34.2.1.2.6.2.2&r2=1.34.2.1.2.6.2.3&diff_format=u Index: ZendEngine2/zend_ini.h diff -u ZendEngine2/zend_ini.h:1.34.2.1.2.6.2.2 ZendEngine2/zend_ini.h:1.34.2.1.2.6.2.3 --- ZendEngine2/zend_ini.h:1.34.2.1.2.6.2.2 Thu Sep 27 18:00:37 2007 +++ ZendEngine2/zend_ini.h Fri Sep 28 02:05:08 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini.h,v 1.34.2.1.2.6.2.2 2007/09/27 18:00:37 dmitry Exp $ */ +/* $Id: zend_ini.h,v 1.34.2.1.2.6.2.3 2007/09/28 02:05:08 jani Exp $ */ #ifndef ZEND_INI_H #define ZEND_INI_H @@ -164,7 +164,6 @@ #define INI_ORIG_STR(name) zend_ini_string((name), sizeof(name), 1) #define INI_ORIG_BOOL(name) ((zend_bool) INI_ORIG_INT(name)) - #define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number TSRMLS_CC) #define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries(module_number TSRMLS_CC) #define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module) @@ -193,15 +192,16 @@ #define ZEND_INI_STAGE_HTACCESS (1<<5) /* INI parsing engine */ -typedef void (*zend_ini_parser_cb_t)(zval *arg1, zval *arg2, int callback_type, void *arg); +typedef void (*zend_ini_parser_cb_t)(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg TSRMLS_DC); BEGIN_EXTERN_C() -ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg); -ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg); +ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC); +ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC); END_EXTERN_C() -#define ZEND_INI_PARSER_ENTRY 1 -#define ZEND_INI_PARSER_SECTION 2 -#define ZEND_INI_PARSER_POP_ENTRY 3 +/* INI entries */ +#define ZEND_INI_PARSER_ENTRY 1 /* Normal entry: foo = bar */ +#define ZEND_INI_PARSER_SECTION 2 /* Section: [foobar] */ +#define ZEND_INI_PARSER_POP_ENTRY 3 /* Offset entry: foo[] = bar */ typedef struct _zend_ini_parser_param { zend_ini_parser_cb_t ini_parser_cb; http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_ini_parser.y?r1=1.41.2.2.2.2&r2=1.41.2.2.2.2.2.1&diff_format=u Index: ZendEngine2/zend_ini_parser.y diff -u ZendEngine2/zend_ini_parser.y:1.41.2.2.2.2 ZendEngine2/zend_ini_parser.y:1.41.2.2.2.2.2.1 --- ZendEngine2/zend_ini_parser.y:1.41.2.2.2.2 Mon Jul 23 16:17:10 2007 +++ ZendEngine2/zend_ini_parser.y Fri Sep 28 02:05:08 2007 @@ -13,13 +13,15 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Zeev Suraski <zeev@zend.com> | + | Authors: Zeev Suraski <zeev@zend.com> | + | Jani Taskinen <jani@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_parser.y,v 1.41.2.2.2.2 2007/07/23 16:17:10 jani Exp $ */ +/* $Id: zend_ini_parser.y,v 1.41.2.2.2.2.2.1 2007/09/28 02:05:08 jani Exp $ */ #define DEBUG_CFG_PARSER 0 + #include "zend.h" #include "zend_API.h" #include "zend_ini.h" @@ -27,32 +29,23 @@ #include "zend_ini_scanner.h" #include "zend_extensions.h" +#define YYERROR_VERBOSE #define YYSTYPE zval #ifdef ZTS #define YYPARSE_PARAM tsrm_ls #define YYLEX_PARAM tsrm_ls -#endif - -#define ZEND_INI_PARSER_CB (CG(ini_parser_param))->ini_parser_cb -#define ZEND_INI_PARSER_ARG (CG(ini_parser_param))->arg - -int ini_lex(zval *ini_lval TSRMLS_DC); -#ifdef ZTS int ini_parse(void *arg); #else int ini_parse(void); #endif -zval yylval; - -#ifndef ZTS -extern int ini_lex(zval *ini_lval TSRMLS_DC); -extern FILE *ini_in; -extern void init_cfg_scanner(void); -#endif +#define ZEND_INI_PARSER_CB (CG(ini_parser_param))->ini_parser_cb +#define ZEND_INI_PARSER_ARG (CG(ini_parser_param))->arg -void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) +/* {{{ zend_ini_do_op() +*/ +static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) { int i_result; int i_op1, i_op2; @@ -91,16 +84,22 @@ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0; Z_TYPE_P(result) = IS_STRING; } +/* }}} */ -void zend_ini_init_string(zval *result) +/* {{{ zend_ini_init_string() +*/ +static void zend_ini_init_string(zval *result) { Z_STRVAL_P(result) = malloc(1); Z_STRVAL_P(result)[0] = 0; Z_STRLEN_P(result) = 0; Z_TYPE_P(result) = IS_STRING; } +/* }}} */ -void zend_ini_add_string(zval *result, zval *op1, zval *op2) +/* {{{ zend_ini_add_string() +*/ +static void zend_ini_add_string(zval *result, zval *op1, zval *op2) { int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); @@ -110,12 +109,15 @@ Z_STRLEN_P(result) = length; Z_TYPE_P(result) = IS_STRING; } +/* }}} */ -void zend_ini_get_constant(zval *result, zval *name) +/* {{{ zend_ini_get_constant() +*/ +static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC) { zval z_constant; - TSRMLS_FETCH(); + /* If name contains ':' it is not a constant. Bug #26893. */ if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name)) && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) { /* z_constant is emalloc()'d */ @@ -129,16 +131,20 @@ *result = *name; } } +/* }}} */ -void zend_ini_get_var(zval *result, zval *name) +/* {{{ zend_ini_get_var() +*/ +static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC) { zval curval; char *envvar; - TSRMLS_FETCH(); + /* Fetch configuration option value */ if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) { Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval)); Z_STRLEN_P(result) = Z_STRLEN(curval); + /* ..or if not found, try ENV */ } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL || (envvar = getenv(Z_STRVAL_P(name))) != NULL) { Z_STRVAL_P(result) = strdup(envvar); @@ -147,9 +153,11 @@ zend_ini_init_string(result); } } +/* }}} */ - -static void ini_error(char *str) +/* {{{ ini_error() +*/ +static void ini_error(char *msg) { char *error_buf; int error_buf_len; @@ -158,10 +166,10 @@ currently_parsed_filename = zend_ini_scanner_get_filename(TSRMLS_C); if (currently_parsed_filename) { - error_buf_len = 128+strlen(currently_parsed_filename); /* should be more than enough */ + error_buf_len = 128 + strlen(msg) + strlen(currently_parsed_filename); /* should be more than enough */ error_buf = (char *) emalloc(error_buf_len); - sprintf(error_buf, "Error parsing %s on line %d\n", currently_parsed_filename, zend_ini_scanner_get_lineno(TSRMLS_C)); + sprintf(error_buf, "%s in %s on line %d\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno(TSRMLS_C)); } else { error_buf = estrdup("Invalid configuration directive\n"); } @@ -177,71 +185,87 @@ } efree(error_buf); } +/* }}} */ - -ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg) +/* {{{ zend_parse_ini_file() +*/ +ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC) { int retval; zend_ini_parser_param ini_parser_param; - TSRMLS_FETCH(); ini_parser_param.ini_parser_cb = ini_parser_cb; ini_parser_param.arg = arg; - CG(ini_parser_param) = &ini_parser_param; - if (zend_ini_open_file_for_scanning(fh TSRMLS_CC)==FAILURE) { + + if (zend_ini_open_file_for_scanning(fh, scanner_mode TSRMLS_CC) == FAILURE) { return FAILURE; } CG(ini_parser_unbuffered_errors) = unbuffered_errors; retval = ini_parse(TSRMLS_C); - zend_ini_close_file(fh TSRMLS_CC); - if (retval==0) { + shutdown_ini_scanner(TSRMLS_C); + + if (retval == 0) { return SUCCESS; } else { return FAILURE; } } +/* }}} */ - -ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg) +/* {{{ zend_parse_ini_string() +*/ +ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC) { + int retval; zend_ini_parser_param ini_parser_param; - TSRMLS_FETCH(); ini_parser_param.ini_parser_cb = ini_parser_cb; ini_parser_param.arg = arg; - CG(ini_parser_param) = &ini_parser_param; - if (zend_ini_prepare_string_for_scanning(str TSRMLS_CC)==FAILURE) { + + if (zend_ini_prepare_string_for_scanning(str, scanner_mode TSRMLS_CC) == FAILURE) { return FAILURE; } CG(ini_parser_unbuffered_errors) = unbuffered_errors; + retval = ini_parse(TSRMLS_C); + + shutdown_ini_scanner(TSRMLS_C); - if (ini_parse(TSRMLS_C)) { + if (retval == 0) { return SUCCESS; } else { return FAILURE; } } - +/* }}} */ %} +%expect 1 %pure_parser + +%token TC_SECTION +%token TC_RAW +%token TC_NUMBER %token TC_STRING -%token TC_ENCAPSULATED_STRING -%token BRACK -%token SECTION -%token CFG_TRUE -%token CFG_FALSE +%token TC_OFFSET %token TC_DOLLAR_CURLY +%token TC_VARNAME +%token TC_QUOTED_STRING +%token BOOL_TRUE +%token BOOL_FALSE +%token END_OF_LINE +%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' %left '|' '&' %right '~' '!' +%destructor { free(Z_STRVAL($$)); } TC_RAW TC_NUMBER TC_STRING TC_OFFSET TC_VARNAME TC_QUOTED_STRING BOOL_TRUE BOOL_FALSE + %% statement_list: @@ -250,61 +274,94 @@ ; statement: - TC_STRING '=' string_or_value { + TC_SECTION section_string_or_value ']' { #if DEBUG_CFG_PARSER - printf("'%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3)); + printf("SECTION: [%s]\n", Z_STRVAL($2)); #endif - ZEND_INI_PARSER_CB(&$1, &$3, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG); + ZEND_INI_PARSER_CB(&$2, NULL, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG TSRMLS_CC); + free(Z_STRVAL($2)); + } + | TC_STRING '=' string_or_value { +#if DEBUG_CFG_PARSER + printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3)); +#endif + ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); free(Z_STRVAL($3)); } - | TC_STRING BRACK '=' string_or_value { + | TC_OFFSET option_offset ']' '=' string_or_value { #if DEBUG_CFG_PARSER - printf("'%s'[ ] = '%s'\n", Z_STRVAL($1), Z_STRVAL($4)); + printf("OFFSET: '%s'[%s] = '%s'\n", Z_STRVAL($1), Z_STRVAL($2), Z_STRVAL($5)); #endif - ZEND_INI_PARSER_CB(&$1, &$4, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG); + ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); - free(Z_STRVAL($4)); + free(Z_STRVAL($2)); + free(Z_STRVAL($5)); } - | TC_STRING { ZEND_INI_PARSER_CB(&$1, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG); free(Z_STRVAL($1)); } - | SECTION { ZEND_INI_PARSER_CB(&$1, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG); free(Z_STRVAL($1)); } - | '\n' + | TC_STRING { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); } + | END_OF_LINE ; +section_string_or_value: + TC_RAW { $$ = $1; } + | section_var_list { $$ = $1; } + | '"' encapsed_list '"' { $$ = $2; } + | /* empty */ { zend_ini_init_string(&$$); } +; string_or_value: - expr { $$ = $1; } - | CFG_TRUE { $$ = $1; } - | CFG_FALSE { $$ = $1; } - | '\n' { zend_ini_init_string(&$$); } - | /* empty */ { zend_ini_init_string(&$$); } + expr { $$ = $1; } + | TC_RAW { $$ = $1; } + | TC_NUMBER { $$ = $1; } + | BOOL_TRUE { $$ = $1; } + | BOOL_FALSE { $$ = $1; } + | '"' encapsed_list '"' { $$ = $2; } + | END_OF_LINE { zend_ini_init_string(&$$); } ; +option_offset: + TC_NUMBER { $$ = $1; } + | TC_RAW { $$ = $1; } + | var_string_list { $$ = $1; } + | '"' encapsed_list '"' { $$ = $2; } + | /* empty */ { zend_ini_init_string(&$$); } +; -var_string_list: - cfg_var_ref { $$ = $1; } - | TC_ENCAPSULATED_STRING { $$ = $1; } - | constant_string { $$ = $1; } - | var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free($2.value.str.val); } - | var_string_list TC_ENCAPSULATED_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } - | var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free($2.value.str.val); } +encapsed_list: + encapsed_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } + | encapsed_list TC_QUOTED_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } + | /* empty */ { zend_ini_init_string(&$$); } ; -cfg_var_ref: - TC_DOLLAR_CURLY TC_STRING '}' { zend_ini_get_var(&$$, &$2); free($2.value.str.val); } +section_var_list: + cfg_var_ref { $$ = $1; } + | TC_STRING { $$ = $1; } + | section_var_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } + | section_var_list TC_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } +; + +var_string_list: + cfg_var_ref { $$ = $1; } + | constant_string { $$ = $1; } + | var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } + | var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); } ; expr: - var_string_list { $$ = $1; } - | expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); } - | expr '&' expr { zend_ini_do_op('&', &$$, &$1, &$3); } - | '~' expr { zend_ini_do_op('~', &$$, &$2, NULL); } - | '!' expr { zend_ini_do_op('!', &$$, &$2, NULL); } - | '(' expr ')' { $$ = $2; } + var_string_list { $$ = $1; } + | expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); } + | expr '&' expr { zend_ini_do_op('&', &$$, &$1, &$3); } + | '~' expr { zend_ini_do_op('~', &$$, &$2, NULL); } + | '!' expr { zend_ini_do_op('!', &$$, &$2, NULL); } + | '(' expr ')' { $$ = $2; } +; + +cfg_var_ref: + TC_DOLLAR_CURLY TC_VARNAME '}' { zend_ini_get_var(&$$, &$2 TSRMLS_CC); free(Z_STRVAL($2)); } ; constant_string: - TC_STRING { zend_ini_get_constant(&$$, &$1); } + TC_STRING { zend_ini_get_constant(&$$, &$1 TSRMLS_CC); } ; /* http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_ini_scanner.h?r1=1.14.2.1.2.2&r2=1.14.2.1.2.2.2.1&diff_format=u Index: ZendEngine2/zend_ini_scanner.h diff -u ZendEngine2/zend_ini_scanner.h:1.14.2.1.2.2 ZendEngine2/zend_ini_scanner.h:1.14.2.1.2.2.2.1 --- ZendEngine2/zend_ini_scanner.h:1.14.2.1.2.2 Mon Jan 1 09:35:46 2007 +++ ZendEngine2/zend_ini_scanner.h Fri Sep 28 02:05:08 2007 @@ -17,18 +17,23 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.h,v 1.14.2.1.2.2 2007/01/01 09:35:46 sebastian Exp $ */ +/* $Id: zend_ini_scanner.h,v 1.14.2.1.2.2.2.1 2007/09/28 02:05:08 jani Exp $ */ #ifndef _ZEND_INI_SCANNER_H #define _ZEND_INI_SCANNER_H +/* Scanner modes */ +#define ZEND_INI_SCANNER_NORMAL 0 /* Normal mode. [DEFAULT] */ +#define ZEND_INI_SCANNER_RAW 1 /* Raw mode. Option values are not parsed */ + BEGIN_EXTERN_C() int zend_ini_scanner_get_lineno(TSRMLS_D); char *zend_ini_scanner_get_filename(TSRMLS_D); -int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC); -int zend_ini_prepare_string_for_scanning(char *str TSRMLS_DC); +int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC); +int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC); void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC); int ini_lex(zval *ini_lval TSRMLS_DC); +void shutdown_ini_scanner(TSRMLS_D); END_EXTERN_C() #endif /* _ZEND_INI_SCANNER_H */ http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_ini_scanner.l?r1=1.41.2.2.2.2&r2=1.41.2.2.2.2.2.1&diff_format=u Index: ZendEngine2/zend_ini_scanner.l diff -u ZendEngine2/zend_ini_scanner.l:1.41.2.2.2.2 ZendEngine2/zend_ini_scanner.l:1.41.2.2.2.2.2.1 --- ZendEngine2/zend_ini_scanner.l:1.41.2.2.2.2 Mon Jul 23 16:17:10 2007 +++ ZendEngine2/zend_ini_scanner.l Fri Sep 28 02:05:08 2007 @@ -13,21 +13,71 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Zeev Suraski <zeev@zend.com> | + | Authors: Zeev Suraski <zeev@zend.com> | + | Jani Taskinen <jani@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.l,v 1.41.2.2.2.2 2007/07/23 16:17:10 jani Exp $ */ +/* $Id: zend_ini_scanner.l,v 1.41.2.2.2.2.2.1 2007/09/28 02:05:08 jani Exp $ */ + +#define DEBUG_CFG_SCANNER 0 #define yyleng SCNG(yy_leng) #define yytext SCNG(yy_text) #define yytext_ptr SCNG(yy_text) #define yyin SCNG(yy_in) #define yyout SCNG(yy_out) + +/* How it works (for the core ini directives): + * =========================================== + * + * 1. Scanner scans file for tokens and passes them to parser. + * 2. Parser parses the tokens and passes the name/value pairs to the callback + * function which stores them in the configuration hash table. + * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual + * registering of ini entries and uses zend_get_configuration_directive() + * to fetch the previously stored name/value pair from configuration hash table + * and registers the static ini entries which match the name to the value + * into EG(ini_directives) hash table. + * 4. PATH section entries are used per-request from down to top, each overriding + * previous if one exists. zend_alter_ini_entry() is called for each entry. + * Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the + * php_admin_* directives used within Apache httpd.conf when PHP is compiled as + * module for Apache. + * 5. User defined ini files (like .htaccess for apache) are parsed for each request and + * stored in separate hash defined by SAPI. + */ + +/* TODO: (ordered by importance :-) + * =============================================================================== + * + * - Separate constant lookup totally from plain strings (using CONSTANT pattern) + * - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators + * - Add #include "some.ini" + * - Allow variables to refer to options also when using parse_ini_file() + * + */ + +/* These are not needed when yymore() is not used */ +/* #define yy_last_accepting_state SCNG(_yy_last_accepting_state) #define yy_last_accepting_cpos SCNG(_yy_last_accepting_cpos) #define yy_more_flag SCNG(_yy_more_flag) #define yy_more_len SCNG(_yy_more_len) +*/ + +%} + +%x ST_DOUBLE_QUOTES +%x ST_OFFSET +%x ST_RAW +%x ST_SECTION_RAW +%x ST_SECTION_VALUE +%x ST_VALUE +%x ST_VARNAME +%option stack + +%{ #include <errno.h> #include "zend.h" @@ -35,9 +85,6 @@ #include <zend_ini_parser.h> #include "zend_ini_scanner.h" -#undef YYSTYPE -#define YYSTYPE zval - #define YY_DECL int ini_lex(zval *ini_lval TSRMLS_DC) /* Globals Macros */ @@ -48,204 +95,417 @@ ZEND_API zend_scanner_globals ini_scanner_globals; #endif -# define YY_INPUT(buf, result, max_size) \ - if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \ - && zend_stream_ferror( yyin TSRMLS_CC) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); +/* Eat trailing whitespace + extra char */ +#define EAT_TRAILING_WHITESPACE_EX(ch) \ + while (yyleng > 0 && ( \ + (ch != 'X' && yytext[yyleng - 1] == ch) || \ + yytext[yyleng - 1] == '\n' || \ + yytext[yyleng - 1] == '\r' || \ + yytext[yyleng - 1] == '\t' || \ + yytext[yyleng - 1] == ' ') \ + ) { \ + yyleng--; \ + yytext[yyleng]=0; \ + } + +/* Eat trailing whitespace */ +#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') + +#define zend_ini_copy_value(retval, str, len) { \ + Z_STRVAL_P(retval) = zend_strndup(str, len); \ + Z_STRLEN_P(retval) = len; \ + Z_TYPE_P(retval) = IS_STRING; \ +} + +#define RETURN_TOKEN(type, str, len) { \ + zend_ini_copy_value(ini_lval, str, len); \ + return type; \ +} static char *ini_filename; -void init_ini_scanner(TSRMLS_D) +/* {{{ init_ini_scanner() +*/ +static void init_ini_scanner(TSRMLS_D) { - SCNG(lineno)=1; + SCNG(lineno) = 1; + SCNG(scanner_mode) = ZEND_INI_SCANNER_NORMAL; + SCNG(yy_start_stack_ptr) = 0; + SCNG(yy_start_stack_depth) = 0; + SCNG(current_buffer) = NULL; +} +/* }}} */ + +/* {{{ shutdown_ini_scanner() +*/ +void shutdown_ini_scanner(TSRMLS_D) +{ + if (SCNG(yy_start_stack)) { + yy_flex_free(SCNG(yy_start_stack)); + SCNG(yy_start_stack) = NULL; + } + yy_delete_buffer(SCNG(current_buffer) TSRMLS_CC); + if (ini_filename) { + free(ini_filename); + } } +/* }}} */ +/* {{{ zend_ini_scanner_get_lineno() +*/ int zend_ini_scanner_get_lineno(TSRMLS_D) { return SCNG(lineno); } +/* }}} */ +/* {{{ zend_ini_scanner_get_filename() +*/ char *zend_ini_scanner_get_filename(TSRMLS_D) { return ini_filename; } +/* }}} */ -int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC) +/* {{{ zend_ini_open_file_for_scanning() +*/ +int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC) { if (FAILURE == zend_stream_fixup(fh TSRMLS_CC)) { return FAILURE; } init_ini_scanner(TSRMLS_C); + SCNG(scanner_mode) = scanner_mode; yyin = fh; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC); - ini_filename = fh->filename; + ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); return SUCCESS; } +/* }}} */ -int zend_ini_prepare_string_for_scanning(char *str TSRMLS_DC) +/* {{{ zend_ini_prepare_string_for_scanning() +*/ +int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) { int len = strlen(str); + init_ini_scanner(TSRMLS_C); + SCNG(scanner_mode) = scanner_mode; yyin = NULL; yy_scan_buffer(str, len + 2 TSRMLS_CC); ini_filename = NULL; return SUCCESS; } +/* }}} */ +/* {{{ zend_ini_close_file() +*/ void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC) { zend_stream_close(fh); } +/* }}} */ + +/* {{{ zend_ini_escape_string() + */ +static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC) +{ + register char *s, *t; + char *end; + + zend_ini_copy_value(lval, str, len); + + /* convert escape sequences */ + s = t = Z_STRVAL_P(lval); + end = s + Z_STRLEN_P(lval); + + while (s < end) { + if (*s == '\\') { + s++; + if (s >= end) { + continue; + } + switch (*s) { + case 'n': + *t++ = '\n'; + Z_STRLEN_P(lval)--; + break; + case 'r': + *t++ = '\r'; + Z_STRLEN_P(lval)--; + break; + case 't': + *t++ = '\t'; + Z_STRLEN_P(lval)--; + break; + case '"': + if (*s != quote_type) { + *t++ = '\\'; + *t++ = *s; + break; + } + case '\\': + case '$': + *t++ = *s; + Z_STRLEN_P(lval)--; + break; + default: + *t++ = '\\'; + *t++ = *s; + break; + } + } else { + *t++ = *s; + } + + if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { + SCNG(lineno)++; + } + s++; + } + *t = 0; +} +/* }}} */ %} -NEWLINE ("\r"|"\n"|"\r\n") +LNUM [0-9]+ +DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*) +NUMBER {LNUM}|{DNUM} +ANY_CHAR (.|[\n]) +NEWLINE ("\r"|"\n"|"\r\n") +TABS_AND_SPACES [ \t] +CONSTANT [a-zA-Z][a-zA-Z0-9_]* +LABEL [a-zA-Z0-9][a-zA-Z0-9._]* +TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@] +OPERATORS [&|~()!] + +LITERAL_DOLLAR ("$"+([^a-zA-Z0-9$"'\\{]|("\\"{ANY_CHAR}))) +VALUE_CHARS ("{"*([^=\n\r;&|~()!$"'\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) +RAW_VALUE_CHARS [^=\n\r;] +SINGLE_QUOTED_CHARS [^'] + +SECTION_VALUE_CHARS ("{"*([^\n\r;$"'\\{\]]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) +SECTION_RAW_CHARS [^\]\n\r] + +/* Allow using ${foobar} inside quoted strings */ +DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) +/* " */ + +%option nounput %option noyywrap +%option noyylineno +%option noyy_top_state %option never-interactive %% -<INITIAL>[ ]*[\[][ ]*[\]][ ]* { - return BRACK; +<INITIAL>"[" { /* Section start */ + /* Enter section data lookup state */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_SECTION_RAW TSRMLS_CC); + } else { + yy_push_state(ST_SECTION_VALUE TSRMLS_CC); + } + return TC_SECTION; +} + +<ST_VALUE,ST_SECTION_VALUE,ST_OFFSET>"'"{SINGLE_QUOTED_CHARS}+"'" { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + yytext++; + yyleng = yyleng - 2; + yytext[yyleng] = 0; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); } -<INITIAL>[ ]*("true"|"on"|"yes")[ ]* { - Z_STRVAL_P(ini_lval) = zend_strndup("1", 1); - Z_STRLEN_P(ini_lval) = 1; - Z_TYPE_P(ini_lval) = IS_STRING; - return CFG_TRUE; +<ST_SECTION_RAW,ST_SECTION_VALUE>"]"{TABS_AND_SPACES}*{NEWLINE}? { /* End of section */ + BEGIN(INITIAL); + SCNG(lineno)++; + return ']'; } +<INITIAL>{LABEL}"["{TABS_AND_SPACES}* { /* Start of option with offset */ + /* Eat trailing whitespace and [ */ + EAT_TRAILING_WHITESPACE_EX('['); -<INITIAL>[ ]*("false"|"off"|"no"|"none"|"null")[ ]* { - Z_STRVAL_P(ini_lval) = zend_strndup("", 0); - Z_STRLEN_P(ini_lval) = 0; - Z_TYPE_P(ini_lval) = IS_STRING; - return CFG_FALSE; + /* Enter offset lookup state */ + yy_push_state(ST_OFFSET TSRMLS_CC); + + RETURN_TOKEN(TC_OFFSET, yytext, yyleng); } -<INITIAL>[[][^\]\n]+[\]][ ]*{NEWLINE}? { - /* SECTION */ +<ST_OFFSET>{TABS_AND_SPACES}*"]" { /* End of section or an option offset */ + BEGIN(INITIAL); + return ']'; +} - /* eat trailing ] and spaces */ - while (yyleng>0 && (yytext[yyleng-1]=='\n' || yytext[yyleng-1]=='\r' || yytext[yyleng-1]==']' || yytext[yyleng-1]==' ')) { - yyleng--; - yytext[yyleng]=0; - } +<ST_DOUBLE_QUOTES,ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>"${" { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} - SCNG(lineno)++; +<ST_VARNAME>{LABEL} { /* Variable name */ + RETURN_TOKEN(TC_VARNAME, yytext, yyleng); +} - /* eat leading [ */ - yytext++; - yyleng--; +<ST_VARNAME>"}" { /* Variable end */ + yy_pop_state(TSRMLS_C); + return '}'; +} - Z_STRVAL_P(ini_lval) = zend_strndup(yytext, yyleng); - Z_STRLEN_P(ini_lval) = yyleng; - Z_TYPE_P(ini_lval) = IS_STRING; - return SECTION; +<INITIAL,ST_VALUE>("true"|"on"|"yes"){TABS_AND_SPACES}* { /* TRUE value (when used outside option value/offset this causes parse error!) */ + RETURN_TOKEN(BOOL_TRUE, "1", 1); } -<INITIAL>["][^"]*["] { - char *p = yytext; +<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/ + RETURN_TOKEN(BOOL_FALSE, "", 0); +} - /* ENCAPSULATED TC_STRING */ +<INITIAL,ST_OFFSET>{LABEL} { /* Get option name or option offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} - while ((p = strpbrk(p, "\r\n"))) { - if (*p == '\r' && *(p + 1) == '\n') { - p++; - } - SCNG(lineno)++; - p++; +<INITIAL>{TABS_AND_SPACES}*[=]{TABS_AND_SPACES}* { /* Start option value */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_RAW TSRMLS_CC); + } else { + yy_push_state(ST_VALUE TSRMLS_CC); } + return '='; +} - /* eat trailing " */ - yytext[yyleng-1]=0; +<ST_RAW>{RAW_VALUE_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + /* Eat leading and trailing double quotes */ + if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { + yytext++; + yyleng = yyleng - 2; + yytext[yyleng] = 0; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} - /* eat leading " */ - yytext++; +<ST_SECTION_RAW>{SECTION_RAW_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} - Z_STRVAL_P(ini_lval) = zend_strndup(yytext, yyleng - 2); - Z_STRLEN_P(ini_lval) = yyleng - 2; - Z_TYPE_P(ini_lval) = IS_STRING; - return TC_ENCAPSULATED_STRING; +<ST_VALUE,ST_RAW>{NEWLINE} { /* End of option value */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; } -<INITIAL>"${" { - return TC_DOLLAR_CURLY; +<ST_VALUE,ST_OFFSET>{CONSTANT} { /* Get constant option value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); } -<INITIAL>"}" { - Z_LVAL_P(ini_lval) = (long) yytext[0]; +<ST_VALUE,ST_OFFSET>{NUMBER} { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} + +<INITIAL>{TOKENS} { /* Disallow these chars outside option values */ return yytext[0]; } -<INITIAL>[&|~$(){}!] { +<ST_VALUE>{OPERATORS}{TABS_AND_SPACES}* { /* Boolean operators */ return yytext[0]; } -<INITIAL>[^=\n\r\t;|&$~(){}!"\[]+ { - /* STRING */ - register int i; - - /* eat trailing whitespace */ - for (i=yyleng-1; i>=0; i--) { - if (yytext[i]==' ' || yytext[i]=='\t') { - yytext[i]=0; - yyleng--; - } else { - break; - } - } - /* eat leading whitespace */ - while (yytext[0]) { - if (yytext[0]==' ' || yytext[0]=='\t') { - yytext++; - yyleng--; - } else { - break; - } - } - if (yyleng!=0) { - Z_STRVAL_P(ini_lval) = zend_strndup(yytext, yyleng); - Z_STRLEN_P(ini_lval) = yyleng; - Z_TYPE_P(ini_lval) = IS_STRING; - return TC_STRING; - } else { - /* whitespace */ - } +<ST_VALUE>[=] { /* Make = used in option value to trigger error */ + yyless(yyleng - 1); + BEGIN(INITIAL); + return END_OF_LINE; } -<INITIAL>[=\n] { - if (yytext[0] == '\n') { - SCNG(lineno)++; - } - return yytext[0]; +<ST_VALUE>{VALUE_CHARS}+ { /* Get everything else as option/offset value */ + /* Eat trailing tabs and spaces */ + EAT_TRAILING_WHITESPACE(); + RETURN_TOKEN(TC_STRING, yytext, yyleng); } -<INITIAL>{NEWLINE} { - SCNG(lineno)++; - return '\n'; +<ST_SECTION_VALUE,ST_OFFSET>{SECTION_VALUE_CHARS}+ { /* Get rest as section/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); } -<INITIAL>[;][^\r\n]*{NEWLINE}? { - /* comment */ - SCNG(lineno)++; - return '\n'; +<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>["] { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} + +<ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}+ { /* Escape double quoted string contents */ + zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); + return TC_QUOTED_STRING; +} + +<ST_DOUBLE_QUOTES>["] { /* Double quoted '"' string ends */ + yy_pop_state(TSRMLS_C); + return '"'; } -<INITIAL>[ \t] { +<INITIAL,ST_VALUE,ST_RAW,ST_OFFSET>{TABS_AND_SPACES} { /* eat whitespace */ } -<INITIAL>. { -#if DEBUG - php_error(E_NOTICE,"Unexpected character on line %d: '%s' (ASCII %d)\n", yylineno, yytext, yytext[0]); -#endif +<INITIAL>{NEWLINE} { + SCNG(lineno)++; + return END_OF_LINE; +} + +<INITIAL,ST_VALUE,ST_RAW>[;][^\r\n]*{NEWLINE} { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} + +<ST_VALUE,ST_RAW><<EOF>> { /* End of option value (if EOF is reached before EOL */ + BEGIN(INITIAL); + return END_OF_LINE; } <<EOF>> { - yy_delete_buffer(YY_CURRENT_BUFFER TSRMLS_CC); +#if DEBUG_CFG_SCANNER + while (YYSTATE != INITIAL) { + switch (YYSTATE) { + case INITIAL: + break; + + case ST_DOUBLE_QUOTES: + fprintf(stderr, "ERROR: Unterminated ini option value double quotes\n"); + break; + + case ST_OFFSET: + fprintf(stderr, "ERROR: Unterminated ini option offset\n"); + break; + + case ST_RAW: + fprintf(stderr, "ERROR: Unterminated raw ini option value\n"); + break; + + case ST_SECTION_RAW: + fprintf(stderr, "ERROR: Unterminated raw ini section value\n"); + break; + + case ST_SECTION_VALUE: + fprintf(stderr, "ERROR: Unterminated ini section value\n"); + break; + + case ST_VALUE: + fprintf(stderr, "ERROR: Unterminated ini option value\n"); + break; + + case ST_VARNAME: + fprintf(stderr, "ERROR: Unterminated ini variable\n"); + break; + + default: + fprintf(stderr, "BUG: Unknown state (%d)\n", YYSTATE); + break; + } + yy_pop_state(TSRMLS_C); + } +#endif yyterminate(); } http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.725.2.31.2.64.2.1&r2=1.725.2.31.2.64.2.2&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.1 php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.2 --- php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.1 Thu Sep 27 18:00:45 2007 +++ php-src/ext/standard/basic_functions.c Fri Sep 28 02:05:08 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.725.2.31.2.64.2.1 2007/09/27 18:00:45 dmitry Exp $ */ +/* $Id: basic_functions.c,v 1.725.2.31.2.64.2.2 2007/09/28 02:05:08 jani Exp $ */ #include "php.h" #include "php_streams.h" @@ -41,6 +41,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #include "zend.h" +#include "zend_ini_scanner.h" #include "zend_language_scanner.h" #include <zend_language_parser.h> @@ -947,8 +948,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_parse_ini_file, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, process_sections) + ZEND_ARG_INFO(0, scanner_mode) ZEND_END_ARG_INFO() +#if ZEND_DEBUG +static +ZEND_BEGIN_ARG_INFO(arginfo_dump_config_hash, 0) +ZEND_END_ARG_INFO() +#endif + static ZEND_BEGIN_ARG_INFO_EX(arginfo_import_request_variables, 0, 0, 1) ZEND_ARG_INFO(0, types) @@ -1405,6 +1413,7 @@ ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() #endif + static ZEND_BEGIN_ARG_INFO(arginfo_sys_get_temp_dir, 0) ZEND_END_ARG_INFO() @@ -3384,7 +3393,7 @@ PHP_FE(set_magic_quotes_runtime, NULL) PHP_FE(get_magic_quotes_gpc, NULL) PHP_FE(get_magic_quotes_runtime, NULL) - + PHP_FE(import_request_variables, arginfo_import_request_variables) PHP_FE(error_log, arginfo_error_log) PHP_FE(error_get_last, arginfo_error_get_last) @@ -3430,6 +3439,9 @@ PHP_FE(connection_status, arginfo_connection_status) PHP_FE(ignore_user_abort, arginfo_ignore_user_abort) PHP_FE(parse_ini_file, arginfo_parse_ini_file) +#if ZEND_DEBUG + PHP_FE(dump_config_hash, arginfo_dump_config_hash) +#endif PHP_FE(is_uploaded_file, arginfo_is_uploaded_file) PHP_FE(move_uploaded_file, arginfo_move_uploaded_file) @@ -3988,6 +4000,9 @@ REGISTER_LONG_CONSTANT("INI_SYSTEM", ZEND_INI_SYSTEM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INI_ALL", ZEND_INI_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INI_SCANNER_NORMAL", ZEND_INI_SCANNER_NORMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("INI_SCANNER_RAW", ZEND_INI_SCANNER_RAW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHP_URL_SCHEME", PHP_URL_SCHEME, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_URL_HOST", PHP_URL_HOST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_URL_PORT", PHP_URL_PORT, CONST_CS | CONST_PERSISTENT); @@ -4847,12 +4862,34 @@ } /* }}} */ -/* {{{ proto string get_cfg_var(string option_name) +/* {{{ add_config_entry_cb + */ +static int add_config_entry_cb(zval *entry, int num_args, va_list args, zend_hash_key *hash_key TSRMLS_DC) +{ + zval *retval = (zval *) va_arg(args, int); + zval *tmp; + + if (Z_TYPE_P(entry) == IS_STRING) { + if (hash_key->nKeyLength > 0) { + add_assoc_stringl_ex(retval, hash_key->arKey, hash_key->nKeyLength, Z_STRVAL_P(entry), Z_STRLEN_P(entry), 1); + } else { + add_index_stringl(retval, hash_key->h, Z_STRVAL_P(entry), Z_STRLEN_P(entry), 1); + } + } else if (Z_TYPE_P(entry) == IS_ARRAY) { + MAKE_STD_ZVAL(tmp); + array_init(tmp); + zend_hash_apply_with_arguments(Z_ARRVAL_P(entry), (apply_func_args_t) add_config_entry_cb, 1, tmp TSRMLS_CC); + add_assoc_zval_ex(retval, hash_key->arKey, hash_key->nKeyLength, tmp); + } + return 0; +} +/* }}} */ + +/* {{{ proto mixed get_cfg_var(string option_name) Get the value of a PHP configuration option */ PHP_FUNCTION(get_cfg_var) { - zval **varname; - char *value; + zval **varname, *retval; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &varname) == FAILURE) { WRONG_PARAM_COUNT; @@ -4860,10 +4897,19 @@ convert_to_string_ex(varname); - if (cfg_get_string(Z_STRVAL_PP(varname), &value) == FAILURE) { + retval = cfg_get_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname) + 1); + + if (retval) { + if (Z_TYPE_P(retval) == IS_ARRAY) { + array_init(return_value); + zend_hash_apply_with_arguments(Z_ARRVAL_P(retval), (apply_func_args_t) add_config_entry_cb, 1, return_value TSRMLS_CC); + return; + } else { + RETURN_STRING(Z_STRVAL_P(retval), 1); + } + } else { RETURN_FALSE; } - RETURN_STRING(value, 1); } /* }}} */ @@ -5576,7 +5622,7 @@ convert_to_string_ex(varname); - str = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0); + str = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname) + 1, 0); if (!str) { RETURN_FALSE; @@ -5713,8 +5759,7 @@ } } - if (zend_alter_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value), - PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) { + if (zend_alter_ini_entry_ex(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname) + 1, Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } @@ -5739,7 +5784,6 @@ /* {{{ proto string set_include_path(string new_include_path) Sets the include_path configuration option */ - PHP_FUNCTION(set_include_path) { zval **new_value; @@ -5756,19 +5800,15 @@ } else { RETVAL_FALSE; } - if (zend_alter_ini_entry("include_path", sizeof("include_path"), - Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value), - PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) { + if (zend_alter_ini_entry_ex("include_path", sizeof("include_path"), Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } } - /* }}} */ /* {{{ proto string get_include_path() Get the current include_path configuration option */ - PHP_FUNCTION(get_include_path) { char *str; @@ -5781,22 +5821,18 @@ } RETURN_STRING(str, 1); } - /* }}} */ /* {{{ proto void restore_include_path() Restore the value of the include_path configuration option */ - PHP_FUNCTION(restore_include_path) { if (ZEND_NUM_ARGS() != 0) { WRONG_PARAM_COUNT; } - zend_restore_ini_entry("include_path", sizeof("include_path"), - PHP_INI_STAGE_RUNTIME); + zend_restore_ini_entry("include_path", sizeof("include_path"), PHP_INI_STAGE_RUNTIME); } - /* }}} */ /* {{{ proto mixed print_r(mixed var [, bool return]) @@ -5861,7 +5897,7 @@ RETURN_FALSE; } convert_to_string_ex(arg); - zend_alter_ini_entry("ignore_user_abort", sizeof("ignore_user_abort"), Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_alter_ini_entry_ex("ignore_user_abort", sizeof("ignore_user_abort"), Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); break; default: @@ -6116,7 +6152,7 @@ /* {{{ php_simple_ini_parser_cb */ -static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, zval *arr) +static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr TSRMLS_DC) { zval *element; @@ -6146,11 +6182,11 @@ if (!(Z_STRLEN_P(arg1) > 1 && Z_STRVAL_P(arg1)[0] == '0') && is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) == IS_LONG) { ulong key = (ulong) zend_atoi(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); if (zend_hash_index_find(Z_ARRVAL_P(arr), key, (void **) &find_hash) == FAILURE) { - ALLOC_ZVAL(hash); - INIT_PZVAL(hash); - array_init(hash); + ALLOC_ZVAL(hash); + INIT_PZVAL(hash); + array_init(hash); - zend_hash_index_update(Z_ARRVAL_P(arr), key, &hash, sizeof(zval *), NULL); + zend_hash_index_update(Z_ARRVAL_P(arr), key, &hash, sizeof(zval *), NULL); } else { hash = *find_hash; } @@ -6176,7 +6212,12 @@ *element = *arg2; zval_copy_ctor(element); INIT_PZVAL(element); - add_next_index_zval(hash, element); + + if (arg3 && Z_STRLEN_P(arg3) > 0) { + add_assoc_zval_ex(hash, Z_STRVAL_P(arg3), Z_STRLEN_P(arg3) + 1, element); + } else { + add_next_index_zval(hash, element); + } } break; @@ -6188,10 +6229,8 @@ /* {{{ php_ini_parser_cb_with_sections */ -static void php_ini_parser_cb_with_sections(zval *arg1, zval *arg2, int callback_type, zval *arr) +static void php_ini_parser_cb_with_sections(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr TSRMLS_DC) { - TSRMLS_FETCH(); - if (callback_type == ZEND_INI_PARSER_SECTION) { MAKE_STD_ZVAL(BG(active_ini_file_section)); array_init(BG(active_ini_file_section)); @@ -6205,59 +6244,62 @@ active_arr = arr; } - php_simple_ini_parser_cb(arg1, arg2, callback_type, active_arr); + php_simple_ini_parser_cb(arg1, arg2, arg3, callback_type, active_arr TSRMLS_CC); } } /* }}} */ -/* {{{ proto array parse_ini_file(string filename [, bool process_sections]) +/* {{{ proto array parse_ini_file(string filename [, bool process_sections [, int scanner_mode]]) Parse configuration file */ PHP_FUNCTION(parse_ini_file) { - zval **filename, **process_sections; + char *filename = NULL; + int filename_len = 0; + zend_bool process_sections = 0; + long scanner_mode = ZEND_INI_SCANNER_NORMAL; zend_file_handle fh; zend_ini_parser_cb_t ini_parser_cb; - switch (ZEND_NUM_ARGS()) { - - case 1: - if (zend_get_parameters_ex(1, &filename) == FAILURE) { - RETURN_FALSE; - } - ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb; - break; - - case 2: - if (zend_get_parameters_ex(2, &filename, &process_sections) == FAILURE) { - RETURN_FALSE; - } - - convert_to_boolean_ex(process_sections); - - if (Z_BVAL_PP(process_sections)) { - BG(active_ini_file_section) = NULL; - ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections; - } else { - ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb; - } - break; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &filename, &filename_len, &process_sections, &scanner_mode) == FAILURE) { + RETURN_FALSE; + } - default: - ZEND_WRONG_PARAM_COUNT(); - break; + if (filename_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename can not be empty!"); + RETURN_FALSE; } - convert_to_string_ex(filename); + /* Set callback function */ + if (process_sections) { + BG(active_ini_file_section) = NULL; + ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections; + } else { + ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb; + } + /* Setup filehandle */ memset(&fh, 0, sizeof(fh)); - fh.filename = Z_STRVAL_PP(filename); - Z_TYPE(fh) = ZEND_HANDLE_FILENAME; + fh.filename = filename; + fh.type = ZEND_HANDLE_FILENAME; array_init(return_value); - zend_parse_ini_file(&fh, 0, ini_parser_cb, return_value); + zend_parse_ini_file(&fh, 0, scanner_mode, ini_parser_cb, return_value TSRMLS_CC); } /* }}} */ +#if ZEND_DEBUG +/* {{{ proto void dump_config_hash(void) + */ +PHP_FUNCTION(dump_config_hash) +{ + HashTable hash = get_configuration_hash(); + + array_init(return_value); + zend_hash_apply_with_arguments(&hash, (apply_func_args_t) add_config_entry_cb, 1, return_value TSRMLS_CC); +} +/* }}} */ +#endif + static int copy_request_variable(void *pDest, int num_args, va_list args, zend_hash_key *hash_key) { char *prefix, *new_key; http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.h?r1=1.139.2.4.2.6&r2=1.139.2.4.2.6.2.1&diff_format=u Index: php-src/ext/standard/basic_functions.h diff -u php-src/ext/standard/basic_functions.h:1.139.2.4.2.6 php-src/ext/standard/basic_functions.h:1.139.2.4.2.6.2.1 --- php-src/ext/standard/basic_functions.h:1.139.2.4.2.6 Sat Jul 21 01:24:26 2007 +++ php-src/ext/standard/basic_functions.h Fri Sep 28 02:05:09 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.139.2.4.2.6 2007/07/21 01:24:26 jani Exp $ */ +/* $Id: basic_functions.h,v 1.139.2.4.2.6.2.1 2007/09/28 02:05:09 jani Exp $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -125,6 +125,9 @@ /* From the INI parser */ PHP_FUNCTION(parse_ini_file); +#if ZEND_DEBUG +PHP_FUNCTION(dump_config_hash); +#endif PHP_FUNCTION(str_rot13); PHP_FUNCTION(stream_get_filters); http://cvs.php.net/viewvc.cgi/php-src/ext/standard/browscap.c?r1=1.85.2.2.2.3&r2=1.85.2.2.2.3.2.1&diff_format=u Index: php-src/ext/standard/browscap.c diff -u php-src/ext/standard/browscap.c:1.85.2.2.2.3 php-src/ext/standard/browscap.c:1.85.2.2.2.3.2.1 --- php-src/ext/standard/browscap.c:1.85.2.2.2.3 Wed Mar 7 00:52:40 2007 +++ php-src/ext/standard/browscap.c Fri Sep 28 02:05:09 2007 @@ -16,18 +16,19 @@ +----------------------------------------------------------------------+ */ -/* $Id: browscap.c,v 1.85.2.2.2.3 2007/03/07 00:52:40 iliaa Exp $ */ +/* $Id: browscap.c,v 1.85.2.2.2.3.2.1 2007/09/28 02:05:09 jani Exp $ */ #include "php.h" #include "php_regex.h" #include "php_browscap.h" #include "php_ini.h" #include "php_string.h" - +#include "zend_ini_scanner.h" #include "zend_globals.h" static HashTable browser_hash; static zval *current_section; +static char *current_section_name; #define DEFAULT_SECTION_NAME "Default Browser Capability Settings" @@ -88,7 +89,7 @@ /* {{{ php_browscap_parser_cb */ -static void php_browscap_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg) +static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg TSRMLS_DC) { if (!arg1) { return; @@ -100,12 +101,37 @@ zval *new_property; char *new_key; + /* parent entry can not be same as current section -> causes infinite loop! */ + if (!strcasecmp(Z_STRVAL_P(arg1), "parent") && + !strcasecmp(current_section_name, Z_STRVAL_P(arg2)) + ) { + zend_error(E_CORE_ERROR, "Invalid browscap ini file: 'Parent' value can not be same as the section name: %s (in file %s)", current_section_name, INI_STR("browscap")); + return; + } + new_property = (zval *) pemalloc(sizeof(zval), 1); INIT_PZVAL(new_property); - Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); - Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2); Z_TYPE_P(new_property) = IS_STRING; + /* Set proper value for true/false settings */ + if ((Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "on", sizeof("on") - 1)) || + (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "yes", sizeof("yes") - 1)) || + (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "true", sizeof("true") - 1)) + ) { + Z_STRVAL_P(new_property) = zend_strndup("1", 1); + Z_STRLEN_P(new_property) = 1; + } else if ( + (Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "no", sizeof("no") - 1)) || + (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "off", sizeof("off") - 1)) || + (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "none", sizeof("none") - 1)) || + (Z_STRLEN_P(arg2) == 5 && !strncasecmp(Z_STRVAL_P(arg2), "false", sizeof("false") - 1)) + ) { + Z_STRVAL_P(new_property) = zend_strndup("", 0); + Z_STRLEN_P(new_property) = 0; + } else { /* Other than true/false setting */ + Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); + Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2); + } new_key = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); zend_str_tolower(new_key, Z_STRLEN_P(arg1)); zend_hash_update(Z_ARRVAL_P(current_section), new_key, Z_STRLEN_P(arg1)+1, &new_property, sizeof(zval *), NULL); @@ -127,8 +153,10 @@ section_properties = (HashTable *) pemalloc(sizeof(HashTable), 1); zend_hash_init(section_properties, 0, NULL, (dtor_func_t) browscap_entry_dtor, 1); - current_section->value.ht = section_properties; - current_section->type = IS_ARRAY; + Z_ARRVAL_P(current_section) = section_properties; + Z_TYPE_P(current_section) = IS_ARRAY; + current_section_name = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); + zend_hash_update(&browser_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, (void *) &current_section, sizeof(zval *), NULL); Z_STRVAL_P(processed) = Z_STRVAL_P(arg1); @@ -171,7 +199,7 @@ } fh.filename = browscap; Z_TYPE(fh) = ZEND_HANDLE_FP; - zend_parse_ini_file(&fh, 1, (zend_ini_parser_cb_t) php_browscap_parser_cb, &browser_hash); + zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_RAW, (zend_ini_parser_cb_t) php_browscap_parser_cb, &browser_hash TSRMLS_CC); } return SUCCESS; http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/parse_ini_file.phpt?r1=1.1.2.1&r2=1.1.2.1.2.1&diff_format=u Index: php-src/ext/standard/tests/file/parse_ini_file.phpt diff -u php-src/ext/standard/tests/file/parse_ini_file.phpt:1.1.2.1 php-src/ext/standard/tests/file/parse_ini_file.phpt:1.1.2.1.2.1 --- php-src/ext/standard/tests/file/parse_ini_file.phpt:1.1.2.1 Mon Aug 13 11:34:42 2007 +++ php-src/ext/standard/tests/file/parse_ini_file.phpt Fri Sep 28 02:05:09 2007 @@ -50,98 +50,98 @@ [Non-alphanumerics_as_values] ;Non-alpha numeric chars without quotes -Non-alpha1 = ; -Non-alpha2 = + -Non-alpha3 = * -Non-alpha4 = % -Non-alpha5 = <> -Non-alpha6 = @ -Non-alpha7 = # -Non-alpha8 = ^ -non-alpha9 = - -Non-alpha10 = : -Non-alpha11 = ? -Non-alpha12 = / -Non-alpha13 = \ +Non_alpha1 = ; +Non_alpha2 = + +Non_alpha3 = * +Non_alpha4 = % +Non_alpha5 = <> +Non_alpha6 = @ +Non_alpha7 = # +Non_alpha8 = ^ +Non_alpha9 = - +Non_alpha10 = : +Non_alpha11 = ? +Non_alpha12 = / +Non_alpha13 = \ ;These chars have a special meaning when used in the value, ; hence parser throws an error -;Non-alpha14 = & -;Non-alpha15 = {} -;Non-alpha16 = | -;Non-alpha17 = ~ -;Non-alpha18 = ! -;Non-alpha19 = $ -;Non-alpha20 = () - -Non-alpha1_quotes = ";" -Non-alpha2_quotes = "+" -Non-alpha3_quotes = "*" -Non-alpha4_quotes = "%" -Non-alpha5_quotes = "<>" -Non-alpha6_quotes = "@" -Non-alpha7_quotes = "#" -Non-alpha8_quotes = "^" -Non-alpha9_quotes = "-" -Non-alpha10_quotes = "=" -Non-alpha11_quotes = ":" -Non-alpha12_quotes = "?" -Non-alpha13_quotes = "/" -Non-alpha14_quotes = "\" -Non-alpha15_quotes = "&" -Non-alpha16_quotes = "{}" -Non-alpha17_quotes = "|" -Non-alpha18_quotes = "~" -Non-alpha19_quotes = "!" -non-alpha20_quotes = "$" -non-alpha21_quotes = "()" +;Non_alpha14 = & +;Non_alpha15 = {} +;Non_alpha16 = | +;Non_alpha17 = ~ +;Non_alpha18 = ! +;Non_alpha19 = $ +;Non_alpha20 = () + +Non_alpha1_quotes = ";" +Non_alpha2_quotes = "+" +Non_alpha3_quotes = "*" +Non_alpha4_quotes = "%" +Non_alpha5_quotes = "<>" +Non_alpha6_quotes = "@" +Non_alpha7_quotes = "#" +Non_alpha8_quotes = "^" +Non_alpha9_quotes = "-" +Non_alpha10_quotes = "=" +Non_alpha11_quotes = ":" +Non_alpha12_quotes = "?" +Non_alpha13_quotes = "/" +;Non_alpha14_quotes = "\" +Non_alpha15_quotes = "&" +Non_alpha16_quotes = "{}" +Non_alpha17_quotes = "|" +Non_alpha18_quotes = "~" +Non_alpha19_quotes = "!" +;Non_alpha20_quotes = "$" +Non_alpha21_quotes = "()" [Non-alpha numerics in strings] ;expected error, as the non-alphanumeric chars not enclosed in double quotes("") -Non-alpha_string1 = Hello@world -;Non-alpha_string2 = Hello!world -;Non-alpha_string3 = Hello#world -;Non-alpha_string4 = Hello%world -;Non-alpha_string5 = Hello&world -;Non-alpha_string6 = Hello*world -;Non-alpha_string7 = Hello+world -;Non-alpha_string8 = Hello-world -;Non-alpha_string9 = Hello'world -;Non-alpha_string10 = Hello:world -;Non-alpha_string11 = Hello;world -;Non-alpha_string12 = Hello<world -;Non-alpha_string13 = Hello>world -;Non-alpha_string14 = Hello>world -;Non-alpha_string15 = Hello?world -;Non-alpha_string16 = Hello\world -;Non-alpha_string17 = Hello^world -;Non-alpha_string18 = Hello_world -;Non-alpha_string19 = Hello|world -;Non-alpha_string20 = Hello~world -;Non-alpha_string21 = Hello`world -;Non-alpha_string22 = Hello(world) +Non_alpha_string1 = Hello@world +;Non_alpha_string2 = Hello!world +;Non_alpha_string3 = Hello#world +;Non_alpha_string4 = Hello%world +;Non_alpha_string5 = Hello&world +;Non_alpha_string6 = Hello*world +;Non_alpha_string7 = Hello+world +;Non_alpha_string8 = Hello-world +;Non_alpha_string9 = Hello'world +;Non_alpha_string10 = Hello:world +;Non_alpha_string11 = Hello;world +;Non_alpha_string12 = Hello<world +;Non_alpha_string13 = Hello>world +;Non_alpha_string14 = Hello>world +;Non_alpha_string15 = Hello?world +;Non_alpha_string16 = Hello\world +;Non_alpha_string17 = Hello^world +;Non_alpha_string18 = Hello_world +;Non_alpha_string19 = Hello|world +;Non_alpha_string20 = Hello~world +;Non_alpha_string21 = Hello`world +;Non_alpha_string22 = Hello(world) [Non-alpha numerics in strings -with quotes] -Non-alpha_string1_quotes = "Hello@world" -Non-alpha_string2_quotes = "Hello!world" -Non-alpha_string3_quotes = "Hello#world" -Non-alpha_string4_quotes = "Hello&world" -Non-alpha_string5_quotes = "Hello*world" -Non-alpha_string6_quotes = "Hello+world" -Non-alpha_string7_quotes = "Hello-world" -Non-alpha_string8_quotes = "Hello'world" -Non-alpha_string9_quotes = "Hello:world" -Non-alpha_string10_quotes = "Hello;world" -Non-alpha_string11_quotes = "Hello<world" -Non-alpha_string12_quotes = "Hello>world" -Non-alpha_string13_quotes = "Hello>world" -Non-alpha_string14_quotes = "Hello?world" -Non-alpha_string15_quotes = "Hello\world" -Non-alpha_string16_quotes = "Hello^world" -Non-alpha_string17_quotes = "Hello_world" -Non-alpha_string18_quotes = "Hello|world" -Non-alpha_string19_quotes = "Hello~world" -Non-alpha_string20_quotes = "Hello`world" -Non-alpha_string21_quotes = "Hello(world)" +Non_alpha_string1_quotes = "Hello@world" +Non_alpha_string2_quotes = "Hello!world" +Non_alpha_string3_quotes = "Hello#world" +Non_alpha_string4_quotes = "Hello&world" +Non_alpha_string5_quotes = "Hello*world" +Non_alpha_string6_quotes = "Hello+world" +Non_alpha_string7_quotes = "Hello-world" +Non_alpha_string8_quotes = "Hello'world" +Non_alpha_string9_quotes = "Hello:world" +Non_alpha_string10_quotes = "Hello;world" +Non_alpha_string11_quotes = "Hello<world" +Non_alpha_string12_quotes = "Hello>world" +Non_alpha_string13_quotes = "Hello>world" +Non_alpha_string14_quotes = "Hello?world" +Non_alpha_string15_quotes = "Hello\world" +Non_alpha_string16_quotes = "Hello^world" +Non_alpha_string17_quotes = "Hello_world" +Non_alpha_string18_quotes = "Hello|world" +Non_alpha_string19_quotes = "Hello~world" +Non_alpha_string20_quotes = "Hello`world" +Non_alpha_string21_quotes = "Hello(world)" [Newlines_in_Values] String1 = "Hello, world\nGood Morning" @@ -150,7 +150,7 @@ String3 = 'Hello, world\tGood Morning' String4 = "\n" String5 = "\n\n" -String3 = Hello, world\tGood Morning +String6 = Hello, world\tGood Morning [ReservedKeys_as_Values] Key1 = YES @@ -242,74 +242,73 @@ [Octal_value] => 0100 [Hex_value1] => 0x101 [Hex_Value2] => 0x103 - [Non-alpha1] => - [Non-alpha2] => + - [Non-alpha3] => * - [Non-alpha4] => % - [Non-alpha5] => <> - [Non-alpha6] => @ - [Non-alpha7] => # - [Non-alpha8] => ^ - [non-alpha9] => - - [Non-alpha10] => : - [Non-alpha11] => ? - [Non-alpha12] => / - [Non-alpha13] => \ - [Non-alpha1_quotes] => ; - [Non-alpha2_quotes] => + - [Non-alpha3_quotes] => * - [Non-alpha4_quotes] => % - [Non-alpha5_quotes] => <> - [Non-alpha6_quotes] => @ - [Non-alpha7_quotes] => # - [Non-alpha8_quotes] => ^ - [Non-alpha9_quotes] => - - [Non-alpha10_quotes] => = - [Non-alpha11_quotes] => : - [Non-alpha12_quotes] => ? - [Non-alpha13_quotes] => / - [Non-alpha14_quotes] => \ - [Non-alpha15_quotes] => & - [Non-alpha16_quotes] => {} - [Non-alpha17_quotes] => | - [Non-alpha18_quotes] => ~ - [Non-alpha19_quotes] => ! - [non-alpha20_quotes] => $ - [non-alpha21_quotes] => () - [Non-alpha_string1] => Hello@world - [Non-alpha_string1_quotes] => Hello@world - [Non-alpha_string2_quotes] => Hello!world - [Non-alpha_string3_quotes] => Hello#world - [Non-alpha_string4_quotes] => Hello&world - [Non-alpha_string5_quotes] => Hello*world - [Non-alpha_string6_quotes] => Hello+world - [Non-alpha_string7_quotes] => Hello-world - [Non-alpha_string8_quotes] => Hello'world - [Non-alpha_string9_quotes] => Hello:world - [Non-alpha_string10_quotes] => Hello;world - [Non-alpha_string11_quotes] => Hello<world - [Non-alpha_string12_quotes] => Hello>world - [Non-alpha_string13_quotes] => Hello>world - [Non-alpha_string14_quotes] => Hello?world - [Non-alpha_string15_quotes] => Hello\world - [Non-alpha_string16_quotes] => Hello^world - [Non-alpha_string17_quotes] => Hello_world - [Non-alpha_string18_quotes] => Hello|world - [Non-alpha_string19_quotes] => Hello~world - [Non-alpha_string20_quotes] => Hello`world - [Non-alpha_string21_quotes] => Hello(world) + [Non_alpha1] => + [Non_alpha2] => + + [Non_alpha3] => * + [Non_alpha4] => % + [Non_alpha5] => <> + [Non_alpha6] => @ + [Non_alpha7] => # + [Non_alpha8] => ^ + [Non_alpha9] => - + [Non_alpha10] => : + [Non_alpha11] => ? + [Non_alpha12] => / + [Non_alpha13] => \ + [Non_alpha1_quotes] => ; + [Non_alpha2_quotes] => + + [Non_alpha3_quotes] => * + [Non_alpha4_quotes] => % + [Non_alpha5_quotes] => <> + [Non_alpha6_quotes] => @ + [Non_alpha7_quotes] => # + [Non_alpha8_quotes] => ^ + [Non_alpha9_quotes] => - + [Non_alpha10_quotes] => = + [Non_alpha11_quotes] => : + [Non_alpha12_quotes] => ? + [Non_alpha13_quotes] => / + [Non_alpha15_quotes] => & + [Non_alpha16_quotes] => {} + [Non_alpha17_quotes] => | + [Non_alpha18_quotes] => ~ + [Non_alpha19_quotes] => ! + [Non_alpha21_quotes] => () + [Non_alpha_string1] => Hello@world + [Non_alpha_string1_quotes] => Hello@world + [Non_alpha_string2_quotes] => Hello!world + [Non_alpha_string3_quotes] => Hello#world + [Non_alpha_string4_quotes] => Hello&world + [Non_alpha_string5_quotes] => Hello*world + [Non_alpha_string6_quotes] => Hello+world + [Non_alpha_string7_quotes] => Hello-world + [Non_alpha_string8_quotes] => Hello'world + [Non_alpha_string9_quotes] => Hello:world + [Non_alpha_string10_quotes] => Hello;world + [Non_alpha_string11_quotes] => Hello<world + [Non_alpha_string12_quotes] => Hello>world + [Non_alpha_string13_quotes] => Hello>world + [Non_alpha_string14_quotes] => Hello?world + [Non_alpha_string15_quotes] => Hello\world + [Non_alpha_string16_quotes] => Hello^world + [Non_alpha_string17_quotes] => Hello_world + [Non_alpha_string18_quotes] => Hello|world + [Non_alpha_string19_quotes] => Hello~world + [Non_alpha_string20_quotes] => Hello`world + [Non_alpha_string21_quotes] => Hello(world) [String1] => Hello, world Good Morning [String2] => Hello, world Good Morning - [String3] => Hello, worldGood Morning + [String3] => Hello, world Good Morning [String4] => [String5] => + [String6] => Hello, world Good Morning [Key1] => 1 [Key2] => 1 [Key3] => 1 @@ -379,70 +378,68 @@ [Non-alphanumerics_as_values] => Array ( - [Non-alpha1] => - [Non-alpha2] => + - [Non-alpha3] => * - [Non-alpha4] => % - [Non-alpha5] => <> - [Non-alpha6] => @ - [Non-alpha7] => # - [Non-alpha8] => ^ - [non-alpha9] => - - [Non-alpha10] => : - [Non-alpha11] => ? - [Non-alpha12] => / - [Non-alpha13] => \ - [Non-alpha1_quotes] => ; - [Non-alpha2_quotes] => + - [Non-alpha3_quotes] => * - [Non-alpha4_quotes] => % - [Non-alpha5_quotes] => <> - [Non-alpha6_quotes] => @ - [Non-alpha7_quotes] => # - [Non-alpha8_quotes] => ^ - [Non-alpha9_quotes] => - - [Non-alpha10_quotes] => = - [Non-alpha11_quotes] => : - [Non-alpha12_quotes] => ? - [Non-alpha13_quotes] => / - [Non-alpha14_quotes] => \ - [Non-alpha15_quotes] => & - [Non-alpha16_quotes] => {} - [Non-alpha17_quotes] => | - [Non-alpha18_quotes] => ~ - [Non-alpha19_quotes] => ! - [non-alpha20_quotes] => $ - [non-alpha21_quotes] => () + [Non_alpha1] => + [Non_alpha2] => + + [Non_alpha3] => * + [Non_alpha4] => % + [Non_alpha5] => <> + [Non_alpha6] => @ + [Non_alpha7] => # + [Non_alpha8] => ^ + [Non_alpha9] => - + [Non_alpha10] => : + [Non_alpha11] => ? + [Non_alpha12] => / + [Non_alpha13] => \ + [Non_alpha1_quotes] => ; + [Non_alpha2_quotes] => + + [Non_alpha3_quotes] => * + [Non_alpha4_quotes] => % + [Non_alpha5_quotes] => <> + [Non_alpha6_quotes] => @ + [Non_alpha7_quotes] => # + [Non_alpha8_quotes] => ^ + [Non_alpha9_quotes] => - + [Non_alpha10_quotes] => = + [Non_alpha11_quotes] => : + [Non_alpha12_quotes] => ? + [Non_alpha13_quotes] => / + [Non_alpha15_quotes] => & + [Non_alpha16_quotes] => {} + [Non_alpha17_quotes] => | + [Non_alpha18_quotes] => ~ + [Non_alpha19_quotes] => ! + [Non_alpha21_quotes] => () ) [Non-alpha numerics in strings] => Array ( - [Non-alpha_string1] => Hello@world + [Non_alpha_string1] => Hello@world ) [Non-alpha numerics in strings -with quotes] => Array ( - [Non-alpha_string1_quotes] => Hello@world - [Non-alpha_string2_quotes] => Hello!world - [Non-alpha_string3_quotes] => Hello#world - [Non-alpha_string4_quotes] => Hello&world - [Non-alpha_string5_quotes] => Hello*world - [Non-alpha_string6_quotes] => Hello+world - [Non-alpha_string7_quotes] => Hello-world - [Non-alpha_string8_quotes] => Hello'world - [Non-alpha_string9_quotes] => Hello:world - [Non-alpha_string10_quotes] => Hello;world - [Non-alpha_string11_quotes] => Hello<world - [Non-alpha_string12_quotes] => Hello>world - [Non-alpha_string13_quotes] => Hello>world - [Non-alpha_string14_quotes] => Hello?world - [Non-alpha_string15_quotes] => Hello\world - [Non-alpha_string16_quotes] => Hello^world - [Non-alpha_string17_quotes] => Hello_world - [Non-alpha_string18_quotes] => Hello|world - [Non-alpha_string19_quotes] => Hello~world - [Non-alpha_string20_quotes] => Hello`world - [Non-alpha_string21_quotes] => Hello(world) + [Non_alpha_string1_quotes] => Hello@world + [Non_alpha_string2_quotes] => Hello!world + [Non_alpha_string3_quotes] => Hello#world + [Non_alpha_string4_quotes] => Hello&world + [Non_alpha_string5_quotes] => Hello*world + [Non_alpha_string6_quotes] => Hello+world + [Non_alpha_string7_quotes] => Hello-world + [Non_alpha_string8_quotes] => Hello'world + [Non_alpha_string9_quotes] => Hello:world + [Non_alpha_string10_quotes] => Hello;world + [Non_alpha_string11_quotes] => Hello<world + [Non_alpha_string12_quotes] => Hello>world + [Non_alpha_string13_quotes] => Hello>world + [Non_alpha_string14_quotes] => Hello?world + [Non_alpha_string15_quotes] => Hello\world + [Non_alpha_string16_quotes] => Hello^world + [Non_alpha_string17_quotes] => Hello_world + [Non_alpha_string18_quotes] => Hello|world + [Non_alpha_string19_quotes] => Hello~world + [Non_alpha_string20_quotes] => Hello`world + [Non_alpha_string21_quotes] => Hello(world) ) [Newlines_in_Values] => Array @@ -453,12 +450,13 @@ Hello, world Good Morning - [String3] => Hello, worldGood Morning + [String3] => Hello, world Good Morning [String4] => [String5] => + [String6] => Hello, world Good Morning ) [ReservedKeys_as_Values] => Array @@ -488,4 +486,4 @@ ) ) -*** Done ** \ No newline at end of file +*** Done ** http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_file.phpt?r1=1.1.2.2&r2=1.1.2.2.2.1&diff_format=u Index: php-src/ext/standard/tests/general_functions/parse_ini_file.phpt diff -u php-src/ext/standard/tests/general_functions/parse_ini_file.phpt:1.1.2.2 php-src/ext/standard/tests/general_functions/parse_ini_file.phpt:1.1.2.2.2.1 --- php-src/ext/standard/tests/general_functions/parse_ini_file.phpt:1.1.2.2 Thu Nov 16 13:01:23 2006 +++ php-src/ext/standard/tests/general_functions/parse_ini_file.phpt Fri Sep 28 02:05:09 2007 @@ -1,12 +1,13 @@ --TEST-- -parse_ini_file() tests +parse_ini_file() multiple calls --FILE-- <?php $filename = dirname(__FILE__)."/parse_ini_file.dat"; +@unlink($filename); /* Make sure the file really does not exist! */ var_dump(parse_ini_file()); -var_dump(parse_ini_file(1,1,1)); +var_dump(parse_ini_file(1,1,1,1)); var_dump(parse_ini_file($filename)); var_dump(parse_ini_file($filename, true)); @@ -15,7 +16,6 @@ "; file_put_contents($filename, $ini); var_dump(parse_ini_file($filename)); - $ini = " test== "; @@ -81,7 +81,6 @@ "; file_put_contents($filename, $ini); var_dump(parse_ini_file($filename, true)); - $ini = " test=test2 test=test3 @@ -90,22 +89,21 @@ file_put_contents($filename, $ini); var_dump(parse_ini_file($filename, true)); - @unlink($filename); echo "Done\n"; ?> --EXPECTF-- -Warning: Wrong parameter count for parse_ini_file() in %s on line %d -NULL +Warning: parse_ini_file() expects at least 1 parameter, 0 given in %sparse_ini_file.php on line 6 +bool(false) -Warning: Wrong parameter count for parse_ini_file() in %s on line %d -NULL +Warning: parse_ini_file() expects at most 3 parameters, 4 given in %sparse_ini_file.php on line 7 +bool(false) -Warning: parse_ini_file(%sparse_ini_file.dat): failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(%sparse_ini_file.dat): failed to open stream: No such file or directory in %sparse_ini_file.php on line 8 array(0) { } -Warning: parse_ini_file(%sparse_ini_file.dat): failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(%sparse_ini_file.dat): failed to open stream: No such file or directory in %sparse_ini_file.php on line 9 array(0) { } array(1) { @@ -113,15 +111,15 @@ string(0) "" } -Warning: Error parsing %sparse_ini_file.dat on line 2 - in %s on line %d +Warning: syntax error, unexpected '=' in %sparse_ini_file.dat on line 2 + in %sparse_ini_file.php on line 20 array(1) { ["test"]=> string(0) "" } -Warning: Error parsing %sparse_ini_file.dat on line 2 - in %s on line %d +Warning: syntax error, unexpected '=' in %sparse_ini_file.dat on line 2 + in %sparse_ini_file.php on line 26 array(1) { ["test"]=> string(4) "test" http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.640.2.23.2.57&r2=1.640.2.23.2.57.2.1&diff_format=u Index: php-src/main/main.c diff -u php-src/main/main.c:1.640.2.23.2.57 php-src/main/main.c:1.640.2.23.2.57.2.1 --- php-src/main/main.c:1.640.2.23.2.57 Mon Sep 24 11:53:40 2007 +++ php-src/main/main.c Fri Sep 28 02:05:09 2007 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.640.2.23.2.57 2007/09/24 11:53:40 dmitry Exp $ */ +/* $Id: main.c,v 1.640.2.23.2.57.2.1 2007/09/28 02:05:09 jani Exp $ */ /* {{{ includes */ @@ -447,12 +447,15 @@ PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) - STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, always_populate_raw_post_data, php_core_globals, core_globals) STD_PHP_INI_ENTRY("realpath_cache_size", "16K", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_size_limit, virtual_cwd_globals, cwd_globals) STD_PHP_INI_ENTRY("realpath_cache_ttl", "120", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_ttl, virtual_cwd_globals, cwd_globals) + + STD_PHP_INI_ENTRY("user_ini.filename", ".user.ini", PHP_INI_SYSTEM, OnUpdateString, user_ini_filename, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("user_ini.cache_ttl", "300", PHP_INI_SYSTEM, OnUpdateLong, user_ini_cache_ttl, php_core_globals, core_globals) PHP_INI_END() /* }}} */ @@ -1025,7 +1028,7 @@ } convert_to_string_ex(new_timeout); - if (zend_alter_ini_entry("max_execution_time", sizeof("max_execution_time"), Z_STRVAL_PP(new_timeout), Z_STRLEN_PP(new_timeout), PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == SUCCESS) { + if (zend_alter_ini_entry_ex("max_execution_time", sizeof("max_execution_time"), Z_STRVAL_PP(new_timeout), Z_STRLEN_PP(new_timeout), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC) == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; http://cvs.php.net/viewvc.cgi/php-src/main/php_globals.h?r1=1.98.2.1.2.7&r2=1.98.2.1.2.7.2.1&diff_format=u Index: php-src/main/php_globals.h diff -u php-src/main/php_globals.h:1.98.2.1.2.7 php-src/main/php_globals.h:1.98.2.1.2.7.2.1 --- php-src/main/php_globals.h:1.98.2.1.2.7 Tue Jul 24 14:21:36 2007 +++ php-src/main/php_globals.h Fri Sep 28 02:05:09 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_globals.h,v 1.98.2.1.2.7 2007/07/24 14:21:36 jani Exp $ */ +/* $Id: php_globals.h,v 1.98.2.1.2.7.2.1 2007/09/28 02:05:09 jani Exp $ */ #ifndef PHP_GLOBALS_H #define PHP_GLOBALS_H @@ -161,6 +161,9 @@ #endif long max_input_nesting_level; zend_bool in_user_include; + + char *user_ini_filename; + long user_ini_cache_ttl; }; http://cvs.php.net/viewvc.cgi/php-src/main/php_ini.c?r1=1.136.2.4.2.15&r2=1.136.2.4.2.15.2.1&diff_format=u Index: php-src/main/php_ini.c diff -u php-src/main/php_ini.c:1.136.2.4.2.15 php-src/main/php_ini.c:1.136.2.4.2.15.2.1 --- php-src/main/php_ini.c:1.136.2.4.2.15 Fri Aug 31 08:16:13 2007 +++ php-src/main/php_ini.c Fri Sep 28 02:05:09 2007 @@ -16,11 +16,12 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ini.c,v 1.136.2.4.2.15 2007/08/31 08:16:13 jani Exp $ */ +/* $Id: php_ini.c,v 1.136.2.4.2.15.2.1 2007/09/28 02:05:09 jani Exp $ */ #include "php.h" #include "ext/standard/info.h" #include "zend_ini.h" +#include "zend_ini_scanner.h" #include "php_ini.h" #include "ext/standard/dl.h" #include "zend_extensions.h" @@ -45,8 +46,8 @@ zend_llist functions; } php_extension_lists; - /* True globals */ +static HashTable *active_ini_hash; static HashTable configuration_hash; PHPAPI char *php_ini_opened_path=NULL; static php_extension_lists extension_lists; @@ -54,14 +55,13 @@ /* {{{ php_ini_displayer_cb */ -static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type) +static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type TSRMLS_DC) { if (ini_entry->displayer) { ini_entry->displayer(ini_entry, type); } else { char *display_string; uint display_string_length, esc_html=0; - TSRMLS_FETCH(); if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) { if (ini_entry->orig_value && ini_entry->orig_value[0]) { @@ -112,16 +112,16 @@ PUTS("<td class=\"e\">"); PHPWRITE(ini_entry->name, ini_entry->name_length - 1); PUTS("</td><td class=\"v\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE TSRMLS_CC); PUTS("</td><td class=\"v\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG TSRMLS_CC); PUTS("</td></tr>\n"); } else { PHPWRITE(ini_entry->name, ini_entry->name_length - 1); PUTS(" => "); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE TSRMLS_CC); PUTS(" => "); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG TSRMLS_CC); PUTS("\n"); } return 0; @@ -148,7 +148,6 @@ /* }}} */ /* php.ini support */ - #ifdef ZTS # if (ZEND_DEBUG) # define ZEND_EXTENSION_TOKEN "zend_extension_debug_ts" @@ -163,17 +162,46 @@ # endif #endif -/* {{{ php_config_ini_parser_cb +/* {{{ config_zval_dtor */ -static void php_config_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg) +void config_zval_dtor(zval *zvalue) { + if (Z_TYPE_P(zvalue) == IS_ARRAY) { + zend_hash_destroy(Z_ARRVAL_P(zvalue)); + free(Z_ARRVAL_P(zvalue)); + } else if (Z_TYPE_P(zvalue) == IS_STRING) { + free(Z_STRVAL_P(zvalue)); + } +} +/* Reset / free active_ini_sectin global */ +#define RESET_ACTIVE_INI_HASH() do { \ + active_ini_hash = NULL; \ +} while (0) +/* }}} */ + +/* {{{ php_ini_parser_cb + */ +static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, HashTable *target_hash) +{ + zval *entry; + HashTable *active_hash; + + if (active_ini_hash) { + active_hash = active_ini_hash; + } else { + active_hash = target_hash; + } + switch (callback_type) { case ZEND_INI_PARSER_ENTRY: { - zval *entry; - if (!arg2) { + /* bare string - nothing to do */ break; } + +/* FIXME: Should the extension loading be disabled for PATH sections? */ + + /* PHP and Zend extensions are not added into configuration hash! */ if (!strcasecmp(Z_STRVAL_P(arg1), "extension")) { /* load function module */ zval copy; @@ -185,41 +213,101 @@ char *extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); zend_llist_add_element(&extension_lists.engine, &extension_name); + + /* All other entries are added into either configuration_hash or active ini section array */ } else { - zend_hash_update(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, arg2, sizeof(zval), (void **) &entry); + /* Store in active hash */ + zend_hash_update(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, arg2, sizeof(zval), (void **) &entry); Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); } } break; case ZEND_INI_PARSER_POP_ENTRY: { - zval *hash; - zval **find_hash; - zval *element; + zval *option_arr; + zval *find_arr; if (!arg2) { /* bare string - nothing to do */ break; } - if (zend_hash_find(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, (void **) &find_hash) == FAILURE) { - ALLOC_ZVAL(hash); - array_init(hash); +/* fprintf(stdout, "ZEND_INI_PARSER_POP_ENTRY: %s[%s] = %s\n",Z_STRVAL_P(arg1), Z_STRVAL_P(arg3), Z_STRVAL_P(arg2)); */ - zend_hash_update(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, &hash, sizeof(zval *), NULL); + /* If option not found in hash or is not an array -> create array, otherwise add to existing array */ + if (zend_hash_find(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, (void **) &find_arr) == FAILURE || Z_TYPE_P(find_arr) != IS_ARRAY) { + option_arr = (zval *) pemalloc(sizeof(zval), 1); + INIT_PZVAL(option_arr); + Z_TYPE_P(option_arr) = IS_ARRAY; + Z_ARRVAL_P(option_arr) = (HashTable *) pemalloc(sizeof(HashTable), 1); + zend_hash_init(Z_ARRVAL_P(option_arr), 0, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_update(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, option_arr, sizeof(zval), (void **) &find_arr); + free(option_arr); + } + + /* arg3 is possible option offset name */ + if (arg3 && Z_STRLEN_P(arg3) > 0) { + zend_symtable_update(Z_ARRVAL_P(find_arr), Z_STRVAL_P(arg3), Z_STRLEN_P(arg3) + 1, arg2, sizeof(zval), (void **) &entry); } else { - hash = *find_hash; + zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2, sizeof(zval), (void **) &entry); } - - ALLOC_ZVAL(element); - *element = *arg2; - zval_copy_ctor(element); - INIT_PZVAL(element); - add_next_index_zval(hash, element); + Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); } break; - case ZEND_INI_PARSER_SECTION: + case ZEND_INI_PARSER_SECTION: { /* Create an array of entries of each section */ + +/* fprintf(stdout, "ZEND_INI_PARSER_SECTION: %s\n",Z_STRVAL_P(arg1)); */ + + char *key = NULL; + uint key_len; + + /* Only PATH sections are handled here! */ + if (!strncasecmp(Z_STRVAL_P(arg1), "PATH", sizeof("PATH") - 1)) { + key = Z_STRVAL_P(arg1); + key = key + sizeof("PATH") - 1; + key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1; + +#if 0 /* Disable HOST sections for now. If someone can come up with some good usage case, then I can reconsider :) */ + } else if (!strncasecmp(Z_STRVAL_P(arg1), "HOST", sizeof("HOST") - 1)) { + key = Z_STRVAL_P(arg1); + key = key + sizeof("HOST") - 1; + key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1; +#endif + } + + if (key && key_len > 0) { + /* Strip any trailing slashes */ + while (key_len > 0 && (key[key_len - 1] == '/' || key[key_len - 1] == '\\')) { + key_len--; + key[key_len] = 0; + } + + /* Strip any leading whitespace and '=' */ + while (*key && ( + *key == '=' || + *key == ' ' || + *key == '\t' + )) { + key++; + key_len--; + } + + /* Search for existing entry and if it does not exist create one */ + if (zend_hash_find(target_hash, key, key_len + 1, (void **) &entry) == FAILURE) { + zval *section_arr; + + section_arr = (zval *) pemalloc(sizeof(zval), 1); + INIT_PZVAL(section_arr); + Z_TYPE_P(section_arr) = IS_ARRAY; + Z_ARRVAL_P(section_arr) = (HashTable *) pemalloc(sizeof(HashTable), 1); + zend_hash_init(Z_ARRVAL_P(section_arr), 0, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_update(target_hash, key, key_len + 1, section_arr, sizeof(zval), (void **) &entry); + free(section_arr); + } + active_ini_hash = Z_ARRVAL_P(entry); + } + } break; } } @@ -244,16 +332,6 @@ } /* }}} */ -/* {{{ pvalue_config_destructor - */ -static void pvalue_config_destructor(zval *pvalue) -{ - if (Z_TYPE_P(pvalue) == IS_STRING) { - free(Z_STRVAL_P(pvalue)); - } -} -/* }}} */ - /* {{{ php_init_config */ int php_init_config(TSRMLS_D) @@ -264,14 +342,8 @@ char *open_basedir; int free_ini_search_path = 0; zend_file_handle fh; - struct stat sb; - char ini_file[MAXPATHLEN]; - char *p; - zend_llist scanned_ini_list; - int l, total_l=0; - zend_llist_element *element; - if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) pvalue_config_destructor, 1) == FAILURE) { + if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) config_zval_dtor, 1) == FAILURE) { return FAILURE; } @@ -281,7 +353,6 @@ zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1); zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) ZVAL_DESTRUCTOR, 1); - zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1); safe_mode_state = PG(safe_mode); open_basedir = PG(open_basedir); @@ -492,8 +563,9 @@ if (fh.handle.fp) { fh.type = ZEND_HANDLE_FP; + RESET_ACTIVE_INI_HASH(); - zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); + zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC); { zval tmp; @@ -501,6 +573,8 @@ Z_STRLEN(tmp) = strlen(fh.filename); Z_STRVAL(tmp) = zend_strndup(fh.filename, Z_STRLEN(tmp)); Z_TYPE(tmp) = IS_STRING; + tmp.refcount = 0; + zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL); if (php_ini_opened_path) { efree(php_ini_opened_path); @@ -514,10 +588,24 @@ if (!sapi_module.php_ini_ignore && strlen(PHP_CONFIG_FILE_SCAN_DIR)) { struct dirent **namelist; int ndir, i; + struct stat sb; + char ini_file[MAXPATHLEN]; + char *p; + zend_file_handle fh; + zend_llist scanned_ini_list; + zend_llist_element *element; + int l, total_l = 0; + + /* Reset active ini section */ + RESET_ACTIVE_INI_HASH(); if ((ndir = php_scandir(PHP_CONFIG_FILE_SCAN_DIR, &namelist, 0, php_alphasort)) > 0) { + zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1); + memset(&fh, 0, sizeof(fh)); + for (i = 0; i < ndir; i++) { - /* check for a .ini extension */ + + /* check for any file with .ini extension */ if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) { free(namelist[i]); continue; @@ -528,12 +616,14 @@ if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) { fh.filename = ini_file; fh.type = ZEND_HANDLE_FP; - zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); - /* Here, add it to the list of ini files read */ - l = strlen(ini_file); - total_l += l + 2; - p = estrndup(ini_file, l); - zend_llist_add_element(&scanned_ini_list, &p); + + if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC) == SUCCESS) { + /* Here, add it to the list of ini files read */ + l = strlen(ini_file); + total_l += l + 2; + p = estrndup(ini_file, l); + zend_llist_add_element(&scanned_ini_list, &p); + } } } } @@ -541,14 +631,17 @@ } free(namelist); - /* - * Don't need an extra byte for the \0 in this malloc as the last - * element will not get a trailing , which gives us the byte for the \0 - */ if (total_l) { - php_ini_scanned_files = (char *) malloc(total_l); - *php_ini_scanned_files = '\0'; + int php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0; + php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); + if (!php_ini_scanned_files_len) { + *php_ini_scanned_files = '\0'; + } + total_l += php_ini_scanned_files_len; for (element = scanned_ini_list.head; element; element = element->next) { + if (php_ini_scanned_files_len) { + strlcat(php_ini_scanned_files, ",\n", total_l); + } strlcat(php_ini_scanned_files, *(char **)element->data, total_l); strlcat(php_ini_scanned_files, element->next ? ",\n" : "\n", total_l); } @@ -558,7 +651,9 @@ } if (sapi_module.ini_entries) { - zend_parse_ini_string(sapi_module.ini_entries, 1, php_config_ini_parser_cb, &extension_lists); + /* Reset active ini section */ + RESET_ACTIVE_INI_HASH(); + zend_parse_ini_string(sapi_module.ini_entries, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC); } return SUCCESS; @@ -594,6 +689,81 @@ } /* }}} */ +/* {{{ php_parse_user_ini_file + */ +PHPAPI int php_parse_user_ini_file(char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC) +{ + struct stat sb; + char ini_file[MAXPATHLEN]; + zend_file_handle fh; + + snprintf(ini_file, MAXPATHLEN, "%s%c%s", dirname, DEFAULT_SLASH, ini_filename); + + if (VCWD_STAT(ini_file, &sb) == 0) { + if (S_ISREG(sb.st_mode)) { + memset(&fh, 0, sizeof(fh)); + if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) { + fh.filename = ini_file; + fh.type = ZEND_HANDLE_FP; + + /* Reset active ini section */ + RESET_ACTIVE_INI_HASH(); + + if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash TSRMLS_CC) == SUCCESS) { + /* FIXME: Add parsed file to the list of user files read? */ + return SUCCESS; + } + return FAILURE; + } + } + } + return FAILURE; +} +/* }}} */ + +/* {{{ php_ini_activate_config + */ +PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC) +{ + char *str; + zval *data; + uint str_len; + ulong num_index; + + /* Walk through config hash and alter matching ini entries using the values found in the hash */ + for (zend_hash_internal_pointer_reset(source_hash); + zend_hash_get_current_key_ex(source_hash, &str, &str_len, &num_index, 0, NULL) == HASH_KEY_IS_STRING; + zend_hash_move_forward(source_hash) + ) { + zend_hash_get_current_data(source_hash, (void **) &data); + zend_alter_ini_entry_ex(str, str_len, Z_STRVAL_P(data), Z_STRLEN_P(data), modify_type, stage, 0 TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ php_ini_activate_per_dir_config + */ +PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC) +{ + zval *tmp; + char *ptr; + + /* Walk through each directory in path and apply any found per-dir-system-configuration from configuration_hash */ + if (path && path_len) { + ptr = path + 1; + while ((ptr = strchr(ptr, DEFAULT_SLASH)) != NULL) { + *ptr = 0; + /* Search for source array matching the path from configuration_hash */ + if (zend_hash_find(&configuration_hash, path, path_len, (void **) &tmp) == SUCCESS) { + php_ini_activate_config(Z_ARRVAL_P(tmp), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC); + } + *ptr = '/'; + ptr++; + } + } +} +/* }}} */ + /* {{{ cfg_get_entry */ PHPAPI zval *cfg_get_entry(char *name, uint name_length) @@ -659,6 +829,14 @@ } /* }}} */ +#if ZEND_DEBUG +#include "php_ini.h" +PHPAPI HashTable get_configuration_hash(void) +{ + return configuration_hash; +} +#endif + /* * Local variables: * tab-width: 4 http://cvs.php.net/viewvc.cgi/php-src/main/php_ini.h?r1=1.45.2.3.2.3&r2=1.45.2.3.2.3.2.1&diff_format=u Index: php-src/main/php_ini.h diff -u php-src/main/php_ini.h:1.45.2.3.2.3 php-src/main/php_ini.h:1.45.2.3.2.3.2.1 --- php-src/main/php_ini.h:1.45.2.3.2.3 Fri Aug 31 07:48:05 2007 +++ php-src/main/php_ini.h Fri Sep 28 02:05:09 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ini.h,v 1.45.2.3.2.3 2007/08/31 07:48:05 jani Exp $ */ +/* $Id: php_ini.h,v 1.45.2.3.2.3.2.1 2007/09/28 02:05:09 jani Exp $ */ #ifndef PHP_INI_H #define PHP_INI_H @@ -24,6 +24,7 @@ #include "zend_ini.h" BEGIN_EXTERN_C() +void config_zval_dtor(zval *zvalue); int php_init_config(TSRMLS_D); int php_shutdown_config(void); void php_ini_register_extensions(TSRMLS_D); @@ -31,6 +32,12 @@ PHPAPI int cfg_get_long(char *varname, long *result); PHPAPI int cfg_get_double(char *varname, double *result); PHPAPI int cfg_get_string(char *varname, char **result); +PHPAPI int php_parse_user_ini_file(char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC); +PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC); +PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC); +#if ZEND_DEBUG +PHPAPI HashTable get_configuration_hash(void); +#endif END_EXTERN_C() #define PHP_INI_USER ZEND_INI_USER http://cvs.php.net/viewvc.cgi/php-src/sapi/cgi/cgi_main.c?r1=1.267.2.15.2.50.2.2&r2=1.267.2.15.2.50.2.3&diff_format=u Index: php-src/sapi/cgi/cgi_main.c diff -u php-src/sapi/cgi/cgi_main.c:1.267.2.15.2.50.2.2 php-src/sapi/cgi/cgi_main.c:1.267.2.15.2.50.2.3 --- php-src/sapi/cgi/cgi_main.c:1.267.2.15.2.50.2.2 Thu Sep 27 22:09:46 2007 +++ php-src/sapi/cgi/cgi_main.c Fri Sep 28 02:05:10 2007 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cgi_main.c,v 1.267.2.15.2.50.2.2 2007/09/27 22:09:46 jani Exp $ */ +/* $Id: cgi_main.c,v 1.267.2.15.2.50.2.3 2007/09/28 02:05:10 jani Exp $ */ #include "php.h" #include "php_globals.h" @@ -152,8 +152,30 @@ #ifdef PHP_WIN32 zend_bool impersonate; #endif + HashTable user_config_cache; } php_cgi_globals_struct; +/* {{{ user_config_cache + * + * Key for each cache entry is dirname(PATH_TRANSLATED). + * + * NOTE: Each cache entry config_hash contains the combination from all user ini files found in + * the path starting from doc_root throught to dirname(PATH_TRANSLATED). There is no point + * storing per-file entries as it would not be possible to detect added / deleted entries + * between separate files. + */ +typedef struct _user_config_cache_entry { + time_t expires; + HashTable *user_config; +} user_config_cache_entry; + +static void user_config_cache_entry_dtor(user_config_cache_entry *entry) /* {{{ */ +{ + zend_hash_destroy(entry->user_config); + free(entry->user_config); +} +/* }}} */ + #ifdef ZTS static int php_cgi_globals_id; #define CGIG(v) TSRMG(php_cgi_globals_id, php_cgi_globals_struct *, v) @@ -566,12 +588,96 @@ } } +/* {{{ php_cgi_ini_activate_user_config + */ +static void php_cgi_ini_activate_user_config(char *path, int path_len, int start TSRMLS_DC) +{ + char *ptr; + user_config_cache_entry *new_entry, *entry; + time_t request_time = sapi_get_request_time(TSRMLS_C); + + /* Find cached config entry: If not found, create one */ + if (zend_hash_find(&CGIG(user_config_cache), path, path_len + 1, (void **) &entry) == FAILURE) { + new_entry = pemalloc(sizeof(user_config_cache_entry), 1); + new_entry->expires = 0; + new_entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1); + zend_hash_init(new_entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_update(&CGIG(user_config_cache), path, path_len + 1, new_entry, sizeof(user_config_cache_entry), (void **) &entry); + free(new_entry); + } + + /* Check whether cache entry has expired and rescan if it is */ + if (request_time > entry->expires) { + + /* Clear the expired config */ + zend_hash_clean(entry->user_config); + + /* Walk through each directory and apply entries to user_config hash */ + ptr = path + start; /* start is the point where doc_root ends! */ + while ((ptr = strchr(ptr, DEFAULT_SLASH)) != NULL) { + *ptr = 0; + php_parse_user_ini_file(path, PG(user_ini_filename), entry->user_config TSRMLS_CC); + *ptr = '/'; + ptr++; + } + entry->expires = request_time + PG(user_ini_cache_ttl); + } + + /* Activate ini entries with values from the user config hash */ + php_ini_activate_config(entry->user_config, PHP_INI_PERDIR, PHP_INI_STAGE_HTACCESS TSRMLS_CC); +} +/* }}} */ + +static int sapi_cgi_activate(TSRMLS_D) +{ + char *path, *doc_root; + uint path_len, doc_root_len; + + /* PATH_TRANSLATED should be defined at this stage but better safe than sorry :) */ + if (!SG(request_info).path_translated) { + return FAILURE; + } + + doc_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT") - 1 TSRMLS_CC); + + /* DOCUMENT_ROOT should also be defined at this stage..but better check it anyway */ + if (!doc_root) { + return FAILURE; + } + doc_root_len = strlen(doc_root); + if (doc_root[doc_root_len - 1] == '/') { + --doc_root_len; + } + + /* Prepare search path */ + path_len = strlen(SG(request_info).path_translated); + path = zend_strndup(SG(request_info).path_translated, path_len); + php_dirname(path, path_len); + path_len = strlen(path); + + /* Make sure we have trailing slash! */ + if (!IS_SLASH(path[path_len])) { + path[path_len++] = DEFAULT_SLASH; + } + path[path_len] = 0; + + /* Activate per-dir-system-configuration defined in php.ini and stored into configuration_hash during startup */ + php_ini_activate_per_dir_config(path, path_len TSRMLS_CC); /* Note: for global settings sake we check from root to path */ + + /* Load and activate user ini files in path starting from DOCUMENT_ROOT */ + if (strlen(PG(user_ini_filename))) { + php_cgi_ini_activate_user_config(path, path_len, doc_root_len - 1 TSRMLS_CC); + } + + free(path); + return SUCCESS; +} + static int sapi_cgi_deactivate(TSRMLS_D) { /* flush only when SAPI was started. The reasons are: 1. SAPI Deactivate is called from two places: module init and request shutdown - 2. When the first call occurs and the request is not set up, flush fails on - FastCGI. + 2. When the first call occurs and the request is not set up, flush fails on FastCGI. */ if (SG(sapi_started)) { sapi_cgibin_flush(SG(server_context)); @@ -587,7 +693,6 @@ return SUCCESS; } - /* {{{ sapi_module_struct cgi_sapi_module */ static sapi_module_struct cgi_sapi_module = { @@ -597,7 +702,7 @@ php_cgi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ - NULL, /* activate */ + sapi_cgi_activate, /* activate */ sapi_cgi_deactivate, /* deactivate */ sapi_cgibin_ub_write, /* unbuffered write */ @@ -1072,6 +1177,7 @@ #ifdef PHP_WIN32 php_cgi_globals->impersonate = 0; #endif + zend_hash_init(&php_cgi_globals->user_config_cache, 0, NULL, (dtor_func_t) user_config_cache_entry_dtor, 1); } /* }}} */ @@ -1093,6 +1199,8 @@ */ static PHP_MSHUTDOWN_FUNCTION(cgi) { + zend_hash_destroy(&CGIG(user_config_cache)); + UNREGISTER_INI_ENTRIES(); return SUCCESS; } http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_basic.data?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_basic.data +++ php-src/ext/standard/tests/general_functions/parse_ini_basic.data [basic] basicval = bar longval = 12345 with.dot = fooobar boolon = on booltrue = true boolyes = yes booloff = off boolfalse = false boolnone = none boolno = no string = asdadfsdjkslkj ¡@£$$ { }[ ]/%#¤ sqstring = 'adsasdadasdasd' dqstring = "asdadfsdjkslkj ¡@£$$ { } !^~|¥¥{[()/)&/% ¤ # #" php_constant = E_ALL [basic with whitespace] basicval = bar longval = 12345 with.dot = fooobar boolon = on booltrue = true boolyes = yes booloff = off boolfalse = false boolnone = none boolno = no sqstring = 'adsasdadasdasd' dqstring = "asdadfsdjkslkj ¡@£$$€¥¥{[()/)&/%#¤" php_constant = E_ALL [comments] ; some comment ; some comment with whitespace somecomment = comment follows;aaa@bbb ; comment here ; [variables] var1 = ${basicval} var2 = ${basicval}/foo var3 = foo/${basicval} var4 = foo/${basicval}/foo quoted_var1 = "${basicqval}" quoted_var2 = "${basicqval}/foo" quoted_var3 = "foo/${basicqval}" quoted_var4 = "foo/${basicqval}/foo" [offset values] foo1[] = "basic offset 1" foo1[ ] = "basic offset 2" foo2[123] = "long offset" foo3[abc] = "string offset" foo4[""] = "quoted offset 1" foo4[" "] = "quoted offset 2" foo4["sqfoobar"] = "quoted string offset" foo4['dqfoobar'] = "single quoted offset" foo6[${basicval}] = "variable" foo6[${basicval}/foo] = "variable with string 1" foo6[foo/${basicval}] = "variable with string 2" foo6[foo/${basicval}/foo] = "variable with string 3" foo7["${basicqval}"] = "quoted variable 1" foo7["${basicqval}/foo"] = "quoted variable 2" foo7["foo/${basicqval}"] = "quoted variable 3" foo7[ "foo/${basicqval}/foo" ] = "quoted variable 4" [non value] novalue_option1 = novalue_option2= novalue_option3 = novalue_option4= novalue_option4[] = novalue_option4[]= novalue_option4[]= ["Quoted strings and variables in sections"] [${basicval}] [${basicval}/foo] [foo/${basicval}] [foo/${basicval}/foo] ["${basicqval}"] ["${basicqval}/foo"] ["foo/${basicqval}"] ["foo/${basicqval}/foo"] [PATH=${basicval}/no/quotes] ; Invalid! ;[PATH="${basicval}/path/quoted"] ["PATH=${basicval}/all/quoted"] ; The rest is from bug #29306 [01] e=e f=f [02] g=g h=h [1] a=a b=b [2] c=c d=d [0815] bla=bla http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_basic.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_basic.phpt +++ php-src/ext/standard/tests/general_functions/parse_ini_basic.phpt --TEST-- parse_ini_file() tests --ENV-- basicval=FUBAR_VARIABLE basicqval=FUBAR_QUOTES_VARIABLE --FILE-- <?php $ini_file = dirname(__FILE__)."/parse_ini_basic.data"; var_dump(parse_ini_file($ini_file, 1)); echo "Done.\n"; ?> --EXPECTF-- array(22) { ["basic"]=> array(14) { ["basicval"]=> string(3) "bar" ["longval"]=> string(5) "12345" ["with.dot"]=> string(7) "fooobar" ["boolon"]=> string(1) "1" ["booltrue"]=> string(1) "1" ["boolyes"]=> string(1) "1" ["booloff"]=> string(0) "" ["boolfalse"]=> string(0) "" ["boolnone"]=> string(0) "" ["boolno"]=> string(0) "" ["string"]=> string(34) "asdadfsdjkslkj ¡@£$$ { }[ ]/%#¤" ["sqstring"]=> string(14) "adsasdadasdasd" ["dqstring"]=> string(51) "asdadfsdjkslkj ¡@£$$ { } !^~|¥¥{[()/)&/% ¤ # #" ["php_constant"]=> string(4) "8191" } ["basic with whitespace"]=> array(13) { ["basicval"]=> string(3) "bar" ["longval"]=> string(5) "12345" ["with.dot"]=> string(7) "fooobar" ["boolon"]=> string(1) "1" ["booltrue"]=> string(1) "1" ["boolyes"]=> string(1) "1" ["booloff"]=> string(0) "" ["boolfalse"]=> string(0) "" ["boolnone"]=> string(0) "" ["boolno"]=> string(0) "" ["sqstring"]=> string(14) "adsasdadasdasd" ["dqstring"]=> string(41) "asdadfsdjkslkj ¡@£$$€¥¥{[()/)&/%#¤" ["php_constant"]=> string(4) "8191" } ["comments"]=> array(1) { ["somecomment"]=> string(15) "comment follows" } ["variables"]=> array(8) { ["var1"]=> string(14) "FUBAR_VARIABLE" ["var2"]=> string(18) "FUBAR_VARIABLE/foo" ["var3"]=> string(18) "foo/FUBAR_VARIABLE" ["var4"]=> string(22) "foo/FUBAR_VARIABLE/foo" ["quoted_var1"]=> string(21) "FUBAR_QUOTES_VARIABLE" ["quoted_var2"]=> string(25) "FUBAR_QUOTES_VARIABLE/foo" ["quoted_var3"]=> string(25) "foo/FUBAR_QUOTES_VARIABLE" ["quoted_var4"]=> string(29) "foo/FUBAR_QUOTES_VARIABLE/foo" } ["offset values"]=> array(6) { ["foo1"]=> array(2) { [0]=> string(14) "basic offset 1" [1]=> string(14) "basic offset 2" } ["foo2"]=> array(1) { [123]=> string(11) "long offset" } ["foo3"]=> array(1) { ["abc"]=> string(13) "string offset" } ["foo4"]=> array(4) { [0]=> string(15) "quoted offset 1" [" "]=> string(15) "quoted offset 2" ["sqfoobar"]=> string(20) "quoted string offset" ["dqfoobar"]=> string(20) "single quoted offset" } ["foo6"]=> array(4) { ["FUBAR_VARIABLE"]=> string(8) "variable" ["FUBAR_VARIABLE/foo"]=> string(22) "variable with string 1" ["foo/FUBAR_VARIABLE"]=> string(22) "variable with string 2" ["foo/FUBAR_VARIABLE/foo"]=> string(22) "variable with string 3" } ["foo7"]=> array(4) { ["FUBAR_QUOTES_VARIABLE"]=> string(17) "quoted variable 1" ["FUBAR_QUOTES_VARIABLE/foo"]=> string(17) "quoted variable 2" ["foo/FUBAR_QUOTES_VARIABLE"]=> string(17) "quoted variable 3" ["foo/FUBAR_QUOTES_VARIABLE/foo"]=> string(17) "quoted variable 4" } } ["non value"]=> array(4) { ["novalue_option1"]=> string(0) "" ["novalue_option2"]=> string(0) "" ["novalue_option3"]=> string(0) "" ["novalue_option4"]=> array(3) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(0) "" } } ["Quoted strings and variables in sections"]=> array(0) { } ["FUBAR_VARIABLE"]=> array(0) { } ["FUBAR_VARIABLE/foo"]=> array(0) { } ["foo/FUBAR_VARIABLE"]=> array(0) { } ["foo/FUBAR_VARIABLE/foo"]=> array(0) { } ["FUBAR_QUOTES_VARIABLE"]=> array(0) { } ["FUBAR_QUOTES_VARIABLE/foo"]=> array(0) { } ["foo/FUBAR_QUOTES_VARIABLE"]=> array(0) { } ["foo/FUBAR_QUOTES_VARIABLE/foo"]=> array(0) { } ["PATH=FUBAR_VARIABLE/no/quotes"]=> array(0) { } ["PATH=FUBAR_VARIABLE/all/quoted"]=> array(0) { } ["01"]=> array(2) { ["e"]=> string(1) "e" ["f"]=> string(1) "f" } ["02"]=> array(2) { ["g"]=> string(1) "g" ["h"]=> string(1) "h" } [1]=> array(2) { ["a"]=> string(1) "a" ["b"]=> string(1) "b" } [2]=> array(2) { ["c"]=> string(1) "c" ["d"]=> string(1) "d" } ["0815"]=> array(1) { ["bla"]=> string(3) "bla" } } Done. http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_booleans.data?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_booleans.data +++ php-src/ext/standard/tests/general_functions/parse_ini_booleans.data [error_reporting values] foo = E_ALL E_NOTICE error_reporting = E_ALL error_reporting1 = E_COMPILE_ERROR|E_RECOVERABLE_ERROR |E_ERROR|E_CORE_ERROR error_reporting2 = E_ALL&~E_NOTICE error_reporting3 = E_ALL & ~E_NOTICE error_reporting4 = E_ALL & ~E_NOTICE | E_STRICT [true or false] bool_true = true bool_yes = yes bool_on = on bool_false=false bool_off =Off bool_no=No bool_none= NoNe bool_null = NULl [strings] string_true = "true" string_yes = " yes" string_on = " on " string_false="false" string_off ="Off " string_no="No " string_none=" NoNe" string_null = "NULl" http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_booleans.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_booleans.phpt +++ php-src/ext/standard/tests/general_functions/parse_ini_booleans.phpt --TEST-- parse_ini_file() boolean operators --FILE-- <?php $ini_file = dirname(__FILE__)."/parse_ini_booleans.data"; var_dump(parse_ini_file($ini_file, 1)); echo "Done.\n"; ?> --EXPECTF-- array(3) { ["error_reporting values"]=> array(6) { ["foo"]=> string(14) "E_ALL E_NOTICE" ["error_reporting"]=> string(4) "8191" ["error_reporting1"]=> string(4) "4177" ["error_reporting2"]=> string(4) "8183" ["error_reporting3"]=> string(4) "8183" ["error_reporting4"]=> string(4) "8183" } ["true or false"]=> array(8) { ["bool_true"]=> string(1) "1" ["bool_yes"]=> string(1) "1" ["bool_on"]=> string(1) "1" ["bool_false"]=> string(0) "" ["bool_off"]=> string(0) "" ["bool_no"]=> string(0) "" ["bool_none"]=> string(0) "" ["bool_null"]=> string(0) "" } ["strings"]=> array(8) { ["string_true"]=> string(4) "true" ["string_yes"]=> string(4) " yes" ["string_on"]=> string(5) " on " ["string_false"]=> string(5) "false" ["string_off"]=> string(4) "Off " ["string_no"]=> string(4) "No " ["string_none"]=> string(5) " NoNe" ["string_null"]=> string(4) "NULl" } } Done.
« previous php.cvs (#46324) next »