From: Jani Taskinen Date: Mon, 4 Feb 2008 20:45:16 +0000 (+0000) Subject: - Fixed bugs #43915, #43923 and #44019, a tiny performance issue fixed too X-Git-Tag: RELEASE_2_0_0a1~611 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71e3d357ef89f4f70765636f90c1533fa35459d9;p=php - Fixed bugs #43915, #43923 and #44019, a tiny performance issue fixed too --- diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index ca2d810119..633d1480aa 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -246,13 +246,16 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s %} -%expect 1 +%expect 0 %pure_parser %token TC_SECTION %token TC_RAW +%token TC_CONSTANT %token TC_NUMBER %token TC_STRING +%token TC_WHITESPACE +%token TC_LABEL %token TC_OFFSET %token TC_DOLLAR_CURLY %token TC_VARNAME @@ -260,7 +263,7 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s %token BOOL_TRUE %token BOOL_FALSE %token END_OF_LINE -%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' +%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}' %left '|' '&' %right '~' '!' @@ -279,7 +282,7 @@ statement: 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 { + | TC_LABEL '=' string_or_value { #if DEBUG_CFG_PARSER printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3)); #endif @@ -296,32 +299,24 @@ statement: free(Z_STRVAL($2)); free(Z_STRVAL($5)); } - | TC_STRING { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); } + | TC_LABEL { 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; } + var_string_list { $$ = $1; } | /* empty */ { zend_ini_init_string(&$$); } ; string_or_value: 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; } + var_string_list { $$ = $1; } | /* empty */ { zend_ini_init_string(&$$); } ; @@ -331,18 +326,13 @@ encapsed_list: | /* empty */ { zend_ini_init_string(&$$); } ; -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; } + | '"' encapsed_list '"' { $$ = $2; } | 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)); } + | var_string_list '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); } ; expr: @@ -359,7 +349,11 @@ cfg_var_ref: ; constant_string: - TC_STRING { zend_ini_get_constant(&$$, &$1 TSRMLS_CC); } + TC_CONSTANT { zend_ini_get_constant(&$$, &$1 TSRMLS_CC); } + | TC_RAW { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ } + | TC_NUMBER { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ } + | TC_STRING { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ } + | TC_WHITESPACE { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ } ; /* diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index f3b2593ae3..e809ce3731 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -263,7 +263,6 @@ static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_ty } else { *t++ = *s; } - if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { SCNG(lineno)++; } @@ -277,25 +276,26 @@ static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_ty LNUM [0-9]+ DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*) -NUMBER {LNUM}|{DNUM} -ANY_CHAR (.|[\n]) +NUMBER [-]?{LNUM}|{DNUM} +ANY_CHAR (.|[\n\t]) NEWLINE ("\r"|"\n"|"\r\n") TABS_AND_SPACES [ \t] +WHITESPACE [ \t]+ CONSTANT [a-zA-Z][a-zA-Z0-9_]* -LABEL [a-zA-Z0-9][a-zA-Z0-9._]* -TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@] +LABEL [a-zA-Z0-9][a-zA-Z0-9._-]* +TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}] OPERATORS [&|~()!] +DOLLAR_CURLY "${" -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] +SINGLE_QUOTED_CHARS [^'] +RAW_VALUE_CHARS [^=\n\r;] -/* Allow using ${foobar} inside quoted strings */ -DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) +/* Allow using ${foobar} in sections, quoted strings and values */ +LITERAL_DOLLAR ("$"([^a-zA-Z0-9{]|("\\"{ANY_CHAR}))) +VALUE_CHARS ([^$= \t\n\r;&|~()!"']|{LITERAL_DOLLAR}) +SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR}) +DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR}) /* " */ @@ -348,7 +348,7 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) return ']'; } -"${" { /* Variable start */ +{DOLLAR_CURLY} { /* Variable start */ yy_push_state(ST_VARNAME TSRMLS_CC); return TC_DOLLAR_CURLY; } @@ -370,8 +370,8 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) RETURN_TOKEN(BOOL_FALSE, "", 0); } -{LABEL} { /* Get option name or option offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); +{LABEL} { /* Get option name */ + RETURN_TOKEN(TC_LABEL, yytext, yyleng); } {TABS_AND_SPACES}*[=]{TABS_AND_SPACES}* { /* Start option value */ @@ -397,17 +397,17 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) RETURN_TOKEN(TC_RAW, yytext, yyleng); } -{NEWLINE} { /* End of option value */ +{TABS_AND_SPACES}*{NEWLINE} { /* End of option value */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -{CONSTANT} { /* Get constant option value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); +{CONSTANT} { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); } -{NUMBER} { /* Get number option value as string */ +{NUMBER} { /* Get number option value as string */ RETURN_TOKEN(TC_NUMBER, yytext, yyleng); } @@ -426,8 +426,6 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) } {VALUE_CHARS}+ { /* Get everything else as option/offset value */ - /* Eat trailing tabs and spaces */ - EAT_TRAILING_WHITESPACE(); RETURN_TOKEN(TC_STRING, yytext, yyleng); } @@ -435,7 +433,7 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) RETURN_TOKEN(TC_STRING, yytext, yyleng); } -["] { /* Double quoted '"' string start */ +{TABS_AND_SPACES}*["] { /* Double quoted '"' string start */ yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); return '"'; } @@ -445,21 +443,25 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{LITERAL_DOLLAR}) return TC_QUOTED_STRING; } -["] { /* Double quoted '"' string ends */ +["]{TABS_AND_SPACES}* { /* Double quoted '"' string ends */ yy_pop_state(TSRMLS_C); return '"'; } -{TABS_AND_SPACES} { +{WHITESPACE} { + RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); +} + +{TABS_AND_SPACES}+ { /* eat whitespace */ } -{NEWLINE} { +{TABS_AND_SPACES}*{NEWLINE} { SCNG(lineno)++; return END_OF_LINE; } -[;][^\r\n]*{NEWLINE} { /* Comment */ +{TABS_AND_SPACES}*[;][^\r\n]*{NEWLINE} { /* Comment */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; diff --git a/ext/standard/tests/general_functions/parse_ini_basic.data b/ext/standard/tests/general_functions/parse_ini_basic.data index cba8f9d70f..05b515ee60 100644 --- a/ext/standard/tests/general_functions/parse_ini_basic.data +++ b/ext/standard/tests/general_functions/parse_ini_basic.data @@ -13,6 +13,7 @@ string = asdadfsdjkslkj ¡@£$$ { }[ ]/%#¤ sqstring = 'adsasdadasdasd' dqstring = "asdadfsdjkslkj ¡@£$$ { } !^~|¥¥{[()/)&/% ¤ # #" php_constant = E_ALL +user_constant = TEST_CONSTANT [basic with whitespace] basicval = bar @@ -89,7 +90,7 @@ novalue_option4[]= ;[PATH="${basicval}/path/quoted"] ["PATH=${basicval}/all/quoted"] -; The rest is from bug #29306 +; This is test for bug #29306 [01] e=e f=f @@ -104,3 +105,25 @@ c=c d=d [0815] bla=bla + +;Test for bug #43923 +[bug #43923] +curly1 = { +curly2 = "{" +curly3 = '{' + +;Test for bug #44019 +[bug #44019] +concatenation_before = TEST_CONSTANT "+some_text_after" +concatenation_middle = "some_text_before+" TEST_CONSTANT "+some_text_after" +concatenation_after = "some_text_before+" TEST_CONSTANT +concatenation_nows_before = TEST_CONSTANT"+some_text_after" +concatenation_nows_middle = "some_text_before+"TEST_CONSTANT"+some_text_after" +concatenation_nows_after = "some_text_before+"TEST_CONSTANT + +;Test for bug #43915 +[bug #43915] +ini_with-hyphen = with hyphen and underscore +ini.with-hyphen = dot and hyphen +ini-with.hyphen = hyphen and dot + diff --git a/ext/standard/tests/general_functions/parse_ini_basic.phpt b/ext/standard/tests/general_functions/parse_ini_basic.phpt index fa7481ba68..acdb8755c6 100644 --- a/ext/standard/tests/general_functions/parse_ini_basic.phpt +++ b/ext/standard/tests/general_functions/parse_ini_basic.phpt @@ -8,14 +8,16 @@ basicqval=FUBAR_QUOTES_VARIABLE $ini_file = dirname(__FILE__)."/parse_ini_basic.data"; +define('TEST_CONSTANT', 'this_is_test_constant'); + var_dump(parse_ini_file($ini_file, 1)); echo "Done.\n"; ?> --EXPECTF-- -array(22) { +array(25) { ["basic"]=> - array(14) { + array(15) { ["basicval"]=> string(3) "bar" ["longval"]=> @@ -44,6 +46,8 @@ array(22) { string(51) "asdadfsdjkslkj ¡@£$$ { } !^~|¥¥{[()/)&/% ¤ # #" ["php_constant"]=> string(4) "8191" + ["user_constant"]=> + string(21) "this_is_test_constant" } ["basic with whitespace"]=> array(13) { @@ -235,5 +239,38 @@ array(22) { ["bla"]=> string(3) "bla" } + ["bug #43923"]=> + array(3) { + ["curly1"]=> + string(1) "{" + ["curly2"]=> + string(1) "{" + ["curly3"]=> + string(1) "{" + } + ["bug #44019"]=> + array(6) { + ["concatenation_before"]=> + string(37) "this_is_test_constant+some_text_after" + ["concatenation_middle"]=> + string(54) "some_text_before+this_is_test_constant+some_text_after" + ["concatenation_after"]=> + string(38) "some_text_before+this_is_test_constant" + ["concatenation_nows_before"]=> + string(37) "this_is_test_constant+some_text_after" + ["concatenation_nows_middle"]=> + string(54) "some_text_before+this_is_test_constant+some_text_after" + ["concatenation_nows_after"]=> + string(38) "some_text_before+this_is_test_constant" + } + ["bug #43915"]=> + array(3) { + ["ini_with-hyphen"]=> + string(26) "with hyphen and underscore" + ["ini.with-hyphen"]=> + string(14) "dot and hyphen" + ["ini-with.hyphen"]=> + string(14) "hyphen and dot" + } } Done. diff --git a/ext/standard/tests/general_functions/parse_ini_booleans.data b/ext/standard/tests/general_functions/parse_ini_booleans.data index 2f1c2af214..d408577ea4 100644 --- a/ext/standard/tests/general_functions/parse_ini_booleans.data +++ b/ext/standard/tests/general_functions/parse_ini_booleans.data @@ -6,7 +6,7 @@ error_reporting2 = E_ALL&~E_NOTICE error_reporting3 = E_ALL & ~E_NOTICE error_reporting4 = E_ALL & ~E_NOTICE | E_STRICT -[true or false] +['true or false'] bool_true = true bool_yes = yes bool_on = on diff --git a/ext/standard/tests/general_functions/parse_ini_booleans.phpt b/ext/standard/tests/general_functions/parse_ini_booleans.phpt index ca757457d3..a1be31ddf4 100644 --- a/ext/standard/tests/general_functions/parse_ini_booleans.phpt +++ b/ext/standard/tests/general_functions/parse_ini_booleans.phpt @@ -15,7 +15,7 @@ array(3) { ["error_reporting values"]=> array(6) { ["foo"]=> - string(14) "E_ALL E_NOTICE" + string(6) "8191 8" ["error_reporting"]=> string(4) "8191" ["error_reporting1"]=>