mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-28 19:20:36 +00:00
VFS: fix out of range problem in vfs::unescape
Also improve unescape with "!" allowing any character
This commit is contained in:
parent
0c65a1721d
commit
bf957a575c
@ -438,17 +438,30 @@ std::string vfs::unescape(std::string_view path)
|
|||||||
std::string result;
|
std::string result;
|
||||||
result.reserve(path.size());
|
result.reserve(path.size());
|
||||||
|
|
||||||
|
// Emulate NTS
|
||||||
|
auto get_char = [&](std::size_t pos) -> char2
|
||||||
|
{
|
||||||
|
if (pos < path.size())
|
||||||
|
{
|
||||||
|
return path[pos];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (std::size_t i = 0, s = path.size(); i < s; i++)
|
for (std::size_t i = 0, s = path.size(); i < s; i++)
|
||||||
{
|
{
|
||||||
switch (char2 c = path[i])
|
switch (char2 c = path[i])
|
||||||
{
|
{
|
||||||
case char2{u8"!"[0]}:
|
case char2{u8"!"[0]}:
|
||||||
{
|
{
|
||||||
switch (char2 c2 = path[i + 1])
|
switch (char2 c2 = get_char(i + 1))
|
||||||
{
|
{
|
||||||
case char2{u8"!"[1]}:
|
case char2{u8"!"[1]}:
|
||||||
{
|
{
|
||||||
const uchar c3 = path[i + 2];
|
const uchar c3 = get_char(i + 2);
|
||||||
|
|
||||||
if (c3 >= 0x81 && c3 <= 0xbf)
|
if (c3 >= 0x81 && c3 <= 0xbf)
|
||||||
{
|
{
|
||||||
@ -465,7 +478,7 @@ std::string vfs::unescape(std::string_view path)
|
|||||||
case char2{u8"8"[2]}:
|
case char2{u8"8"[2]}:
|
||||||
case char2{u8"9"[2]}:
|
case char2{u8"9"[2]}:
|
||||||
{
|
{
|
||||||
result += path[i + 2];
|
result += static_cast<char>(c3);
|
||||||
result.back() -= u8"0"[2];
|
result.back() -= u8"0"[2];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -492,15 +505,24 @@ std::string vfs::unescape(std::string_view path)
|
|||||||
case char2{u8"U"[2]}:
|
case char2{u8"U"[2]}:
|
||||||
case char2{u8"V"[2]}:
|
case char2{u8"V"[2]}:
|
||||||
{
|
{
|
||||||
result += path[i + 2];
|
result += static_cast<char>(c3);
|
||||||
result.back() -= u8"A"[2];
|
result.back() -= u8"A"[2];
|
||||||
result.back() += 10;
|
result.back() += 10;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case char2{u8"!"[2]}:
|
case char2{u8"!"[2]}:
|
||||||
{
|
{
|
||||||
|
if (const char2 c4 = get_char(i + 3))
|
||||||
|
{
|
||||||
|
// Escape anything but null character
|
||||||
|
result += c4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
i += 3;
|
i += 3;
|
||||||
result += c;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case char2{u8"."[2]}:
|
case char2{u8"."[2]}:
|
||||||
@ -572,7 +594,7 @@ std::string vfs::unescape(std::string_view path)
|
|||||||
}
|
}
|
||||||
case char2{u8"`"[1]}:
|
case char2{u8"`"[1]}:
|
||||||
{
|
{
|
||||||
const uchar c3 = path[i + 2];
|
const uchar c3 = get_char(i + 2);
|
||||||
|
|
||||||
if (c3 >= 0x80 && c3 <= 0x9e)
|
if (c3 >= 0x80 && c3 <= 0x9e)
|
||||||
{
|
{
|
||||||
@ -607,6 +629,11 @@ std::string vfs::unescape(std::string_view path)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
// NTS detected
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
result += c;
|
result += c;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user