Skip to content

Commit

Permalink
filehandle: Add missing avio_read error check
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
dwbuiten committed Apr 29, 2024
1 parent d7c86dd commit 8b4ca86
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/core/filehandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,16 @@ int64_t FileHandle::Tell() {

size_t FileHandle::Read(char *buffer, size_t size) {
int count = avio_read(avio, (unsigned char *)buffer, size);
if (count < 0)
if (count < 0) {
throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ,
"Failed to read from '" + filename + "': " + AVErrorToString(count));
} else if (avio_feof(avio)) {
// "Similar to feof() but also returns nonzero on read errors" -- FFmpeg docs
if (avio->error != 0 && avio->error != AVERROR_EOF) {
throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ,
"Failed to read from '" + filename + "': " + AVErrorToString(avio->error));
}
}
return (size_t)count;
}

Expand Down

0 comments on commit 8b4ca86

Please sign in to comment.