Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Failed seek on php://memory and SQLite blob streams sets the stream position to -1

未关闭
#23,905 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
55/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
c, php
领域
backend

调研方向

Start by running the two PHP reproducers for php://memory and SQLite3 blob streams, then inspect php_stream_seek() in main/streams/streams.c and the stream implementations named in the report. Done means failed seeks preserve a usable position, ftell() returns the expected offset, subsequent SEEK_CUR operations work, and the debug assertion and release overflow no longer occur.

由索引模型根据 Issue 内容生成。

描述

Bug Status: Needs Triage
Description

When a seek fails on a php://memory stream, or on a blob stream from SQLite3::openBlob() or Pdo\Sqlite::openBlob(), the stream's position is set to -1. Meanwhile the stream's own read/write offset is moved: php://memory resets it to 0, and the blob streams clamp it to 0 or to the blob size.

After that:

  • ftell() returns false, although the stream is still usable.
  • Debug builds abort on the next fseek(..., SEEK_CUR) with Assertion 'stream->position >= 0' failed in php_stream_seek().
  • Release builds hit a signed integer overflow in the SEEK_CUR overflow guard, where ZEND_LONG_MAX - stream->position is computed with position -1. The requested offset becomes PHP_INT_MAX:
    • php://memory moves to PHP_INT_MAX and reads return "".
    • The blob stream fails the seek again and stays at -1.

Plain files and php://temp behave correctly: a failed seek returns -1 and leaves the position unchanged.

Reproducer 1: php://memory

<?php
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'hello world');
fseek($stream, 6);

var_dump(fseek($stream, -7, SEEK_CUR)); // fails: before start of stream
var_dump(ftell($stream));
var_dump(fseek($stream, 1, SEEK_CUR));
var_dump(ftell($stream));
var_dump(fread($stream, 4));

Actual output:

int(-1)
bool(false)
int(0)
int(9223372036854775807)
string(0) ""

Actual output (debug build):

int(-1)
bool(false)
php: main/streams/streams.c:1393: php_stream_seek: Assertion `stream->position >= 0' failed.
Aborted (core dumped)

Expected output:

int(-1)
int(6)
int(0)
int(7)
string(4) "orld"

Reproducer 2: SQLite3 blob (Pdo\Sqlite::openBlob() is affected the same way)

<?php
$db = new SQLite3(':memory:');
$db->exec('CREATE TABLE test (id INTEGER PRIMARY KEY, data BLOB)');
$db->exec("INSERT INTO test (id, data) VALUES (1, 'hello world')");
$stream = $db->openBlob('test', 'data', 1);

var_dump(fseek($stream, 12)); // fails: beyond end of blob
var_dump(ftell($stream));
var_dump(fseek($stream, 6, SEEK_CUR));
var_dump(ftell($stream));
var_dump(fread($stream, 5));

Actual output:

int(-1)
bool(false)
int(-1)
bool(false)
string(0) ""

(Debug builds abort with the same assertion as reproducer 1.)

Expected output:

int(-1)
int(0)
int(0)
int(6)
string(5) "world"

Related: #21433 #20964 #20927

PHP Version
PHP 8.4.27-dev (cli) (built: Sep 25 2026 10:06:46) (NTS)
PHP 8.5.12-dev (cli) (built: Sep 25 2026 10:12:00) (NTS)
PHP 8.6.0-dev (cli) (built: Sep 25 2026 10:17:03) (NTS)
Operating System

Ubuntu 24.04

主要语言
C
星标
40.4k
派生
8.2k
平均合并
3 天 4 小时
30 天内合并 PR
150

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

php/php-src 的其他 Issue

查看 php/php-src 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。