From 64f3fb7f703c18d38664f9d08e15d0398339d85c Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sat, 28 Aug 2021 16:30:36 +0300 Subject: [PATCH 1/2] Proposal to a few fixes/improvements in the ini parser --- Zend/zend_ini_scanner.l | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index 73853f6ec1171..474580ba3af96 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -591,31 +591,35 @@ end_raw_value_chars: return 0; } - while (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR++) { + unsigned char *s = SCNG(yy_text); + + while (s < YYLIMIT) { + switch (*s++) { case '"': - if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { - continue; - } break; case '$': - if (*YYCURSOR == '{') { + if (s < YYLIMIT && *s == '{') { break; } continue; case '\\': - if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { - YYCURSOR++; + if (s < YYLIMIT) { + unsigned char escaped = *s++; + /* A special case for Windows paths, e.g. key="C:\path\" */ + if (escaped == '"' && (s >= YYLIMIT || *s == '\n' || *s == '\r')) { + break; + } } ZEND_FALLTHROUGH; default: continue; } - YYCURSOR--; + s--; break; } + YYCURSOR = s; yyleng = YYCURSOR - SCNG(yy_text); zend_ini_escape_string(ini_lval, yytext, yyleng, '"'); From 6f641893499e71f84efa7ccaff31688be1f13431 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Mon, 30 Aug 2021 17:05:35 +0300 Subject: [PATCH 2/2] add test of characters escaping in parse_ini_file --- .../general_functions/parse_ini_basic.data | 11 +++++++++++ .../general_functions/parse_ini_basic.phpt | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ext/standard/tests/general_functions/parse_ini_basic.data b/ext/standard/tests/general_functions/parse_ini_basic.data index cafbb157424af..00860b24173f3 100644 --- a/ext/standard/tests/general_functions/parse_ini_basic.data +++ b/ext/standard/tests/general_functions/parse_ini_basic.data @@ -130,3 +130,14 @@ ini-with.hyphen = hyphen and dot [windows paths] winpath1="c:\some windows\path\test\new\r\quote \" here\single ' quote\some more" winpath2="special case\" + +[characters escaping] +; Note: single-quoted strings don't support characters escaping, and the line below +; is single-quoted string, followed by unquoted text, followed by single-quoted '.' +single_quoted = 'She said \'Exactly my point\'.' +double_quoted = "She said \"Exactly my point\"." +double_quoted_2 = "Use \\\" to escape double quote" +double_quoted_multiline = "Lorem \"ipsum\""" + dolor" +dollar_test = "\${test}" +unescaped ="\n\r\t" diff --git a/ext/standard/tests/general_functions/parse_ini_basic.phpt b/ext/standard/tests/general_functions/parse_ini_basic.phpt index 481f24045f708..b2cae43745a8b 100644 --- a/ext/standard/tests/general_functions/parse_ini_basic.phpt +++ b/ext/standard/tests/general_functions/parse_ini_basic.phpt @@ -15,7 +15,7 @@ var_dump(parse_ini_file($ini_file, 1)); echo "Done.\n"; ?> --EXPECT-- -array(26) { +array(27) { ["basic"]=> array(15) { ["basicval"]=> @@ -279,5 +279,21 @@ array(26) { ["winpath2"]=> string(13) "special case\" } + ["characters escaping"]=> + array(6) { + ["single_quoted"]=> + string(28) "She said \Exactly my point\." + ["double_quoted"]=> + string(28) "She said "Exactly my point"." + ["double_quoted_2"]=> + string(29) "Use \" to escape double quote" + ["double_quoted_multiline"]=> + string(20) "Lorem "ipsum" + dolor" + ["dollar_test"]=> + string(7) "${test}" + ["unescaped"]=> + string(6) "\n\r\t" + } } Done.