You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: SFTPReadStream returns no data after seeking back from EOF (movie previews fail on SFTP storage) #66001
This is not a troubleshooting question, general support matter, or webserver/proxy problem, but likely a bug.
This issue is not already reported on Github OR solved at the Community Help Forum (I've searched!).
I'm using a maintained major version of Nextcloud Server and tested against the latest patch level.
I agree to follow Nextcloud's Code of Conduct.
I've tried my best to provide clear reproduction steps that someone unfamiliar with this bug could use to reproduce it.
Bug description
SFTPReadStream never clears its $eof flag when seeking. Once a read has reached the end of the remote file, every later fseek() reports success and ftell() returns the new position, but all reads return an empty string.
The most visible effect is the movie preview on SFTP external storage. OC\Preview\Movie::getSparseFile() walks the MP4 atoms with stream_get_contents($content, …, $offset) to find the moov atom. When moov is at the end of the file (typical for phone recordings), that walk reads up to EOF. The following fseek($content, 0) + stream_copy_to_stream() then copies 0 bytes, so ffmpeg gets a sparse file that is all zeros and fails ("Invalid data found when processing input"). The log shows Movie preview generation process failed, file=… again on every preview request.
seekTo() resets the positions and the buffer, but not $this->eof:
Upload an MP4 larger than 10 MB with the moov atom at the end (e.g. a phone video, or ffmpeg -i in.mp4 -c copy -movflags -faststart out.mp4).
Open the folder so a preview is requested, or call \OC\Preview\Movie::getThumbnail() on the file.
The preview fails, and Movie preview generation process failed is logged.
Minimal check of the stream itself (in a script run as the web user):
$c = $node->fopen('r'); // file on the SFTP storagestream_get_contents($c, 8, $node->getSize() - 8); // read up to EOFfseek($c, 0);
var_dump(feof($c), strlen(fread($c, 8192))); // bool(true), int(0)
Expected behavior
After a seek, reads return the data at the new position, and the preview of the video is generated.
With a fresh stream for the copy, the same sparse file gives a valid image, and with $this->eof = false; in seekTo() the stream reads again after the seek.
Nextcloud Server version
35
Operating system
Other
PHP engine version
PHP 8.5
Web server
Nginx
Database engine version
MariaDB
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
Encryption is Disabled
What user-backends are you using?
Default user-backend (database)
Additional info
Seen on 35.0.2 (official Docker image, fpm), and the code on master is the same. I will open a PR with the one-line fix and a unit test for SFTPReadStream.
Activity
fix(files_external): reset EOF when seeking in SFTPReadStream