Skip to content

Commit 6734880

Browse files
committed
Fix bug #79945: Stream wrappers in imagecreatefrompng causes segfault
Closes phpGH-12696
1 parent c442a1f commit 6734880

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

NEWS

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,20 @@ PHP NEWS
1111
- PHPDBG:
1212
. Fixed bug GH-12675 (MEMORY_LEAK in phpdbg_prompt.c). (nielsdos)
1313

14+
- SQLite3:
15+
. Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0).
16+
(SakiTakamachi)
17+
1418
- Standard:
1519
. Fix memory leak in syslog device handling. (danog)
1620
. Fixed bug GH-12621 (browscap segmentation fault when configured in the
1721
vhost). (nielsdos)
1822
. Fixed bug GH-12655 (proc_open() does not take into account references
1923
in the descriptor array). (nielsdos)
2024

21-
- SQLite3:
22-
. Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0).
23-
(SakiTakamachi)
25+
- Streams:
26+
. Fixed bug #79945 (Stream wrappers in imagecreatefrompng causes segfault).
27+
(Jakub Zelenka)
2428

2529
- Zip:
2630
. Fixed bug GH-12661 (Inconsistency in ZipArchive::addGlob remove_path Option

ext/gd/tests/bug79945.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #79945 (using php wrappers in imagecreatefrompng causes segmentation fault)
3+
--EXTENSIONS--
4+
gd
5+
--SKIPIF--
6+
<?php
7+
set_error_handler(function($errno, $errstr) {
8+
if (str_contains($errstr, 'Cannot cast a filtered stream on this system')) {
9+
die('skip: fopencookie not support on this system');
10+
}
11+
});
12+
imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png');
13+
restore_error_handler();
14+
?>
15+
--FILE--
16+
<?php
17+
imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png');
18+
?>
19+
--CLEAN--
20+
--EXPECTF--
21+
22+
Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d

main/php_streams.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ struct _php_stream {
211211
* PHP_STREAM_FCLOSE_XXX as appropriate */
212212
uint8_t fclose_stdiocast:2;
213213

214+
/* whether stdio cast flushing is in progress */
215+
int8_t fclose_stdiocast_flush_in_progress:1;
216+
214217
char mode[16]; /* "rwb" etc. ala stdio */
215218

216219
uint32_t flags; /* PHP_STREAM_FLAG_XXX */

main/streams/streams.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,8 +1294,13 @@ PHPAPI zend_off_t _php_stream_tell(php_stream *stream)
12941294
PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence)
12951295
{
12961296
if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) {
1297-
/* flush to commit data written to the fopencookie FILE* */
1298-
fflush(stream->stdiocast);
1297+
/* flush can call seek internally so we need to prevent an infinite loop */
1298+
if (!stream->fclose_stdiocast_flush_in_progress) {
1299+
stream->fclose_stdiocast_flush_in_progress = 1;
1300+
/* flush to commit data written to the fopencookie FILE* */
1301+
fflush(stream->stdiocast);
1302+
stream->fclose_stdiocast_flush_in_progress = 0;
1303+
}
12991304
}
13001305

13011306
/* handle the case where we are in the buffer */

0 commit comments

Comments
 (0)