Skip to content

Commit b230d18

Browse files
committed
Renderer: fix icon texture OOB crash when switching saves
1 parent 84f66b9 commit b230d18

5 files changed

Lines changed: 40 additions & 7 deletions

File tree

src/core/formats/ps2icon.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,20 +242,21 @@ namespace PS2Icon
242242

243243
size_t Icon::loadTexture(const uint8_t* data, size_t length, size_t offset)
244244
{
245+
constexpr uint16_t DEFAULT_TEXEL = 0xFFFF;
246+
const size_t texturePixelCount = static_cast<size_t>(TEXTURE_WIDTH) * static_cast<size_t>(TEXTURE_HEIGHT);
247+
245248
// Check if texture data exists (bit 2 = 0x04)
246249
if (!(textureFlags & 0x04))
247250
{
248251
Logger::info("PS2Icon: No texture data (textureFlags=0x{:02X})", textureFlags);
249-
texture.resize(1);
250-
texture[0] = 0xFFFF;
252+
texture.assign(texturePixelCount, DEFAULT_TEXEL);
251253
return offset;
252254
}
253255

254256
if (offset >= length)
255257
{
256258
Logger::warn("PS2Icon: Texture flag set but no data remaining");
257-
texture.resize(1);
258-
texture[0] = 0xFFFF;
259+
texture.assign(texturePixelCount, DEFAULT_TEXEL);
259260
return offset;
260261
}
261262

src/core/renderer/Common/RendererCommon.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,22 @@ namespace TextureUtils
352352

353353
std::vector<uint8_t> convertPS2TextureToRGBA(const uint16_t* textureData, uint32_t width, uint32_t height)
354354
{
355-
std::vector<uint8_t> rgba(width * height * 4);
355+
if (!textureData || width == 0 || height == 0)
356+
{
357+
Logger::warn("TextureUtils: Invalid texture input (ptr={}, width={}, height={})", (const void*)textureData, width, height);
358+
return {};
359+
}
360+
361+
const size_t pixelCount = static_cast<size_t>(width) * static_cast<size_t>(height);
362+
if (pixelCount > std::numeric_limits<size_t>::max() / 4)
363+
{
364+
Logger::error("TextureUtils: Texture size overflow (width={}, height={})", width, height);
365+
return {};
366+
}
367+
368+
std::vector<uint8_t> rgba(pixelCount * 4);
356369

357-
for (size_t i = 0; i < width * height; ++i)
370+
for (size_t i = 0; i < pixelCount; ++i)
358371
{
359372
uint16_t pixel = textureData[i];
360373
uint8_t r5 = static_cast<uint8_t>((pixel >> 0) & 0x1F); // Red (bits 0-4)

src/core/renderer/Metal/MetalRenderer.mm

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,14 @@ void updateUniformData(const MetalResources::FrameResources& frameRes, const Cam
236236
uint32_t width = m_icon->getTextureWidth();
237237
uint32_t height = m_icon->getTextureHeight();
238238
auto rgbaData = TextureUtils::convertPS2TextureToRGBA(m_icon->getTextureData(), width, height);
239-
m_impl->resources.uploadTexture(m_impl->device.getDevice(), rgbaData.data(), width, height);
239+
if (!rgbaData.empty())
240+
{
241+
m_impl->resources.uploadTexture(m_impl->device.getDevice(), rgbaData.data(), width, height);
242+
}
243+
else
244+
{
245+
Logger::warn("MTL: Texture conversion returned empty data");
246+
}
240247
m_iconChanged = false;
241248
}
242249

src/core/renderer/OpenGL/OpenGLRenderer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ void OpenGLRenderer::setupTexture()
301301
}
302302

303303
auto rgba = TextureUtils::convertPS2TextureToRGBA(textureData, texWidth, texHeight);
304+
if (rgba.empty())
305+
{
306+
Logger::error("GL: Texture conversion returned empty data");
307+
m_context->releaseCurrent();
308+
return;
309+
}
304310

305311
m_resources.uploadTexture(rgba.data(), texWidth, texHeight);
306312

src/core/renderer/Vulkan/VulkanRenderer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,12 @@ bool VulkanRenderer::uploadTexture()
695695
}
696696

697697
auto rgba = TextureUtils::convertPS2TextureToRGBA(textureData, texWidth, texHeight);
698+
if (rgba.empty())
699+
{
700+
Logger::warn("VK: Texture conversion returned empty data");
701+
return false;
702+
}
703+
698704
Logger::debug("VK: Texture converted to RGBA, size={} bytes", rgba.size());
699705
VkDeviceSize imageSize = rgba.size();
700706

0 commit comments

Comments
 (0)