From 2e47442a6b1e9a47d449008df2a853e6e99fada3 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 1 Apr 2025 18:58:31 +0100 Subject: [PATCH] Fix GH-18212: fseek with SEEK_CUR and negative offset crash on debug Triggers the assertion as with SEEK_CUR the stream position is set to a negative value so we force the failure without affecting its position instead. close GH-18224 --- NEWS | 2 ++ ext/standard/tests/file/gh18212.phpt | 13 +++++++++++++ ext/standard/tests/file/stream_rfc2397_007.phpt | 2 +- main/streams/streams.c | 4 ++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/file/gh18212.phpt diff --git a/NEWS b/NEWS index 37a320d27be..335903eee23 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ PHP NEWS . Fixed bug GH-18145 (php8ts crashes in php_clear_stat_cache()). (Jakub Zelenka) . Fixed bug GH-18209 (Use-after-free in extract() with EXTR_REFS). (ilutov) + . Fixed bug GH-18212 (fseek with SEEK_CUR whence value and negative offset + leads to negative stream position). (David Carlier) 10 Apr 2025, PHP 8.3.20 diff --git a/ext/standard/tests/file/gh18212.phpt b/ext/standard/tests/file/gh18212.phpt new file mode 100644 index 00000000000..6e4d8ad9bd3 --- /dev/null +++ b/ext/standard/tests/file/gh18212.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-18212: fseek with SEEK_CUR and negative offset leads to negative file stream position. +--FILE-- + +--EXPECT-- +int(-1) +int(-1) + diff --git a/ext/standard/tests/file/stream_rfc2397_007.phpt b/ext/standard/tests/file/stream_rfc2397_007.phpt index dcbe5beeb3d..49a037e855f 100644 --- a/ext/standard/tests/file/stream_rfc2397_007.phpt +++ b/ext/standard/tests/file/stream_rfc2397_007.phpt @@ -118,7 +118,7 @@ int(2) bool(false) ===S:-10,C=== int(-1) -bool(false) +int(2) bool(false) ===S:3,S=== int(0) diff --git a/main/streams/streams.c b/main/streams/streams.c index 7a5dc2a58aa..4e0aaa53b44 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1390,6 +1390,10 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) } whence = SEEK_SET; break; + case SEEK_SET: + if (offset < 0) { + return -1; + } } ret = stream->ops->seek(stream, offset, whence, &stream->position);