From 5f4926483a5e54dc1c1b38439408c5dfc4ab33d6 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Sun, 18 Jan 2026 09:27:55 +0530 Subject: [PATCH 1/4] Fix fseek undefined behavior --- main/streams/memory.c | 4 ++-- tests/basic/bug20964.phpt | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/basic/bug20964.phpt diff --git a/main/streams/memory.c b/main/streams/memory.c index 2f411ff8e8c9c..37c3dc69e2280 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -128,7 +128,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe switch(whence) { case SEEK_CUR: if (offset < 0) { - if (ms->fpos < (size_t)(-offset)) { + if (ms->fpos < -(size_t)offset) { ms->fpos = 0; *newoffs = -1; return -1; @@ -165,7 +165,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe stream->eof = 0; stream->fatal_error = 0; return 0; - } else if (ZSTR_LEN(ms->data) < (size_t)(-offset)) { + } else if (ZSTR_LEN(ms->data) < -(size_t)offset) { ms->fpos = 0; *newoffs = -1; return -1; diff --git a/tests/basic/bug20964.phpt b/tests/basic/bug20964.phpt new file mode 100644 index 0000000000000..5c739a52a5935 --- /dev/null +++ b/tests/basic/bug20964.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #20964 fseek with PHP_INT_MIN on php://memory +--FILE-- + +--EXPECTF-- +int(%d) \ No newline at end of file From 69b4e6dbc6558692c3aa705ef588e1d70edeb3e7 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Sun, 18 Jan 2026 10:23:05 +0530 Subject: [PATCH 2/4] Fix fseek undefined behavior --- tests/basic/bug20964.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic/bug20964.phpt b/tests/basic/bug20964.phpt index 5c739a52a5935..95c78a8cab77c 100644 --- a/tests/basic/bug20964.phpt +++ b/tests/basic/bug20964.phpt @@ -8,4 +8,4 @@ $result = fseek($stream, PHP_INT_MIN, SEEK_END); var_dump($result); ?> --EXPECTF-- -int(%d) \ No newline at end of file +int(-1) \ No newline at end of file From 40c76b2c366791a238fa1d23a274e5f71fc8be30 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Mon, 19 Jan 2026 05:38:46 +0530 Subject: [PATCH 3/4] Fix fseek undefined behavior --- main/streams/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/streams/memory.c b/main/streams/memory.c index 37c3dc69e2280..2a7dab222f1eb 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -128,7 +128,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe switch(whence) { case SEEK_CUR: if (offset < 0) { - if (ms->fpos < -(size_t)offset) { + if (ms->fpos < (size_t)(-offset)) { ms->fpos = 0; *newoffs = -1; return -1; From 015fc48ac401eb1b563d49060f4e02cb9a06f348 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Mon, 19 Jan 2026 07:31:54 +0530 Subject: [PATCH 4/4] Fix fseek undefined behavior --- main/streams/memory.c | 7 ++++++- tests/basic/bug20964.phpt | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/main/streams/memory.c b/main/streams/memory.c index 2a7dab222f1eb..e6969e2038e3e 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -125,6 +125,11 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); + if (offset == ZEND_LONG_MIN) { + zend_argument_value_error(2, "must be greater than " ZEND_LONG_FMT, ZEND_LONG_MIN); + return FAILURE; + } + switch(whence) { case SEEK_CUR: if (offset < 0) { @@ -165,7 +170,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe stream->eof = 0; stream->fatal_error = 0; return 0; - } else if (ZSTR_LEN(ms->data) < -(size_t)offset) { + } else if (ZSTR_LEN(ms->data) < (size_t)(-offset)) { ms->fpos = 0; *newoffs = -1; return -1; diff --git a/tests/basic/bug20964.phpt b/tests/basic/bug20964.phpt index 95c78a8cab77c..9aae8946818ec 100644 --- a/tests/basic/bug20964.phpt +++ b/tests/basic/bug20964.phpt @@ -8,4 +8,8 @@ $result = fseek($stream, PHP_INT_MIN, SEEK_END); var_dump($result); ?> --EXPECTF-- -int(-1) \ No newline at end of file +Fatal error: Uncaught ValueError: fseek(): Argument #2 ($offset) must be greater than -%d in %s:%d +Stack trace: +#0 %s(%d): fseek(Resource id #%d, -%d, %d) +#1 {main} + thrown in %s on line %d \ No newline at end of file