mirror of
https://github.com/php/php-src.git
synced 2026-03-24 16:22:37 +01:00
Fix #80933: SplFileObject::DROP_NEW_LINE is broken for NUL and CR
`buf` may contain NUL bytes, so we must not use `strcspn()` but rather a binary safe variant. However, we also must not detect a stray CR as line ending, and since we only need to check line endings at the end of the buffer, we can nicely optimize. Co-authored-by: Nikita Popov <nikita.ppv@gmail.com> Closes GH-6836.
This commit is contained in:
4
NEWS
4
NEWS
@@ -2,7 +2,9 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 7.4.19
|
||||
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #80933 (SplFileObject::DROP_NEW_LINE is broken for NUL and CR).
|
||||
(cmb, Nikita)
|
||||
|
||||
29 Apr 2021, PHP 7.4.18
|
||||
|
||||
|
||||
@@ -2046,8 +2046,13 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) /
|
||||
intern->u.file.current_line_len = 0;
|
||||
} else {
|
||||
if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) {
|
||||
line_len = strcspn(buf, "\r\n");
|
||||
buf[line_len] = '\0';
|
||||
if (line_len > 0 && buf[line_len - 1] == '\n') {
|
||||
line_len--;
|
||||
if (line_len > 0 && buf[line_len - 1] == '\r') {
|
||||
line_len--;
|
||||
}
|
||||
buf[line_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
intern->u.file.current_line = buf;
|
||||
|
||||
27
ext/spl/tests/bug80933.phpt
Normal file
27
ext/spl/tests/bug80933.phpt
Normal file
@@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Bug #80933 (SplFileObject::DROP_NEW_LINE is broken for NUL and CR)
|
||||
--FILE--
|
||||
<?php
|
||||
$lines = [
|
||||
"Lorem ipsum \0 dolor sit amet", // string with NUL
|
||||
"Lorem ipsum \r dolor sit amet", // string with CR
|
||||
];
|
||||
foreach ($lines as $line) {
|
||||
$temp = new SplTempFileObject();
|
||||
$temp->fwrite($line);
|
||||
|
||||
$temp->rewind();
|
||||
$read = $temp->fgets();
|
||||
var_dump($line === $read);
|
||||
|
||||
$temp->rewind();
|
||||
$temp->setFlags(SplFileObject::DROP_NEW_LINE);
|
||||
$read = $temp->fgets();
|
||||
var_dump($line === $read);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
Reference in New Issue
Block a user