[VFS] Fixed crash on filename extraction from path.

Names are in CP1252 which fails conversion to utf8.
This commit is contained in:
Gliniak 2024-08-31 18:15:13 +02:00
parent 59eed7818f
commit 02f5316562
18 changed files with 44 additions and 29 deletions

View File

@ -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<Entry>(root_entry);

View File

@ -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> 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<DiscImageEntry>(device, parent, path, mmap);
auto entry =
std::make_unique<DiscImageEntry>(device, parent, path, name, mmap);
return std::move(entry);
}

View File

@ -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<DiscImageEntry> Create(Device* device, Entry* parent,

View File

@ -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<uint32_t>(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<uint32_t>(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<uint32_t>(fileHandle);
entry->data_offset_ = 0;

View File

@ -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> 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<DiscZarchiveEntry>(device, parent, path);
auto entry = std::make_unique<DiscZarchiveEntry>(device, parent, path, name);
return std::move(entry);
}

View File

@ -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<DiscZarchiveEntry> Create(Device* device,

View File

@ -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<Entry>(root_entry);
PopulateEntry(root_entry);

View File

@ -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;

View File

@ -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;

View File

@ -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<Entry>(root_entry);

View File

@ -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;

View File

@ -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,

View File

@ -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> 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<XContentContainerEntry>(device, parent, path, files);
auto entry = std::make_unique<XContentContainerEntry>(device, parent, path,
name, files);
return std::move(entry);
}

View File

@ -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<XContentContainerEntry> Create(

View File

@ -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<Entry>(root_entry);

View File

@ -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;

View File

@ -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;

View File

@ -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<Entry> CreateEntryInternal(
const std::string_view name, uint32_t attributes) {