mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-02 10:45:14 +02:00
Fix a batch of missing or wrong range validation
Memory::IsValidAddress and friends tested the extended-RAM range with (address & 0x3F000000), i.e. at 16MB granularity, so they accepted the whole 16MB block containing the end of RAM. That's harmless at 32MB and 64MB, but the Sora no Kiseki SC/3rd HD remasters run with 0x04C00000, so addresses from 0x0CC00000 to 0x0CFFFFFF read as valid, and MaxSizeAtAddress then underflowed to ~4GB there - which defeats ClampValidSizeAt and IsValidRange entirely for that window. Mask with 0x3FFFFFFF instead, in all five helpers and the copies in MemMapFunctions.cpp. IsValidTextureAddress's extended-RAM branch repeated the first branch's whole mask rather than just its alignment bits, so it was dead code and extended RAM was never accepted as a texture source. ComputeTextureHash checked IsValidAddress(addr + sizeInRAM), i.e. only the end address, which can land in a different valid region than the start - a VRAM texture with a large enough computed size ends exactly at the base of RAM and "passes" while reading far past the 8MB VRAM view. Use IsValidRange. TextureReplacer::ComputeHash's strided path had no range check at all, unlike the contiguous path right above it. Also clamp the pack-supplied reduce-hash factor to 1.0 - it's a reduction, and the ini parser only rejects exactly 0. ZipExtractFileToMemory read an uninitialized zip_stat when zip_stat_index failed (it ignored the return value) and sized a host allocation directly from the zip's declared uncompressed size. Reached just by opening an archive. Memory::Reinit ignored Init()'s return value, and DoState fed it a memory size taken straight from the savestate. A bogus size made the map fail to allocate and left base null, after which DoMemoryVoid wrote RAM through it. Validate the size, propagate the failure, and roll back to the previous size if reinit fails. 314 pspautotests pass, all unit tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCPmm7FoQUoqrbMdhfqhQ2
This commit is contained in:
co-authored by
Claude Opus 5
parent
e4a0f649fa
commit
016f976b1f
@@ -31,7 +31,7 @@ u8 *GetPointerWriteOrException(const u32 address) {
|
||||
if ((address & 0x3E000000) == 0x08000000 || // RAM
|
||||
(address & 0xBF800000) == 0x04000000 || // VRAM
|
||||
(address & 0x3FFFC000) == 0x00010000 || // Scratchpad
|
||||
((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
((address & 0x3FFFFFFF) >= 0x08000000 && (address & 0x3FFFFFFF) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
return GetPointerWriteUnchecked(address);
|
||||
} else {
|
||||
// Size is not known, we pass 0 to signal that.
|
||||
@@ -44,7 +44,7 @@ const u8 *GetPointerOrException(const u32 address) {
|
||||
if ((address & 0x3E000000) == 0x08000000 || // RAM
|
||||
(address & 0xBF800000) == 0x04000000 || // VRAM
|
||||
(address & 0x3FFFC000) == 0x00010000 || // Scratchpad
|
||||
((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
((address & 0x3FFFFFFF) >= 0x08000000 && (address & 0x3FFFFFFF) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
return GetPointerUnchecked(address);
|
||||
} else {
|
||||
// Size is not known, we pass 0 to signal that.
|
||||
@@ -90,7 +90,7 @@ inline void ReadMemoryOrException(T &var, const u32 address) {
|
||||
if ((address & 0x3E000000) == 0x08000000 || // RAM
|
||||
(address & 0xBF800000) == 0x04000000 || // VRAM
|
||||
(address & 0x3FFFC000) == 0x00010000 || // Scratchpad
|
||||
((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
((address & 0x3FFFFFFF) >= 0x08000000 && (address & 0x3FFFFFFF) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
var = *((const T*)GetPointerUnchecked(address));
|
||||
} else {
|
||||
Core_MemoryException(address, sizeof(T), currentMIPS->pc, MemoryExceptionType::READ_WORD);
|
||||
@@ -103,7 +103,7 @@ inline void WriteMemoryOrException(u32 address, const T data) {
|
||||
if ((address & 0x3E000000) == 0x08000000 || // RAM
|
||||
(address & 0xBF800000) == 0x04000000 || // VRAM
|
||||
(address & 0x3FFFC000) == 0x00010000 || // Scratchpad
|
||||
((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
((address & 0x3FFFFFFF) >= 0x08000000 && (address & 0x3FFFFFFF) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)
|
||||
*(T*)GetPointerUnchecked(address) = data;
|
||||
} else {
|
||||
Core_MemoryException(address, sizeof(T), currentMIPS->pc, MemoryExceptionType::WRITE_WORD);
|
||||
@@ -113,7 +113,7 @@ inline void WriteMemoryOrException(u32 address, const T data) {
|
||||
bool IsRAMAddress(const u32 address) {
|
||||
if ((address & 0x3E000000) == 0x08000000) {
|
||||
return true;
|
||||
} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
|
||||
} else if ((address & 0x3FFFFFFF) >= 0x08000000 && (address & 0x3FFFFFFF) < 0x08000000 + g_MemorySize) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user