mirror of
https://github.com/php/php-src.git
synced 2024-11-27 11:53:33 +08:00
Fix GH-9883 SplFileObject::__toString() reads next line
We need to overwrite the __toString magic method for SplFileObject, similarly to how DirectoryIterator overwrites it Moreover, the custom cast handler is useless as we define __toString methods, so use the standard one instead. Closes GH-9912
This commit is contained in:
parent
aee1a2f4c0
commit
6fbf81c674
3
NEWS
3
NEWS
@ -21,6 +21,9 @@ PHP NEWS
|
||||
- Session:
|
||||
. Fixed GH-9932 (session name silently fails with . and [). (David Carlier)
|
||||
|
||||
- SPL:
|
||||
. Fixed GH-9883 (SplFileObject::__toString() reads next line). (Girgias)
|
||||
|
||||
24 Nov 2022, PHP 8.1.13
|
||||
|
||||
- CLI:
|
||||
|
@ -1836,34 +1836,6 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_filesystem_object_cast */
|
||||
static int spl_filesystem_object_cast(zend_object *readobj, zval *writeobj, int type)
|
||||
{
|
||||
spl_filesystem_object *intern = spl_filesystem_from_obj(readobj);
|
||||
|
||||
if (type == IS_STRING) {
|
||||
if (readobj->ce->__tostring) {
|
||||
return zend_std_cast_object_tostring(readobj, writeobj, type);
|
||||
}
|
||||
|
||||
switch (intern->type) {
|
||||
case SPL_FS_INFO:
|
||||
case SPL_FS_FILE:
|
||||
ZVAL_STR_COPY(writeobj, intern->file_name);
|
||||
return SUCCESS;
|
||||
case SPL_FS_DIR:
|
||||
ZVAL_STRING(writeobj, intern->u.dir.entry.d_name);
|
||||
return SUCCESS;
|
||||
}
|
||||
} else if (type == _IS_BOOL) {
|
||||
ZVAL_TRUE(writeobj);
|
||||
return SUCCESS;
|
||||
}
|
||||
ZVAL_NULL(writeobj);
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bool silent, zend_long line_add) /* {{{ */
|
||||
{
|
||||
char *buf;
|
||||
@ -2744,6 +2716,23 @@ PHP_METHOD(SplFileObject, seek)
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
PHP_METHOD(SplFileObject, __toString)
|
||||
{
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS);
|
||||
|
||||
CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
|
||||
|
||||
if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) {
|
||||
spl_filesystem_file_read_line(ZEND_THIS, intern, 1);
|
||||
}
|
||||
|
||||
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
|
||||
}
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION(spl_directory) */
|
||||
PHP_MINIT_FUNCTION(spl_directory)
|
||||
{
|
||||
@ -2753,7 +2742,6 @@ PHP_MINIT_FUNCTION(spl_directory)
|
||||
memcpy(&spl_filesystem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
|
||||
spl_filesystem_object_handlers.offset = XtOffsetOf(spl_filesystem_object, std);
|
||||
spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
|
||||
spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
|
||||
spl_filesystem_object_handlers.dtor_obj = spl_filesystem_object_destroy_object;
|
||||
spl_filesystem_object_handlers.free_obj = spl_filesystem_object_free_storage;
|
||||
|
||||
|
@ -293,7 +293,6 @@ class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIt
|
||||
*/
|
||||
public function getCurrentLine(): string {}
|
||||
|
||||
/** @implementation-alias SplFileObject::fgets */
|
||||
public function __toString(): string {}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 3f2caf1c46760d8ef629ccb2e94ab0dba09f713b */
|
||||
* Stub hash: c8e8093692f8a4642ea7c840e301f1afed599ee1 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
|
||||
@ -360,6 +360,7 @@ ZEND_METHOD(SplFileObject, getMaxLineLen);
|
||||
ZEND_METHOD(SplFileObject, hasChildren);
|
||||
ZEND_METHOD(SplFileObject, getChildren);
|
||||
ZEND_METHOD(SplFileObject, seek);
|
||||
ZEND_METHOD(SplFileObject, __toString);
|
||||
ZEND_METHOD(SplTempFileObject, __construct);
|
||||
|
||||
|
||||
@ -480,7 +481,7 @@ static const zend_function_entry class_SplFileObject_methods[] = {
|
||||
ZEND_ME(SplFileObject, getChildren, arginfo_class_SplFileObject_getChildren, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(SplFileObject, seek, arginfo_class_SplFileObject_seek, ZEND_ACC_PUBLIC)
|
||||
ZEND_MALIAS(SplFileObject, getCurrentLine, fgets, arginfo_class_SplFileObject_getCurrentLine, ZEND_ACC_PUBLIC)
|
||||
ZEND_MALIAS(SplFileObject, __toString, fgets, arginfo_class_SplFileObject___toString, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(SplFileObject, __toString, arginfo_class_SplFileObject___toString, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
14
ext/spl/tests/gh9883-extra.phpt
Normal file
14
ext/spl/tests/gh9883-extra.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug GH-9883 (SplFileObject::__toString() reads next line)
|
||||
--FILE--
|
||||
<?php
|
||||
$file_stream = new SplTempFileObject();
|
||||
|
||||
echo $file_stream; // line 4
|
||||
echo $file_stream; // line 5
|
||||
echo $file_stream; // line 6
|
||||
echo $file_stream; // line 7
|
||||
echo $file_stream; // line 8
|
||||
echo $file_stream; // line 9
|
||||
?>
|
||||
--EXPECT--
|
20
ext/spl/tests/gh9883.phpt
Normal file
20
ext/spl/tests/gh9883.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug GH-9883 (SplFileObject::__toString() reads next line)
|
||||
--FILE--
|
||||
<?php
|
||||
$file_stream = new SplFileObject(__FILE__, 'rb');
|
||||
|
||||
echo $file_stream; // line 4
|
||||
echo $file_stream; // line 5
|
||||
echo $file_stream; // line 6
|
||||
echo $file_stream; // line 7
|
||||
echo $file_stream; // line 8
|
||||
echo $file_stream; // line 9
|
||||
?>
|
||||
--EXPECT--
|
||||
<?php
|
||||
<?php
|
||||
<?php
|
||||
<?php
|
||||
<?php
|
||||
<?php
|
Loading…
Reference in New Issue
Block a user