From 994d48b2fa4b58b3d2f94a77ab4970b4489880c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Thu, 11 Sep 2025 21:03:12 +0200 Subject: [PATCH 1/2] FileReadStream improvement --- components/ByteStream/ReadStream/class-filereadstream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ByteStream/ReadStream/class-filereadstream.php b/components/ByteStream/ReadStream/class-filereadstream.php index cd4dce42..290bce15 100644 --- a/components/ByteStream/ReadStream/class-filereadstream.php +++ b/components/ByteStream/ReadStream/class-filereadstream.php @@ -58,10 +58,10 @@ protected function internal_pull( $n ): string { protected function seek_outside_of_buffer( int $target_offset ): void { $this->buffer = ''; $this->offset_in_current_buffer = 0; - $this->bytes_already_forgotten = $target_offset; if ( false === fseek( $this->file_pointer, $target_offset ) ) { throw new ByteStreamException( 'Failed to seek to offset' ); } + $this->bytes_already_forgotten = $target_offset; } public function close_reading(): void { From a14b85724c3bbe2b3816ec4c5f8a40e4600be6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Thu, 11 Sep 2025 23:30:01 +0200 Subject: [PATCH 2/2] Test error handling in FileReadStream --- .../ReadStream/class-filereadstream.php | 8 ++- .../ByteStream/Tests/FileReadStreamTest.php | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 components/ByteStream/Tests/FileReadStreamTest.php diff --git a/components/ByteStream/ReadStream/class-filereadstream.php b/components/ByteStream/ReadStream/class-filereadstream.php index 290bce15..4680dffc 100644 --- a/components/ByteStream/ReadStream/class-filereadstream.php +++ b/components/ByteStream/ReadStream/class-filereadstream.php @@ -56,11 +56,13 @@ protected function internal_pull( $n ): string { } protected function seek_outside_of_buffer( int $target_offset ): void { - $this->buffer = ''; - $this->offset_in_current_buffer = 0; - if ( false === fseek( $this->file_pointer, $target_offset ) ) { + $retval = fseek( $this->file_pointer, $target_offset ); + if ( -1 === $retval ) { throw new ByteStreamException( 'Failed to seek to offset' ); } + + $this->buffer = ''; + $this->offset_in_current_buffer = 0; $this->bytes_already_forgotten = $target_offset; } diff --git a/components/ByteStream/Tests/FileReadStreamTest.php b/components/ByteStream/Tests/FileReadStreamTest.php new file mode 100644 index 00000000..96d67307 --- /dev/null +++ b/components/ByteStream/Tests/FileReadStreamTest.php @@ -0,0 +1,58 @@ +seek_outside_of_buffer($target_offset); + } + }; + + try { + // Go to a place in the buffer where reading 20 bytes will yield a different + // result than reading 20 bytes from the beginning of the file + $stream->pull(8); + $stream->consume(8); + $positionBefore = $stream->tell(); + + // Try to seek to the beginning - this will fail in seek_outside_of_buffer + // because 0 is now outside the buffer range (bytes_already_forgotten > 0) + try { + $stream->seek(-1); + $this->fail('Expected ByteStreamException was not thrown'); + } catch (ByteStreamException $e) { + $this->assertEquals('Failed to seek to offset', $e->getMessage()); + } + + // Verify stream position hasn't changed and stream is still usable + $this->assertEquals($positionBefore, $stream->tell()); + + // Should be able to continue reading from current position + $stream->pull(20); + $nextData = $stream->consume(20); + $expectedData = substr($content, $positionBefore, 20); + $this->assertEquals($expectedData, $nextData); + + } finally { + // Clean up resource + if (is_resource($resource)) { + fclose($resource); + } + } + } +} \ No newline at end of file