PPGe/savedata: Add a bunch of safety checks for png images. Fixes Digimon save crash, see #20125.

This commit is contained in:
Henrik Rydgård committed 2025-03-21 10:07:42 +01:00
1 parent a68e4292f9
commit f14075e650
3 files changed
+25 -8

No files matched your search

+4 -2
View File
@@ -1720,11 +1720,13 @@ void SavedataParam::ClearFileInfo(SaveFileInfo &saveInfo, const std::string &sav
}
if (GetPspParam()->newData.IsValid() && GetPspParam()->newData->buf.IsValid()) {
// We have a png to show
// We may have a png to show
if (!noSaveIcon) {
noSaveIcon = new SaveFileInfo();
PspUtilitySavedataFileData *newData = GetPspParam()->newData;
noSaveIcon->texture = new PPGeImage(newData->buf.ptr, (SceSize)newData->size);
if (Memory::IsValidRange(newData->buf.ptr, newData->size)) {
noSaveIcon->texture = new PPGeImage(newData->buf.ptr, (SceSize)newData->size);
}
}
saveInfo.texture = noSaveIcon->texture;
} else if ((u32)GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_SAVE && GetPspParam()->icon0FileData.buf.IsValid()) {
+16 -1
View File
@@ -1343,12 +1343,17 @@ void PPGeDisableTexture()
std::vector<PPGeImage *> PPGeImage::loadedTextures_;
constexpr size_t MAX_VALID_IMAGE_SIZE = 16 * 1024 * 1024;
PPGeImage::PPGeImage(std::string_view pspFilename)
: filename_(pspFilename) {
}
PPGeImage::PPGeImage(u32 pngPointer, size_t pngSize)
: filename_(""), png_(pngPointer), size_(pngSize) {
if (!Memory::IsValidRange(this->png_, this->size_)) {
WARN_LOG(Log::sceGe, "Created PPGeImage from invalid memory range %08x (%08x bytes). Will not be drawn.");
}
}
PPGeImage::~PPGeImage() {
@@ -1366,7 +1371,13 @@ bool PPGeImage::Load() {
unsigned char *textureData;
int success;
if (filename_.empty()) {
success = pngLoadPtr(Memory::GetPointerRange(png_, (u32)size_), size_, &width_, &height_, &textureData);
_dbg_assert_(size_ < MAX_VALID_IMAGE_SIZE);
const u8 *srcPtr = Memory::GetPointerRange(png_, (u32)size_);
if (!srcPtr) {
ERROR_LOG(Log::sceGe, "Trying to load PPGeImage from invalid range: %08x, %08x bytes", png_, size_);
return false;
}
success = pngLoadPtr(srcPtr, size_, &width_, &height_, &textureData);
} else {
std::vector<u8> pngData;
if (pspFileSystem.ReadEntireFile(filename_, pngData) < 0) {
@@ -1406,6 +1417,10 @@ bool PPGeImage::IsValid() {
if (loadFailed_)
return false;
if (!Memory::IsValidRange(this->png_, this->size_)) {
return false;
}
if (texture_ == 0) {
Decimate();
return Load();
+5 -5
View File
@@ -146,14 +146,14 @@ private:
std::string filename_;
// Only valid if filename_.empty().
u32 png_;
size_t size_;
u32 png_ = 0;
size_t size_ = 0;
u32 texture_ = 0;
int width_;
int height_;
int width_ = 0;
int height_ = 0;
int lastFrame_;
int lastFrame_ = 0;
bool loadFailed_ = false;
};