From 02f5316562bb56c0a687948d19b0b13269614b9d Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 31 Aug 2024 18:15:13 +0200 Subject: [PATCH] [VFS] Fixed crash on filename extraction from path. Names are in CP1252 which fails conversion to utf8. --- src/xenia/vfs/devices/disc_image_device.cc | 2 +- src/xenia/vfs/devices/disc_image_entry.cc | 8 +++++--- src/xenia/vfs/devices/disc_image_entry.h | 2 +- src/xenia/vfs/devices/disc_zarchive_device.cc | 8 +++++--- src/xenia/vfs/devices/disc_zarchive_entry.cc | 7 ++++--- src/xenia/vfs/devices/disc_zarchive_entry.h | 3 ++- src/xenia/vfs/devices/host_path_device.cc | 2 +- src/xenia/vfs/devices/host_path_entry.cc | 6 ++++-- src/xenia/vfs/devices/host_path_entry.h | 1 + src/xenia/vfs/devices/null_device.cc | 2 +- src/xenia/vfs/devices/null_entry.cc | 7 ++++--- src/xenia/vfs/devices/null_entry.h | 3 ++- src/xenia/vfs/devices/xcontent_container_entry.cc | 7 ++++--- src/xenia/vfs/devices/xcontent_container_entry.h | 3 ++- .../vfs/devices/xcontent_devices/stfs_container_device.cc | 2 +- .../vfs/devices/xcontent_devices/svod_container_device.cc | 2 +- src/xenia/vfs/entry.cc | 5 +++-- src/xenia/vfs/entry.h | 3 ++- 18 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/xenia/vfs/devices/disc_image_device.cc b/src/xenia/vfs/devices/disc_image_device.cc index 69f84a476..ef8800a03 100644 --- a/src/xenia/vfs/devices/disc_image_device.cc +++ b/src/xenia/vfs/devices/disc_image_device.cc @@ -112,7 +112,7 @@ bool DiscImageDevice::VerifyMagic(ParseState* state, size_t offset) { DiscImageDevice::Error DiscImageDevice::ReadAllEntries( ParseState* state, const uint8_t* root_buffer) { - auto root_entry = new DiscImageEntry(this, nullptr, "", mmap_.get()); + auto root_entry = new DiscImageEntry(this, nullptr, "", "", mmap_.get()); root_entry->attributes_ = kFileAttributeDirectory; root_entry_ = std::unique_ptr(root_entry); diff --git a/src/xenia/vfs/devices/disc_image_entry.cc b/src/xenia/vfs/devices/disc_image_entry.cc index 0d251dff5..80ecf95b0 100644 --- a/src/xenia/vfs/devices/disc_image_entry.cc +++ b/src/xenia/vfs/devices/disc_image_entry.cc @@ -18,8 +18,9 @@ namespace xe { namespace vfs { DiscImageEntry::DiscImageEntry(Device* device, Entry* parent, - const std::string_view path, MappedMemory* mmap) - : Entry(device, parent, path), + const std::string_view path, + const std::string_view name, MappedMemory* mmap) + : Entry(device, parent, path, name), mmap_(mmap), data_offset_(0), data_size_(0) {} @@ -30,7 +31,8 @@ std::unique_ptr DiscImageEntry::Create( Device* device, Entry* parent, const std::string_view name, MappedMemory* mmap) { auto path = xe::utf8::join_guest_paths(parent->path(), name); - auto entry = std::make_unique(device, parent, path, mmap); + auto entry = + std::make_unique(device, parent, path, name, mmap); return std::move(entry); } diff --git a/src/xenia/vfs/devices/disc_image_entry.h b/src/xenia/vfs/devices/disc_image_entry.h index f955e345f..b5bf5a675 100644 --- a/src/xenia/vfs/devices/disc_image_entry.h +++ b/src/xenia/vfs/devices/disc_image_entry.h @@ -24,7 +24,7 @@ class DiscImageDevice; class DiscImageEntry : public Entry { public: DiscImageEntry(Device* device, Entry* parent, const std::string_view path, - MappedMemory* mmap); + const std::string_view name, MappedMemory* mmap); ~DiscImageEntry() override; static std::unique_ptr Create(Device* device, Entry* parent, diff --git a/src/xenia/vfs/devices/disc_zarchive_device.cc b/src/xenia/vfs/devices/disc_zarchive_device.cc index 0f81e4bdd..14da08b19 100644 --- a/src/xenia/vfs/devices/disc_zarchive_device.cc +++ b/src/xenia/vfs/devices/disc_zarchive_device.cc @@ -36,7 +36,7 @@ bool DiscZarchiveDevice::Initialize() { const std::string root_path = std::string("/"); const ZArchiveNodeHandle handle = reader_->LookUp(root_path); - auto root_entry = new DiscZarchiveEntry(this, nullptr, root_path); + auto root_entry = new DiscZarchiveEntry(this, nullptr, root_path, ""); root_entry->attributes_ = kFileAttributeDirectory; root_entry->handle_ = static_cast(handle); root_entry->name_ = root_path; @@ -79,7 +79,8 @@ bool DiscZarchiveDevice::ReadAllEntries(const std::string& path, } if (reader_->IsFile(handle)) { - auto entry = new DiscZarchiveEntry(this, parent, path); + auto entry = new DiscZarchiveEntry( + this, parent, path, xe::utf8::find_name_from_guest_path(path)); entry->attributes_ = kFileAttributeReadOnly; entry->handle_ = static_cast(handle); entry->parent_ = parent; @@ -103,7 +104,8 @@ bool DiscZarchiveDevice::ReadAllEntries(const std::string& path, return false; } - auto entry = new DiscZarchiveEntry(this, parent, full_path); + auto entry = + new DiscZarchiveEntry(this, parent, full_path, dirEntry.name); entry->handle_ = static_cast(fileHandle); entry->data_offset_ = 0; diff --git a/src/xenia/vfs/devices/disc_zarchive_entry.cc b/src/xenia/vfs/devices/disc_zarchive_entry.cc index 828ab597c..6a874bf82 100644 --- a/src/xenia/vfs/devices/disc_zarchive_entry.cc +++ b/src/xenia/vfs/devices/disc_zarchive_entry.cc @@ -20,8 +20,9 @@ namespace xe { namespace vfs { DiscZarchiveEntry::DiscZarchiveEntry(Device* device, Entry* parent, - const std::string_view path) - : Entry(device, parent, path), + const std::string_view path, + const std::string_view name) + : Entry(device, parent, path, name), data_offset_(0), data_size_(0), handle_(ZARCHIVE_INVALID_NODE) {} @@ -31,7 +32,7 @@ DiscZarchiveEntry::~DiscZarchiveEntry() = default; std::unique_ptr DiscZarchiveEntry::Create( Device* device, Entry* parent, const std::string_view name) { auto path = name; // xe::utf8::join_guest_paths(parent->path(), name); - auto entry = std::make_unique(device, parent, path); + auto entry = std::make_unique(device, parent, path, name); return std::move(entry); } diff --git a/src/xenia/vfs/devices/disc_zarchive_entry.h b/src/xenia/vfs/devices/disc_zarchive_entry.h index 3b01b25a9..5fcf9b319 100644 --- a/src/xenia/vfs/devices/disc_zarchive_entry.h +++ b/src/xenia/vfs/devices/disc_zarchive_entry.h @@ -23,7 +23,8 @@ class DiscZarchiveDevice; class DiscZarchiveEntry : public Entry { public: - DiscZarchiveEntry(Device* device, Entry* parent, const std::string_view path); + DiscZarchiveEntry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name); ~DiscZarchiveEntry() override; static std::unique_ptr Create(Device* device, diff --git a/src/xenia/vfs/devices/host_path_device.cc b/src/xenia/vfs/devices/host_path_device.cc index 33aee1b7a..20b4b5cb0 100644 --- a/src/xenia/vfs/devices/host_path_device.cc +++ b/src/xenia/vfs/devices/host_path_device.cc @@ -39,7 +39,7 @@ bool HostPathDevice::Initialize() { } } - auto root_entry = new HostPathEntry(this, nullptr, "", host_path_); + auto root_entry = new HostPathEntry(this, nullptr, "", "", host_path_); root_entry->attributes_ = kFileAttributeDirectory; root_entry_ = std::unique_ptr(root_entry); PopulateEntry(root_entry); diff --git a/src/xenia/vfs/devices/host_path_entry.cc b/src/xenia/vfs/devices/host_path_entry.cc index dbc554fa9..6d5725c84 100644 --- a/src/xenia/vfs/devices/host_path_entry.cc +++ b/src/xenia/vfs/devices/host_path_entry.cc @@ -23,8 +23,9 @@ namespace vfs { HostPathEntry::HostPathEntry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name, const std::filesystem::path& host_path) - : Entry(device, parent, path), host_path_(host_path) {} + : Entry(device, parent, path, name), host_path_(host_path) {} HostPathEntry::~HostPathEntry() = default; @@ -33,7 +34,8 @@ HostPathEntry* HostPathEntry::Create(Device* device, Entry* parent, xe::filesystem::FileInfo file_info) { auto path = xe::utf8::join_guest_paths(parent->path(), xe::path_to_utf8(file_info.name)); - auto entry = new HostPathEntry(device, parent, path, full_path); + auto entry = new HostPathEntry(device, parent, path, + xe::path_to_utf8(file_info.name), full_path); entry->create_timestamp_ = file_info.create_timestamp; entry->access_timestamp_ = file_info.access_timestamp; diff --git a/src/xenia/vfs/devices/host_path_entry.h b/src/xenia/vfs/devices/host_path_entry.h index 85ce94d8b..f93b494e7 100644 --- a/src/xenia/vfs/devices/host_path_entry.h +++ b/src/xenia/vfs/devices/host_path_entry.h @@ -23,6 +23,7 @@ class HostPathDevice; class HostPathEntry : public Entry { public: HostPathEntry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name, const std::filesystem::path& host_path); ~HostPathEntry() override; diff --git a/src/xenia/vfs/devices/null_device.cc b/src/xenia/vfs/devices/null_device.cc index 79490376b..ab53d70f6 100644 --- a/src/xenia/vfs/devices/null_device.cc +++ b/src/xenia/vfs/devices/null_device.cc @@ -26,7 +26,7 @@ NullDevice::NullDevice(const std::string& mount_path, NullDevice::~NullDevice() = default; bool NullDevice::Initialize() { - auto root_entry = new NullEntry(this, nullptr, mount_path_); + auto root_entry = new NullEntry(this, nullptr, mount_path_, ""); root_entry->attributes_ = kFileAttributeDirectory; root_entry_ = std::unique_ptr(root_entry); diff --git a/src/xenia/vfs/devices/null_entry.cc b/src/xenia/vfs/devices/null_entry.cc index 45b511c40..7a751c948 100644 --- a/src/xenia/vfs/devices/null_entry.cc +++ b/src/xenia/vfs/devices/null_entry.cc @@ -20,14 +20,15 @@ namespace xe { namespace vfs { -NullEntry::NullEntry(Device* device, Entry* parent, std::string path) - : Entry(device, parent, path) {} +NullEntry::NullEntry(Device* device, Entry* parent, std::string path, + const std::string_view name) + : Entry(device, parent, path, name) {} NullEntry::~NullEntry() = default; NullEntry* NullEntry::Create(Device* device, Entry* parent, const std::string& path) { - auto entry = new NullEntry(device, parent, path); + auto entry = new NullEntry(device, parent, path, ""); entry->create_timestamp_ = 0; entry->access_timestamp_ = 0; diff --git a/src/xenia/vfs/devices/null_entry.h b/src/xenia/vfs/devices/null_entry.h index 84f01cb95..2efcd5b91 100644 --- a/src/xenia/vfs/devices/null_entry.h +++ b/src/xenia/vfs/devices/null_entry.h @@ -22,7 +22,8 @@ class NullDevice; class NullEntry : public Entry { public: - NullEntry(Device* device, Entry* parent, std::string path); + NullEntry(Device* device, Entry* parent, std::string path, + const std::string_view name); ~NullEntry() override; static NullEntry* Create(Device* device, Entry* parent, diff --git a/src/xenia/vfs/devices/xcontent_container_entry.cc b/src/xenia/vfs/devices/xcontent_container_entry.cc index 1f264dfec..eecfce4d2 100644 --- a/src/xenia/vfs/devices/xcontent_container_entry.cc +++ b/src/xenia/vfs/devices/xcontent_container_entry.cc @@ -17,8 +17,9 @@ namespace vfs { XContentContainerEntry::XContentContainerEntry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name, MultiFileHandles* files) - : Entry(device, parent, path), + : Entry(device, parent, path, name), files_(files), data_offset_(0), data_size_(0), @@ -30,8 +31,8 @@ std::unique_ptr XContentContainerEntry::Create( Device* device, Entry* parent, const std::string_view name, MultiFileHandles* files) { auto path = xe::utf8::join_guest_paths(parent->path(), name); - auto entry = - std::make_unique(device, parent, path, files); + auto entry = std::make_unique(device, parent, path, + name, files); return std::move(entry); } diff --git a/src/xenia/vfs/devices/xcontent_container_entry.h b/src/xenia/vfs/devices/xcontent_container_entry.h index 8022a088a..93238bc97 100644 --- a/src/xenia/vfs/devices/xcontent_container_entry.h +++ b/src/xenia/vfs/devices/xcontent_container_entry.h @@ -26,7 +26,8 @@ class XContentContainerDevice; class XContentContainerEntry : public Entry { public: XContentContainerEntry(Device* device, Entry* parent, - const std::string_view path, MultiFileHandles* files); + const std::string_view path, + const std::string_view name, MultiFileHandles* files); ~XContentContainerEntry() override; static std::unique_ptr Create( diff --git a/src/xenia/vfs/devices/xcontent_devices/stfs_container_device.cc b/src/xenia/vfs/devices/xcontent_devices/stfs_container_device.cc index 7a37807d2..417f05414 100644 --- a/src/xenia/vfs/devices/xcontent_devices/stfs_container_device.cc +++ b/src/xenia/vfs/devices/xcontent_devices/stfs_container_device.cc @@ -53,7 +53,7 @@ XContentContainerDevice::Result StfsContainerDevice::LoadHostFiles( StfsContainerDevice::Result StfsContainerDevice::Read() { auto& file = files_.at(0); - auto root_entry = new XContentContainerEntry(this, nullptr, "", &files_); + auto root_entry = new XContentContainerEntry(this, nullptr, "", "", &files_); root_entry->attributes_ = kFileAttributeDirectory; root_entry_ = std::unique_ptr(root_entry); diff --git a/src/xenia/vfs/devices/xcontent_devices/svod_container_device.cc b/src/xenia/vfs/devices/xcontent_devices/svod_container_device.cc index 369ecf10d..21b367cc8 100644 --- a/src/xenia/vfs/devices/xcontent_devices/svod_container_device.cc +++ b/src/xenia/vfs/devices/xcontent_devices/svod_container_device.cc @@ -99,7 +99,7 @@ XContentContainerDevice::Result SvodContainerDevice::Read() { const uint64_t root_creation_timestamp = decode_fat_timestamp(root_data.creation_date, root_data.creation_time); - auto root_entry = new XContentContainerEntry(this, nullptr, "", &files_); + auto root_entry = new XContentContainerEntry(this, nullptr, "", "", &files_); root_entry->attributes_ = kFileAttributeDirectory; root_entry->access_timestamp_ = root_creation_timestamp; root_entry->create_timestamp_ = root_creation_timestamp; diff --git a/src/xenia/vfs/entry.cc b/src/xenia/vfs/entry.cc index da2a7b939..4d1ec00e4 100644 --- a/src/xenia/vfs/entry.cc +++ b/src/xenia/vfs/entry.cc @@ -16,10 +16,12 @@ namespace xe { namespace vfs { -Entry::Entry(Device* device, Entry* parent, const std::string_view path) +Entry::Entry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name) : device_(device), parent_(parent), path_(path), + name_(name), attributes_(0), size_(0), allocation_size_(0), @@ -29,7 +31,6 @@ Entry::Entry(Device* device, Entry* parent, const std::string_view path) delete_on_close_(false) { assert_not_null(device); absolute_path_ = xe::utf8::join_guest_paths(device->mount_path(), path); - name_ = xe::utf8::find_name_from_guest_path(path); } Entry::~Entry() = default; diff --git a/src/xenia/vfs/entry.h b/src/xenia/vfs/entry.h index 3b80c25cb..b0bf33857 100644 --- a/src/xenia/vfs/entry.h +++ b/src/xenia/vfs/entry.h @@ -134,7 +134,8 @@ class Entry { virtual void update() { return; } protected: - Entry(Device* device, Entry* parent, const std::string_view path); + Entry(Device* device, Entry* parent, const std::string_view path, + const std::string_view name); virtual std::unique_ptr CreateEntryInternal( const std::string_view name, uint32_t attributes) {