镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

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

Description

@marc-mabe

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

Activity

  1. marc-mabe commented on Oct 1, 2026

    @marc-mabe
    ContributorAuthor

    There more inconsistencies of the fseek exceeding behavior.
    Here is a script to compare different streams: https://github.com/proxy/gist.github.com/marc-mabe/add8a121960023e8334324e7d76f1fbf

    This is showing even more inconsistencies:

    1. Whether a failed seek keeps the position depends on whence

    • wrong position after SEEK_END -12 for ...
      • php://temp in memory, SplTempFileObject
      • php://memory
      • SQLite3 / Pdo\Sqlite blob
    • wrong position after SEEK_CUR -7 for ...
      • php://memory
      • SQLite3 / Pdo\Sqlite blob

    2. The reported position and the real one drift apart

    On failure, the memory handler moves its own position to 0. The SQLite blob handlers move theirs to 0 or to the end. Meanwhile PHP reports false.

    • After a failed seek, fread() silently returns data from 0 or from the end.
    • The next fseek(…, SEEK_CUR) aborts the debug build at ZEND_ASSERT(stream->position >= 0)

    3. php://temp changes behaviour depending on its size

    Before spilling to disk, a failed SEEK_END loses the position. After spilling, the same seek keeps it. The temp stream forwards seeks to an inner stream, and the inner memory and file streams fail differently.

    4. Phar refuses seeks past the end, and the following write or read then corrupts silently

    Phar's seek handler rejects any target past the entry's size and gives no warning. The position stays at 6, so:

    • On a writable entry, fwrite("!") lands at 6: the data becomes "hello !orld". Code that doesn't check the fseek() return value overwrites data where POSIX would append after a gap.
    • On a read-only entry, fread(5) returns "world" instead of "".

    5. Phar sets EOF too early

    After phar's fread(5) returns "world", reading exactly up to the end, EOF is true. gz in the same situation reports false, and earlier I checked that a plain file and php://memory also report false. Those only set EOF once a read hits the end.

    6. SQLite blobs: refusing is fine, the side effects aren't

    • Refusing past-end seeks and failing writes ("It is not possible to increase the size of a BLOB") fits a fixed-size object. It's the fmemopen() model rather than the file model.
    • But the position is lost and can't be restored, because ftell() is false. In this run the read and write therefore happen at 11, only because printing the data left the blob there.

    7. gz writes on seek

    In write mode a forward seek past the end writes the zeros straight away. The data right after the seek already shows "hello world\000". With POSIX, a seek that is never followed by a write leaves the file unchanged; here the gzip file changes anyway.

    Output:

    Compares how seeking outside of a stream behaves across stream types.
    
    For every stream type (writable and read-only) and every seek below, the
    stream is freshly created with the data "hello world" and positioned at the
    middle (offset 6) via SEEK_SET. Then a single seek before the beginning or
    after the end is done using SEEK_SET, SEEK_CUR or SEEK_END, printing the seek
    result, the resulting position and any warnings. For seeks after the end the
    result of feof() and the full stream data are printed as well.
    
    Lines starting with "+" show what happens when reading (read-only streams) or
    writing (writable streams) on the same stream afterwards. Printing the data
    moves the position, so it is restored to where the seek left it first.
    
    PHP 8.6.0-dev (Linux 64-bit)
    data: "hello world" (11 bytes)
    
    === file (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
    
    === file (read-only) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
    
    === SplFileObject (writable) ===
      -- seek before the beginning --
        SplFileObject->fseek(-1, SEEK_SET)       => -1      ftell=6
        SplFileObject->fseek(-7, SEEK_CUR)       => -1      ftell=6
        SplFileObject->fseek(-12, SEEK_END)      => -1      ftell=6
      -- seek after the end --
        SplFileObject->fseek(12, SEEK_SET)       => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fwrite("!")           => 1       ftell=13 eof=false
                                                    data="hello world\000!"
        SplFileObject->fseek(6, SEEK_CUR)        => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fwrite("!")           => 1       ftell=13 eof=false
                                                    data="hello world\000!"
        SplFileObject->fseek(1, SEEK_END)        => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fwrite("!")           => 1       ftell=13 eof=false
                                                    data="hello world\000!"
    
    === SplFileObject (read-only) ===
      -- seek before the beginning --
        SplFileObject->fseek(-1, SEEK_SET)       => -1      ftell=6
        SplFileObject->fseek(-7, SEEK_CUR)       => -1      ftell=6
        SplFileObject->fseek(-12, SEEK_END)      => -1      ftell=6
      -- seek after the end --
        SplFileObject->fseek(12, SEEK_SET)       => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fread(5)              => ""      ftell=12 eof=true
                                                    data="hello world"
        SplFileObject->fseek(6, SEEK_CUR)        => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fread(5)              => ""      ftell=12 eof=true
                                                    data="hello world"
        SplFileObject->fseek(1, SEEK_END)        => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplFileObject->fread(5)              => ""      ftell=12 eof=true
                                                    data="hello world"
    
    === php://temp (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
    
    === php://temp (read-only) ===
      -- seek before the beginning --
        note: read-only temp stream cannot be pre-filled -> empty
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(1, SEEK_END)                       => 0       ftell=1 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=1 feof=true
                                                    data=""
    
    === php://temp/maxmemory:0 (spilled to disk) (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
    
    === php://temp/maxmemory:0 (spilled to disk) (read-only) ===
      -- seek before the beginning --
        note: read-only temp stream cannot be pre-filled -> empty
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(1, SEEK_END)                       => 0       ftell=1 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=1 feof=true
                                                    data=""
    
    === SplTempFileObject (writable) ===
      -- seek before the beginning --
        SplTempFileObject->fseek(-1, SEEK_SET)   => -1      ftell=6
        SplTempFileObject->fseek(-7, SEEK_CUR)   => -1      ftell=6
        SplTempFileObject->fseek(-12, SEEK_END)  => -1      ftell=false
      -- seek after the end --
        SplTempFileObject->fseek(12, SEEK_SET)   => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplTempFileObject->fwrite("!")       => 1       ftell=13 eof=false
                                                    data="hello world\000!"
        SplTempFileObject->fseek(6, SEEK_CUR)    => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplTempFileObject->fwrite("!")       => 1       ftell=13 eof=false
                                                    data="hello world\000!"
        SplTempFileObject->fseek(1, SEEK_END)    => 0       ftell=12 eof=false
                                                    data="hello world"
          + SplTempFileObject->fwrite("!")       => 1       ftell=13 eof=false
                                                    data="hello world\000!"
    
    === file + string.rot13 filter (writable) ===
      -- seek before the beginning --
        note: read+write filter: stored rot13 encoded, read back decoded
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
    
    === file + string.rot13 filter (read-only) ===
      -- seek before the beginning --
        note: read filter: stored rot13 encoded, read back decoded
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data="hello world"
    
    === phar entry (writable) ===
      -- seek before the beginning --
        note: phar.readonly='0' (writing phar archives requires running with -d phar.readonly=0)
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=6 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=7 feof=false
                                                    data="hello !orld"
        fseek(6, SEEK_CUR)                       => -1      ftell=6 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=7 feof=false
                                                    data="hello !orld"
        fseek(1, SEEK_END)                       => -1      ftell=6 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=7 feof=false
                                                    data="hello !orld"
    
    === phar entry (read-only) ===
      -- seek before the beginning --
        note: phar.readonly='0' (writing phar archives requires running with -d phar.readonly=0)
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=6
        fseek(-12, SEEK_END)                     => -1      ftell=6
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=6 feof=false
                                                    data="hello world"
          + fread(5)                             => "world" ftell=11 feof=true
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => -1      ftell=6 feof=false
                                                    data="hello world"
          + fread(5)                             => "world" ftell=11 feof=true
                                                    data="hello world"
        fseek(1, SEEK_END)                       => -1      ftell=6 feof=false
                                                    data="hello world"
          + fread(5)                             => "world" ftell=11 feof=true
                                                    data="hello world"
    
    === php://memory (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
        fseek(1, SEEK_END)                       => 0       ftell=12 feof=false
                                                    data="hello world"
          + fwrite("!")                          => 1       ftell=13 feof=false
                                                    data="hello world\000!"
    
    === php://memory (read-only) ===
      -- seek before the beginning --
        note: read-only memory stream cannot be pre-filled -> empty
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(6, SEEK_CUR)                       => 0       ftell=12 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=12 feof=true
                                                    data=""
        fseek(1, SEEK_END)                       => 0       ftell=1 feof=false
                                                    data=""
          + fread(5)                             => ""      ftell=1 feof=true
                                                    data=""
    
    === SQLite3::openBlob() (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
        fseek(1, SEEK_END)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
    
    === SQLite3::openBlob() (read-only) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
        fseek(1, SEEK_END)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
    
    === Pdo\Sqlite::openBlob() (writable) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
        fseek(1, SEEK_END)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fwrite("!")                          => false   ftell=11 feof=true  [fwrite(): It is not possible to increase the size of a BLOB]
                                                    data="hello world"
    
    === Pdo\Sqlite::openBlob() (read-only) ===
      -- seek before the beginning --
        fseek(-1, SEEK_SET)                      => -1      ftell=6
        fseek(-7, SEEK_CUR)                      => -1      ftell=false
        fseek(-12, SEEK_END)                     => -1      ftell=false
      -- seek after the end --
        fseek(12, SEEK_SET)                      => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
        fseek(6, SEEK_CUR)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
        fseek(1, SEEK_END)                       => -1      ftell=false feof=false
                                                    data="hello world"
                                                    (position false cannot be restored)
          + fread(5)                             => ""      ftell=11 feof=true
                                                    data="hello world"
    
    === zlib gzseek() (writable) ===
      -- seek before the beginning --
        note: write mode: gzseek() only supports forward seeks, so the stream stays at 11 instead of 6; data is read by flushing the stream and inflating the file
        gzseek(-1, SEEK_SET)                     => -1      gztell=11
        gzseek(-7, SEEK_CUR)                     => -1      gztell=11
        gzseek(-12, SEEK_END)                    => -1      gztell=11  [gzseek(): SEEK_END is not supported]
      -- seek after the end --
        gzseek(12, SEEK_SET)                     => 0       gztell=12 gzeof=false
                                                    data="hello world\000"
          + gzwrite("!")                         => 1       gztell=13 gzeof=false
                                                    data="hello world\000!"
        gzseek(6, SEEK_CUR)                      => 0       gztell=17 gzeof=false
                                                    data="hello world\000\000\000\000\000\000"
          + gzwrite("!")                         => 1       gztell=18 gzeof=false
                                                    data="hello world\000\000\000\000\000\000!"
        gzseek(1, SEEK_END)                      => -1      gztell=11 gzeof=false  [gzseek(): SEEK_END is not supported]
                                                    data="hello world"
          + gzwrite("!")                         => 1       gztell=12 gzeof=false
                                                    data="hello world!"
    
    === zlib gzseek() (read-only) ===
      -- seek before the beginning --
        gzseek(-1, SEEK_SET)                     => -1      gztell=6
        gzseek(-7, SEEK_CUR)                     => -1      gztell=6
        gzseek(-12, SEEK_END)                    => -1      gztell=6  [gzseek(): SEEK_END is not supported]
      -- seek after the end --
        gzseek(12, SEEK_SET)                     => 0       gztell=12 gzeof=false
                                                    data="hello world"
          + gzread(5)                            => ""      gztell=12 gzeof=true
                                                    data="hello world"
        gzseek(6, SEEK_CUR)                      => 0       gztell=12 gzeof=false
                                                    data="hello world"
          + gzread(5)                            => ""      gztell=12 gzeof=true
                                                    data="hello world"
        gzseek(1, SEEK_END)                      => -1      gztell=6 gzeof=false  [gzseek(): SEEK_END is not supported]
                                                    data="hello world"
          + gzread(5)                            => "world" gztell=11 gzeof=false
                                                    data="hello world"
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions