From 1feefabeba24fa249c8fc3d320a9becdd4f9bced Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 4 Jun 2021 03:35:13 -0400 Subject: [PATCH 1/2] decoders: Avoid out-of-bounds access This is not a real fix, so assert here and continue before crashing. --- src/video_core/textures/decoders.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 3a463d5db6..1bccc09d95 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -63,6 +63,14 @@ void Swizzle(std::span output, std::span input, u32 bytes_per_pixe const u32 unswizzled_offset = slice * pitch * height + line * pitch + column * bytes_per_pixel; + if (const auto offset = (TO_LINEAR ? unswizzled_offset : swizzled_offset); + offset >= input.size()) { + // TODO(Rodrigo): This is an out of bounds access that should never happen. To + // avoid crashing the emulator, continue. + ASSERT_MSG(false, "offset {} exceeds input size {}!", offset, input.size()); + continue; + } + u8* const dst = &output[TO_LINEAR ? swizzled_offset : unswizzled_offset]; const u8* const src = &input[TO_LINEAR ? unswizzled_offset : swizzled_offset]; std::memcpy(dst, src, bytes_per_pixel); From 287a0f72a5474a5c8c8cdf2b15fb61532e11ec61 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 4 Jun 2021 05:12:14 -0400 Subject: [PATCH 2/2] decoders: Break instead of continue continue causes a memory leak in A Hat in Time. --- src/video_core/textures/decoders.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 1bccc09d95..f1f523ad10 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -66,9 +66,9 @@ void Swizzle(std::span output, std::span input, u32 bytes_per_pixe if (const auto offset = (TO_LINEAR ? unswizzled_offset : swizzled_offset); offset >= input.size()) { // TODO(Rodrigo): This is an out of bounds access that should never happen. To - // avoid crashing the emulator, continue. + // avoid crashing the emulator, break. ASSERT_MSG(false, "offset {} exceeds input size {}!", offset, input.size()); - continue; + break; } u8* const dst = &output[TO_LINEAR ? swizzled_offset : unswizzled_offset];