From 65eb11cb56ec5425cdbab7a7536b168a82e4b815 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya0@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:30:20 -0400 Subject: Fix three Windows-only defects in OoT extraction (#234) --- src/Companion.cpp | 9 +++++---- src/Companion.h | 2 +- src/factories/oot/OoTAudioFactory.cpp | 33 +++++++++++++++++++++++++-------- src/factories/oot/OoTAudioFactory.h | 4 ++-- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/Companion.cpp b/src/Companion.cpp index 74d6ec1..bb58dcf 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -536,7 +536,7 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic& ass auto externalFile = externalFiles[i]; if (externalFile.size() == 0) { this->gCurrentExternalFiles.push_back( - (this->gSourceDirectory / externalFile.as()).string()); + (this->gSourceDirectory / externalFile.as()).generic_string()); } else { SPDLOG_INFO("External File size {}", externalFile.size()); throw std::runtime_error( @@ -544,9 +544,10 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic& ass " - \n\ne.g.:\nexternal_files:\n - actors/actor1.yaml"); } - std::string externalFileName = (this->gSourceDirectory / externalFile.as()).string(); - if (StringHelper::StartsWith(std::filesystem::relative(externalFileName, this->gAssetPath).string(), - "../")) { + std::string externalFileName = + (this->gSourceDirectory / externalFile.as()).generic_string(); + if (StringHelper::StartsWith( + std::filesystem::relative(externalFileName, this->gAssetPath).generic_string(), "../")) { throw std::runtime_error("External File " + externalFileName + " Not In Asset Directory " + this->gAssetPath); } else if (std::filesystem::relative(externalFileName, this->gAssetPath).string() == "") { diff --git a/src/Companion.h b/src/Companion.h index 2b28a8e..5bdfb49 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -248,7 +248,7 @@ public: std::optional> RegisterAsset(const std::string& name, YAML::Node& node); std::optional AddSubFileAsset(YAML::Node asset, std::string newFileName, CompressionType newCompressionType, uint32_t compressedSize = 0); std::optional AddAsset(YAML::Node asset); - std::string GetCurrentDirectory() const { return gCurrentDirectory.string(); } + std::string GetCurrentDirectory() const { return gCurrentDirectory.generic_string(); } void SetCompressedSegment(uint32_t segmentId, uint32_t compressedFileOffset, uint32_t offset); bool GetCompressedSegmentOffset(uint32_t* addr); diff --git a/src/factories/oot/OoTAudioFactory.cpp b/src/factories/oot/OoTAudioFactory.cpp index f4b1d6d..2c0465d 100644 --- a/src/factories/oot/OoTAudioFactory.cpp +++ b/src/factories/oot/OoTAudioFactory.cpp @@ -5,12 +5,23 @@ #include "spdlog/spdlog.h" #include "Companion.h" #include "utils/Decompressor.h" +#include #include namespace OoT { -std::vector OoTAudioFactory::ParseAudioTable(const uint8_t* codeData, uint32_t tableOffset) { - LUS::BinaryReader reader((char*)(codeData + tableOffset), 0x10000); +// BinaryReader copies its whole window up front, so the window must not run past the segment. +static size_t TableWindow(size_t segmentSize, uint32_t tableOffset) { + if (tableOffset >= segmentSize) { + throw std::runtime_error("Audio table offset 0x" + fmt::format("{:X}", tableOffset) + + " is outside the 0x" + fmt::format("{:X}", segmentSize) + " byte code segment"); + } + return std::min(segmentSize - tableOffset, 0x10000); +} + +std::vector OoTAudioFactory::ParseAudioTable(const uint8_t* codeData, size_t segmentSize, + uint32_t tableOffset) { + LUS::BinaryReader reader((char*)(codeData + tableOffset), TableWindow(segmentSize, tableOffset)); reader.SetEndianness(Torch::Endianness::Big); uint16_t numEntries = reader.ReadUInt16(); @@ -36,11 +47,11 @@ std::vector OoTAudioFactory::ParseAudioTable(const uint8_t* cod } std::vector> OoTAudioFactory::ParseSequenceFontTable( - const uint8_t* codeData, uint32_t tableOffset, uint32_t numSequences) { + const uint8_t* codeData, size_t segmentSize, uint32_t tableOffset, uint32_t numSequences) { std::vector> result; result.reserve(numSequences); - LUS::BinaryReader reader((char*)(codeData + tableOffset), 0x10000); + LUS::BinaryReader reader((char*)(codeData + tableOffset), TableWindow(segmentSize, tableOffset)); reader.SetEndianness(Torch::Endianness::Big); std::vector offsets; @@ -92,10 +103,16 @@ std::optional> OoTAudioFactory::parse(std::vector(node, "sequence_table_offset")); - auto fontTable = ParseAudioTable(codeDecoded.segment.data, GetSafeNode(node, "sound_font_table_offset")); - auto sampleBankTable = ParseAudioTable(codeDecoded.segment.data, GetSafeNode(node, "sample_bank_table_offset")); - auto seqFontMap = ParseSequenceFontTable(codeDecoded.segment.data, GetSafeNode(node, "sequence_font_table_offset"), seqTable.size()); + const size_t codeSize = codeDecoded.segment.size; + auto seqTable = + ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode(node, "sequence_table_offset")); + auto fontTable = + ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode(node, "sound_font_table_offset")); + auto sampleBankTable = + ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode(node, "sample_bank_table_offset")); + auto seqFontMap = ParseSequenceFontTable(codeDecoded.segment.data, codeSize, + GetSafeNode(node, "sequence_font_table_offset"), + seqTable.size()); SPDLOG_INFO("OoTAudioFactory: {} sequences, {} fonts, {} sample banks", seqTable.size(), fontTable.size(), sampleBankTable.size()); diff --git a/src/factories/oot/OoTAudioFactory.h b/src/factories/oot/OoTAudioFactory.h index 376a761..31a83e8 100644 --- a/src/factories/oot/OoTAudioFactory.h +++ b/src/factories/oot/OoTAudioFactory.h @@ -26,8 +26,8 @@ public: private: std::vector BuildMainAudioHeader(); std::optional LoadAudioBank(std::vector& buffer); - std::vector ParseAudioTable(const uint8_t* codeData, uint32_t tableOffset); - std::vector> ParseSequenceFontTable(const uint8_t* codeData, + std::vector ParseAudioTable(const uint8_t* codeData, size_t segmentSize, uint32_t tableOffset); + std::vector> ParseSequenceFontTable(const uint8_t* codeData, size_t segmentSize, uint32_t tableOffset, uint32_t numSequences); }; -- cgit v1.2.3