Skip to content

Commit 8b4ca86

Browse files
committed
filehandle: Add missing avio_read error check
Rather than return an error when reading fails part way though, avio_read returns those bytes and fails on the *next* read. This can cause weird stuff to happen, like calculating wrong file signatures due to partial reads, when used over a network. To figure out if there was a partial read due to an error, we need to check avio_feof, which for some reason not only checks for EOF but also for all read/write errors, by its own docs. This only tells us *if* there was an error, or EOF, though, so we must also check the contents of avio->error after that. Signed-off-by: Derek Buitenhuis <[email protected]>
1 parent d7c86dd commit 8b4ca86

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

src/core/filehandle.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,16 @@ int64_t FileHandle::Tell() {
7373

7474
size_t FileHandle::Read(char *buffer, size_t size) {
7575
int count = avio_read(avio, (unsigned char *)buffer, size);
76-
if (count < 0)
76+
if (count < 0) {
7777
throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ,
7878
"Failed to read from '" + filename + "': " + AVErrorToString(count));
79+
} else if (avio_feof(avio)) {
80+
// "Similar to feof() but also returns nonzero on read errors" -- FFmpeg docs
81+
if (avio->error != 0 && avio->error != AVERROR_EOF) {
82+
throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ,
83+
"Failed to read from '" + filename + "': " + AVErrorToString(avio->error));
84+
}
85+
}
7986
return (size_t)count;
8087
}
8188

0 commit comments

Comments
 (0)