Skip to content

Conversation

@alexandre-daubois
Copy link
Member

@alexandre-daubois alexandre-daubois commented Aug 1, 2025

Fix #18120

Allows to use FILE_SKIP_EMPTY_LINES without FILE_IGNORE_NEW_LINES:

$test_file = __DIR__ . "/file_skip_empty_lines.tmp";

$test_data = "First\n\nSecond\n\n\nThird\n";
file_put_contents($test_file, $test_data);

$lines = file($test_file, FILE_SKIP_EMPTY_LINES);
var_dump($lines);

/**
array(3) {
  [0]=>
  string(6) "First
"
  [1]=>
  string(7) "Second
"
  [2]=>
  string(6) "Third
"
}
*/

@alexandre-daubois
Copy link
Member Author

Friendly ping @DanielEScherzer @nielsdos as you participated on the issue 🙂

@ndossche
Copy link
Member

I'll play with this tomorrow or so. Note that this is fixing long standing behaviour, so targeting 8.5/master is likely more appropriate.

@DanielEScherzer
Copy link
Member

^ what @nielsdos said about not targeting 8.3, but wearing my release manager hat I don't think 8.5 is appropriate

@ndossche
Copy link
Member

<?php
$test_file = __DIR__ . "/file_skip_empty_lines.tmp";

$test_data = "\r";
file_put_contents($test_file, $test_data);
$lines = file($test_file, FILE_SKIP_EMPTY_LINES);
var_dump($lines);

$test_data = "\r\r";
file_put_contents($test_file, $test_data);
$lines = file($test_file, FILE_SKIP_EMPTY_LINES);
var_dump($lines);

produces:

array(1) {
  [0]=>
" string(1) "
}
array(0) {
}

which seems incorrect to me. Can you explain whether this is the desired behaviour?

@alexandre-daubois alexandre-daubois changed the base branch from PHP-8.3 to master December 2, 2025 14:07
@alexandre-daubois alexandre-daubois force-pushed the empty-lines-fix branch 2 times, most recently from d8ff4fd to daf2b51 Compare December 2, 2025 14:13
@alexandre-daubois
Copy link
Member Author

@ndossche I addressed your concern and updated the test file as well. Also, I rebased on master as suggested.

size_t eol_len = 1;

if (eol_marker == '\n') {
if (p >= ZSTR_VAL(target_buf) + 2 && *(p - 2) == '\r' && *(p - 1) == '\n') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think target_buf has any guarantees about its length, so ZSTR_VAL(target_buf) + 2 may point out of bounds. However, doing pointer arithmetic that results in a pointer more than 1 byte out of bounds is undefined behaviour.
Use ZSTR_VAL(target_buf) - p >= 2 instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the correct condition is p - ZSTR_VAL(target_buf) >= 2. PR updated 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FILE_SKIP_EMPTY_LINES only works with FILE_IGNORE_NEW_LINES

3 participants