Merge pull request #20141 from hrydgard/digimon-fix

PPGe/savedata: Add a bunch of safety checks for png images.
This commit is contained in:
Henrik Rydgård 2025-03-21 10:34:45 +01:00 committed by GitHub
commit 112bd904b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 8 deletions

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()) {

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();

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;
};