mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-13 03:40:49 +00:00
Fix lv2_fs_object::name
Recreate path from actual decoded components.
This commit is contained in:
parent
5534c9e27c
commit
28fb0d1741
rpcs3/Emu
@ -199,8 +199,9 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
|
||||
if (!path[0])
|
||||
return CELL_ENOENT;
|
||||
|
||||
std::string processed_path;
|
||||
const std::string_view vpath = path.get_ptr();
|
||||
const std::string local_path = vfs::get(vpath);
|
||||
const std::string local_path = vfs::get(vpath, nullptr, &processed_path);
|
||||
|
||||
if (vpath.find_first_not_of('/') == -1)
|
||||
{
|
||||
@ -369,7 +370,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
|
||||
}
|
||||
}
|
||||
|
||||
if (const u32 id = idm::make<lv2_fs_object, lv2_file>(path.get_ptr(), std::move(file), mode, flags))
|
||||
if (const u32 id = idm::make<lv2_fs_object, lv2_file>(processed_path.c_str(), std::move(file), mode, flags))
|
||||
{
|
||||
*fd = id;
|
||||
return CELL_OK;
|
||||
@ -480,9 +481,12 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
|
||||
if (!path[0])
|
||||
return CELL_ENOENT;
|
||||
|
||||
std::string processed_path;
|
||||
std::vector<std::string> ext;
|
||||
const std::string_view vpath = path.get_ptr();
|
||||
const std::string local_path = vfs::get(vpath, &ext);
|
||||
const std::string local_path = vfs::get(vpath, &ext, &processed_path);
|
||||
|
||||
processed_path += "/";
|
||||
|
||||
if (local_path.empty() && ext.empty())
|
||||
{
|
||||
@ -568,7 +572,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
|
||||
|
||||
data.erase(last, data.end());
|
||||
|
||||
if (const u32 id = idm::make<lv2_fs_object, lv2_dir>(path.get_ptr(), std::move(data)))
|
||||
if (const u32 id = idm::make<lv2_fs_object, lv2_dir>(processed_path.c_str(), std::move(data)))
|
||||
{
|
||||
*fd = id;
|
||||
return CELL_OK;
|
||||
|
@ -84,7 +84,7 @@ bool vfs::mount(std::string_view vpath, std::string_view path)
|
||||
}
|
||||
|
||||
// Go back one level
|
||||
list.resize(list.size() - 1);
|
||||
list.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ bool vfs::mount(std::string_view vpath, std::string_view path)
|
||||
}
|
||||
}
|
||||
|
||||
std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir)
|
||||
std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir, std::string* out_path)
|
||||
{
|
||||
const auto table = g_fxo->get<vfs_manager>();
|
||||
|
||||
@ -127,6 +127,14 @@ std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir)
|
||||
vpath = ".";
|
||||
}
|
||||
|
||||
// Fragments for out_path
|
||||
std::vector<std::string_view> name_list;
|
||||
|
||||
if (out_path)
|
||||
{
|
||||
name_list.reserve(vpath.size() / 2);
|
||||
}
|
||||
|
||||
for (std::vector<const vfs_directory*> list{&table->root};;)
|
||||
{
|
||||
// Skip one or more '/'
|
||||
@ -196,14 +204,24 @@ std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir)
|
||||
}
|
||||
|
||||
// Go back one level
|
||||
list.resize(list.size() - 1);
|
||||
result.resize(result.size() - 1);
|
||||
if (out_path)
|
||||
{
|
||||
name_list.pop_back();
|
||||
}
|
||||
|
||||
list.pop_back();
|
||||
result.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto last = list.back();
|
||||
list.push_back(nullptr);
|
||||
|
||||
if (out_path)
|
||||
{
|
||||
name_list.push_back(name);
|
||||
}
|
||||
|
||||
result.push_back(name);
|
||||
|
||||
if (!last)
|
||||
@ -225,6 +243,13 @@ std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir)
|
||||
}
|
||||
|
||||
// Handle /host_root (not escaped, not processed)
|
||||
if (out_path)
|
||||
{
|
||||
*out_path = "/";
|
||||
*out_path += fmt::merge(name_list, "/");
|
||||
*out_path += vpath;
|
||||
}
|
||||
|
||||
return std::string{vpath.substr(1)};
|
||||
}
|
||||
|
||||
@ -240,6 +265,12 @@ std::string vfs::get(std::string_view vpath, std::vector<std::string>* out_dir)
|
||||
}
|
||||
|
||||
// Escape and merge path fragments
|
||||
if (out_path)
|
||||
{
|
||||
*out_path = "/";
|
||||
*out_path += fmt::merge(name_list, "/");
|
||||
}
|
||||
|
||||
return std::string{result_base} + vfs::escape(fmt::merge(result, "/"));
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace vfs
|
||||
bool mount(std::string_view vpath, std::string_view path);
|
||||
|
||||
// Convert VFS path to fs path, optionally listing directories mounted in it
|
||||
std::string get(std::string_view vpath, std::vector<std::string>* out_dir = nullptr);
|
||||
std::string get(std::string_view vpath, std::vector<std::string>* out_dir = nullptr, std::string* out_path = nullptr);
|
||||
|
||||
// Escape VFS path by replacing non-portable characters with surrogates
|
||||
std::string escape(std::string_view path, bool escape_slash = false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user