fix(bps): Fixes BPS patch changing target size (#5829)

This commit is contained in:
fadillzzz 2021-08-23 03:24:35 +07:00 committed by GitHub
parent c40871f126
commit 89410c164a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -63,6 +63,7 @@ namespace Bps {
// Realistically uint32s are more than enough for code patching. // Realistically uint32s are more than enough for code patching.
using Number = u32; using Number = u32;
constexpr std::size_t MagicSize = 4;
constexpr std::size_t FooterSize = 12; constexpr std::size_t FooterSize = 12;
// The BPS format uses CRC32 checksums. // The BPS format uses CRC32 checksums.
@ -149,7 +150,7 @@ public:
: m_source{source}, m_target{target}, m_patch{patch} {} : m_source{source}, m_target{target}, m_patch{patch} {}
bool Apply() { bool Apply() {
const auto magic = *m_patch.Read<std::array<char, 4>>(); const auto magic = *m_patch.Read<std::array<char, MagicSize>>();
if (std::string_view(magic.data(), magic.size()) != "BPS1") { if (std::string_view(magic.data(), magic.size()) != "BPS1") {
LOG_ERROR(Service_FS, "Invalid BPS magic"); LOG_ERROR(Service_FS, "Invalid BPS magic");
return false; return false;
@ -257,10 +258,24 @@ private:
} // namespace Bps } // namespace Bps
bool ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer) { bool ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer) {
Bps::Stream patch_stream{patch.data(), patch.size()};
// Move the offset past the file format marker (i.e. "BPS1")
patch_stream.Seek(Bps::MagicSize);
const Bps::Number source_size = patch_stream.ReadNumber();
const Bps::Number target_size = patch_stream.ReadNumber();
if (target_size > source_size) {
LOG_INFO(Service_FS, "Resizing target to {}", target_size);
buffer.resize(target_size);
}
patch_stream.Seek(0);
const std::vector<u8> source = buffer; const std::vector<u8> source = buffer;
Bps::Stream source_stream{source.data(), source.size()}; Bps::Stream source_stream{source.data(), source.size()};
Bps::Stream target_stream{buffer.data(), buffer.size()}; Bps::Stream target_stream{buffer.data(), buffer.size()};
Bps::Stream patch_stream{patch.data(), patch.size()};
Bps::PatchApplier applier{source_stream, target_stream, patch_stream}; Bps::PatchApplier applier{source_stream, target_stream, patch_stream};
return applier.Apply(); return applier.Apply();
} }