From 1c357f7f7b705564649ec9c755b0efcf94fd0926 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 25 May 2016 18:42:21 -0700 Subject: [PATCH] Fix reads from cache outside the file. Homebrew seems to all trigger us to read after the end of file, which was looping infinitely. Fixes #8773. --- Core/FileLoaders/CachingFileLoader.cpp | 7 ++++++- Core/FileLoaders/DiskCachingFileLoader.cpp | 7 ++++++- Core/FileLoaders/RamCachingFileLoader.cpp | 9 +++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Core/FileLoaders/CachingFileLoader.cpp b/Core/FileLoaders/CachingFileLoader.cpp index f33734aa49..dc4518a68d 100644 --- a/Core/FileLoaders/CachingFileLoader.cpp +++ b/Core/FileLoaders/CachingFileLoader.cpp @@ -72,7 +72,12 @@ size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { // While in case the cache size is too small for the entire read. while (readSize < bytes) { SaveIntoCache(absolutePos + readSize, bytes - readSize); - readSize += ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + readSize += bytesFromCache; + if (bytesFromCache == 0) { + // We can't read any more. + break; + } } StartReadAhead(absolutePos + readSize); diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index e346cf35fe..5bb49a82cd 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -82,7 +82,12 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) while (readSize < bytes) { readSize += cache_->SaveIntoCache(backend_, absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); // If there are already-cached blocks afterward, we have to read them. - readSize += cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + size_t bytesFromCache = cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + readSize += bytesFromCache; + if (bytesFromCache == 0) { + // We can't read any more. + break; + } } } else { readSize = backend_->ReadAt(absolutePos, bytes, data); diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index 28eda51cdc..20598d631c 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -79,7 +79,12 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { // While in case the cache size is too small for the entire read. while (readSize < bytes) { SaveIntoCache(absolutePos + readSize, bytes - readSize); - readSize += ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + readSize += bytesFromCache; + if (bytesFromCache == 0) { + // We can't read any more. + break; + } } } @@ -134,7 +139,7 @@ size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) { u8 *p = (u8 *)data; // Clamp bytes to what's actually available. - if (pos + bytes > filesize_) { + if (pos + (s64)bytes > filesize_) { // Should've been caught above, but just in case. if (pos >= filesize_) { return 0;