diff --git a/NEWS b/NEWS index d8242f50594c4..9d0a7eb86db00 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,8 @@ PHP NEWS - Standard: . Fixed bug GH-19926 (reset internal pointer earlier while splicing array while COW violation flag is still set). (alexandre-daubois) + . Fixed bug GH-18120 (Honor FILE_SKIP_EMPTY_LINES even when + FILE_IGNORE_NEW_LINES is not set). (alexandre-daubois) - Streams: . Added so_reuseaddr streams context socket option that allows disabling diff --git a/ext/standard/file.c b/ext/standard/file.c index fdeabd1872d20..e0f044cd9328b 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -640,6 +640,31 @@ PHP_FUNCTION(file) do { p++; parse_eol: + if (skip_blank_lines) { + size_t eol_len = 1; + + if (eol_marker == '\n') { + if (p - ZSTR_VAL(target_buf) >= 2 && *(p - 2) == '\r' && *(p - 1) == '\n') { + eol_len = 2; + } else if (p == e && p > s) { + const char *check = p - 1; + while (check > s && *check == '\r') { + check--; + } + if (check == s && *check == '\r') { + s = p; + continue; + } + eol_len = 1; + } + } + + size_t line_len = p - s; + if (line_len == eol_len) { + s = p; + continue; + } + } add_index_stringl(return_value, i++, s, p-s); s = p; } while ((p = memchr(p, eol_marker, (e-p)))); diff --git a/ext/standard/tests/file/file_skip_empty_lines.phpt b/ext/standard/tests/file/file_skip_empty_lines.phpt new file mode 100644 index 0000000000000..d19e8431b55e7 --- /dev/null +++ b/ext/standard/tests/file/file_skip_empty_lines.phpt @@ -0,0 +1,124 @@ +--TEST-- +GH-18120 (Honor FILE_SKIP_EMPTY_LINES even when FILE_IGNORE_NEW_LINES is not set) +--FILE-- + +--CLEAN-- + +--EXPECT-- +array(3) { + [0]=> + string(6) "First +" + [1]=> + string(7) "Second +" + [2]=> + string(6) "Third +" +} +array(3) { + [0]=> + string(5) "First" + [1]=> + string(6) "Second" + [2]=> + string(5) "Third" +} +array(6) { + [0]=> + string(5) "First" + [1]=> + string(0) "" + [2]=> + string(6) "Second" + [3]=> + string(0) "" + [4]=> + string(0) "" + [5]=> + string(5) "Third" +} +array(6) { + [0]=> + string(6) "First +" + [1]=> + string(1) " +" + [2]=> + string(7) "Second +" + [3]=> + string(1) " +" + [4]=> + string(1) " +" + [5]=> + string(6) "Third +" +} +array(2) { + [0]=> + string(7) "First +" + [1]=> + string(8) "Second +" +} +array(2) { + [0]=> + string(5) "First" + [1]=> + string(6) "Second" +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} diff --git a/ext/standard/tests/file/file_variation.phpt b/ext/standard/tests/file/file_variation.phpt index 2c46f039c2398..3a69c0bc24eb1 100644 --- a/ext/standard/tests/file/file_variation.phpt +++ b/ext/standard/tests/file/file_variation.phpt @@ -106,20 +106,14 @@ array(5) { [4]=> string(5) " data" } -array(5) { +array(3) { [0]=> string(4) "Gar " [1]=> - string(1) " -" - [2]=> string(6) "bage " - [3]=> - string(1) " -" - [4]=> + [2]=> string(5) " data" } *** Testing with variation in use_include_path argument *** diff --git a/ext/standard/tests/file/file_variation7.phpt b/ext/standard/tests/file/file_variation7.phpt index 72af244a54e17..15d1f319a91d3 100644 --- a/ext/standard/tests/file/file_variation7.phpt +++ b/ext/standard/tests/file/file_variation7.phpt @@ -62,20 +62,17 @@ array(5) { } file() with FILE_SKIP_EMPTY_LINES: -array(5) { +array(4) { [0]=> string(7) "Line 1 " [1]=> - string(1) " -" - [2]=> string(2) " " - [3]=> + [2]=> string(3) " " - [4]=> + [3]=> string(7) "\Line 3" }