mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-06 13:30:00 +00:00
Merge pull request #15039 from MarcZX10/fix/p15-ngs2-waveform-bounds
fix(libSceNgs2): reject ATRAC9 data chunks larger than the buffer
This commit is contained in:
2 files changed
+15
-3
No files matched your search
@@ -413,9 +413,10 @@ static int ParseAtrac9Loop(const RiffChunks& chunks, Ngs2WaveformInfo& info) {
|
||||
return SCE_NGS2_OK;
|
||||
}
|
||||
|
||||
static int ParseAtrac9(const RiffChunks& chunks, Ngs2WaveformInfo& info) {
|
||||
static int ParseAtrac9(const RiffChunks& chunks, std::size_t size, Ngs2WaveformInfo& info) {
|
||||
const auto* format = chunks.format;
|
||||
if (chunks.formatSize < FMT_ATRAC9_SIZE || chunks.fact == nullptr || chunks.factSize < FACT_ATRAC9_SIZE) return SCE_NGS2_ERROR_INVALID_WAVEFORM_FORMAT;
|
||||
if (chunks.dataSize > size - chunks.dataOffset) return SCE_NGS2_ERROR_INVALID_WAVEFORM_DATA;
|
||||
std::uint8_t config[4];
|
||||
std::memcpy(config, format + FMT_CONFIG_OFFSET, sizeof(config));
|
||||
Atrac9CodecInfo codec{};
|
||||
@@ -507,7 +508,7 @@ static int ParseWaveform(const RiffChunks& chunks, std::size_t size, Ngs2Wavefor
|
||||
if (chunks.formatSize < FMT_EXTENSIBLE_SIZE) return SCE_NGS2_ERROR_UNKNOWN_WAVEFORM_FORMAT;
|
||||
const auto* guid = chunks.format + FMT_GUID_OFFSET;
|
||||
if (std::memcmp(guid, PCM_GUID, sizeof(PCM_GUID)) == 0) return ParsePcm(chunks, size, info, false);
|
||||
if (std::memcmp(guid, ATRAC9_GUID, sizeof(ATRAC9_GUID)) == 0) return ParseAtrac9(chunks, info);
|
||||
if (std::memcmp(guid, ATRAC9_GUID, sizeof(ATRAC9_GUID)) == 0) return ParseAtrac9(chunks, size, info);
|
||||
if (chunks.formatSize == FMT_ATRAC9_SIZE) throw std::runtime_error("NGS2: parsing an extensible waveform of format size 0x34 without the ATRAC9 GUID is not implemented");
|
||||
if (std::memcmp(guid, TYPE_43_GUID, sizeof(TYPE_43_GUID)) == 0) throw std::runtime_error("NGS2: parsing waveform type 0x43 is not implemented");
|
||||
return SCE_NGS2_ERROR_UNKNOWN_WAVEFORM_FORMAT;
|
||||
|
||||
@@ -376,7 +376,7 @@ static void TestParseLoops() {
|
||||
}
|
||||
const auto file = LoopedFile(100, 700, 0);
|
||||
Ngs2WaveformInfo info{};
|
||||
Require(sceNgs2ParseWaveformData(file.data(), 168, &info) == SCE_NGS2_OK);
|
||||
Require(sceNgs2ParseWaveformData(file.data(), file.size(), &info) == SCE_NGS2_OK);
|
||||
Require(info.block[1].num_repeats == UINT32_MAX);
|
||||
const auto system = CreateSystem();
|
||||
const auto voice = Voice(CreateRack(system, SCE_NGS2_RACK_ID_SAMPLER));
|
||||
@@ -743,6 +743,16 @@ static void TestStreamingReplay() {
|
||||
}
|
||||
}
|
||||
|
||||
static void TestDataChunkBeyondBuffer() {
|
||||
const auto file = At9File(48000);
|
||||
Ngs2WaveformInfo info{};
|
||||
Require(sceNgs2ParseWaveformData(file.data(), file.size(), &info) == SCE_NGS2_OK && info.data_size == SuperframeBytes);
|
||||
auto truncated = file;
|
||||
Set32(truncated, 4, static_cast<std::uint32_t>(truncated.size() - 8 + 16));
|
||||
Set32(truncated, 96, SuperframeBytes + 16);
|
||||
Require(sceNgs2ParseWaveformData(truncated.data(), truncated.size(), &info) == SCE_NGS2_ERROR_INVALID_WAVEFORM_DATA);
|
||||
}
|
||||
|
||||
int main() {
|
||||
const auto reference = Reference();
|
||||
TestSkipAndBlockEnd(reference);
|
||||
@@ -764,5 +774,6 @@ int main() {
|
||||
TestBlockOnEmptyAtrac9Voice();
|
||||
TestEmptyAddsCloseLikePcm();
|
||||
TestSilenceFlagRejected();
|
||||
TestDataChunkBeyondBuffer();
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user