mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
The VOP1, VOP2 and VOPC SDWA and DPP decoders read the modifier word at wordIndex + 1 before SetRdnaRawWords checked that it exists, so a code span ending at such an instruction was read one word past its end. AddressSanitizer reports a heap-buffer-overflow in decodeVop2Sdwa on a synthetic program. The six decoders now throw "truncated <encoding> instruction" first, as DecodeRdnaVop3 and DecodeRdnaVop3p already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
41 lines
1.2 KiB
C++
41 lines
1.2 KiB
C++
#include "RdnaDecoder/RdnaInstructionDecoder.hpp"
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <span>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
using namespace ShaderRecompiler;
|
|
|
|
int main() {
|
|
struct Case {
|
|
const char* name;
|
|
std::uint32_t word;
|
|
};
|
|
const std::array<Case, 6> cases{{
|
|
{"VOP1 SDWA", 0x7e0202f9u},
|
|
{"VOP1 DPP", 0x7e0202fau},
|
|
{"VOP2 SDWA", 0x4a0202f9u},
|
|
{"VOP2 DPP", 0x4a0202fau},
|
|
{"VOPC SDWA", 0x7c0202f9u},
|
|
{"VOPC DPP", 0x7c0202fau},
|
|
}};
|
|
int failures = 0;
|
|
for (const auto& entry : cases) {
|
|
const std::array<std::uint32_t, 2> words{entry.word, 0xaf00e400u};
|
|
const std::string expected = std::string("truncated ") + entry.name + " instruction";
|
|
try {
|
|
static_cast<void>(RdnaInstructionDecoder{}.Decode(std::span(words).first(1)));
|
|
std::fprintf(stderr, "%s: a missing modifier word decodes\n", entry.name);
|
|
++failures;
|
|
} catch (const std::out_of_range& error) {
|
|
if (expected != error.what()) {
|
|
std::fprintf(stderr, "%s: %s\n", entry.name, error.what());
|
|
++failures;
|
|
}
|
|
}
|
|
}
|
|
return failures == 0 ? 0 : 1;
|
|
}
|