diff --git a/NEWS b/NEWS index 1f09639a2f136..dff47b02fb671 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS - PHPDBG: . Fixed bug GH-12675 (MEMORY_LEAK in phpdbg_prompt.c). (nielsdos) +- SQLite3: + . Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0). + (SakiTakamachi) + - Standard: . Fix memory leak in syslog device handling. (danog) . Fixed bug GH-12621 (browscap segmentation fault when configured in the @@ -18,9 +22,9 @@ PHP NEWS . Fixed bug GH-12655 (proc_open() does not take into account references in the descriptor array). (nielsdos) -- SQLite3: - . Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0). - (SakiTakamachi) +- Streams: + . Fixed bug #79945 (Stream wrappers in imagecreatefrompng causes segfault). + (Jakub Zelenka) - Zip: . Fixed bug GH-12661 (Inconsistency in ZipArchive::addGlob remove_path Option diff --git a/ext/gd/tests/bug79945.phpt b/ext/gd/tests/bug79945.phpt new file mode 100644 index 0000000000000..b985ddd48be31 --- /dev/null +++ b/ext/gd/tests/bug79945.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #79945 (using php wrappers in imagecreatefrompng causes segmentation fault) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--CLEAN-- +--EXPECTF-- + +Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d diff --git a/main/php_streams.h b/main/php_streams.h index e7cbc7369ed45..0837472d2f6b9 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -211,6 +211,9 @@ struct _php_stream { * PHP_STREAM_FCLOSE_XXX as appropriate */ uint8_t fclose_stdiocast:2; + /* whether stdio cast flushing is in progress */ + int8_t fclose_stdiocast_flush_in_progress:1; + char mode[16]; /* "rwb" etc. ala stdio */ uint32_t flags; /* PHP_STREAM_FLAG_XXX */ diff --git a/main/streams/streams.c b/main/streams/streams.c index 4cd211ad85fe5..e1399927b2783 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1294,8 +1294,13 @@ PHPAPI zend_off_t _php_stream_tell(php_stream *stream) PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) { if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { - /* flush to commit data written to the fopencookie FILE* */ - fflush(stream->stdiocast); + /* flush can call seek internally so we need to prevent an infinite loop */ + if (!stream->fclose_stdiocast_flush_in_progress) { + stream->fclose_stdiocast_flush_in_progress = 1; + /* flush to commit data written to the fopencookie FILE* */ + fflush(stream->stdiocast); + stream->fclose_stdiocast_flush_in_progress = 0; + } } /* handle the case where we are in the buffer */