mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
0c255e0f49
- Updates path handling code to system version 11.0.0. - Changes InMemoryFileSystem to normalize all incoming paths.
327 lines
No EOL
14 KiB
C++
327 lines
No EOL
14 KiB
C++
// Uses GLoat to run code in nnsdk https://github.com/h1k421/GLoat
|
|
#include <gloat.hpp>
|
|
|
|
static char Buf[0x80000];
|
|
static int BufPos = 0;
|
|
|
|
static char ResultNameBuf[0x100];
|
|
|
|
namespace nn::fs::detail {
|
|
bool IsEnabledAccessLog();
|
|
}
|
|
|
|
namespace nn::fs::PathTool {
|
|
// SDK < 7
|
|
nn::Result Normalize(char* buffer, uint64_t* outNormalizedPathLength, const char* path, uint64_t bufferLength, bool preserveUnc);
|
|
nn::Result IsNormalized(bool* outIsNormalized, const char* path);
|
|
|
|
// SDK >= 7 < 11
|
|
nn::Result Normalize(char* buffer, uint64_t* outNormalizedPathLength, const char* path, uint64_t bufferLength, bool preserveUnc, bool hasMountName);
|
|
nn::Result IsNormalized(bool* outIsNormalized, const char* path, bool preserveUnc, bool hasMountName);
|
|
|
|
bool IsSubpath(const char* path1, const char* path2);
|
|
}
|
|
|
|
namespace nn::fs {
|
|
// SDK >= 11
|
|
bool IsSubPath(const char* path1, const char* path2);
|
|
}
|
|
|
|
namespace nn::fs::PathNormalizer {
|
|
// SDK >= 11
|
|
nn::Result Normalize(char* buffer, uint64_t* outNormalizedPathLength, const char* path, uint64_t bufferLength, bool preserveUnc, bool hasMountName);
|
|
nn::Result IsNormalized(bool* outIsNormalized, const char* path, bool preserveUnc, bool hasMountName);
|
|
}
|
|
|
|
void* allocate(size_t size)
|
|
{
|
|
void* ptr = malloc(size);
|
|
|
|
char buffer[0x40];
|
|
sprintf(buffer, "Allocating %ld. 0x%p", size, ptr);
|
|
svcOutputDebugString(buffer, sizeof(buffer));
|
|
|
|
return ptr;
|
|
}
|
|
|
|
void deallocate(void* ptr, size_t size)
|
|
{
|
|
char buffer[0x40];
|
|
sprintf(buffer, "Deallocating %ld. 0x%p", size, ptr);
|
|
svcOutputDebugString(buffer, sizeof(buffer));
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void setAllocators(void) {
|
|
nn::fs::SetAllocator(allocate, deallocate);
|
|
}
|
|
|
|
const char* GetResultName(nn::Result result) {
|
|
switch (result.GetValue()) {
|
|
case 0: return "Result.Success";
|
|
case 0x2EE402: return "ResultFs.InvalidPath.Value";
|
|
case 0x2EE602: return "ResultFs.TooLongPath.Value";
|
|
case 0x2EE802: return "ResultFs.InvalidCharacter.Value";
|
|
case 0x2EEA02: return "ResultFs.InvalidPathFormat.Value";
|
|
case 0x2EEC02: return "ResultFs.DirectoryUnobtainable.Value";
|
|
default:
|
|
sprintf(ResultNameBuf, "0x%x", result.GetValue());
|
|
return ResultNameBuf;
|
|
}
|
|
}
|
|
|
|
void CreateNormalizeTestItem(char const* path, bool preserveUnc, bool hasMountName) {
|
|
char normalized[0x200];
|
|
uint64_t normalizedLen = 0;
|
|
memset(normalized, 0, 0x200);
|
|
|
|
//svcOutputDebugString(path, strnlen(path, 0x200));
|
|
|
|
nn::Result result = nn::fs::PathNormalizer::Normalize(normalized, &normalizedLen, path, 0x200, preserveUnc, hasMountName);
|
|
|
|
const char* preserveUncStr = preserveUnc ? "true" : "false";
|
|
const char* hasMountNameStr = hasMountName ? "true" : "false";
|
|
BufPos += sprintf(&Buf[BufPos], "new object[] {@\"%s\", %s, %s, @\"%s\", %ld, %s},\n",
|
|
path, preserveUncStr, hasMountNameStr, normalized, normalizedLen, GetResultName(result));
|
|
}
|
|
|
|
void CreateIsNormalizedTestItem(char const* path, bool preserveUnc, bool hasMountName) {
|
|
bool isNormalized = false;
|
|
|
|
nn::Result result = nn::fs::PathNormalizer::IsNormalized(&isNormalized, path, preserveUnc, hasMountName);
|
|
|
|
const char* preserveUncStr = preserveUnc ? "true" : "false";
|
|
const char* hasMountNameStr = hasMountName ? "true" : "false";
|
|
const char* isNormalizedStr = isNormalized ? "true" : "false";
|
|
BufPos += sprintf(&Buf[BufPos], "new object[] {@\"%s\", %s, %s, %s, %s},\n",
|
|
path, preserveUncStr, hasMountNameStr, isNormalizedStr, GetResultName(result));
|
|
}
|
|
|
|
void CreateIsSubpathTestItem(const char* path1, const char* path2) {
|
|
bool result = nn::fs::IsSubPath(path1, path2);
|
|
|
|
const char* resultStr = result ? "true" : "false";
|
|
BufPos += sprintf(&Buf[BufPos], "new object[] {@\"%s\", @\"%s\", %s},\n",
|
|
path1, path2, resultStr);
|
|
}
|
|
|
|
void CreateTestItemWithParentDirs(char const* path, bool preserveUnc, bool hasMountName, void (*func)(char const*, bool, bool), int parentCount) {
|
|
char parentPath[0x200];
|
|
memset(parentPath, 0, sizeof(parentPath));
|
|
|
|
strcpy(parentPath, path);
|
|
func(parentPath, preserveUnc, hasMountName);
|
|
|
|
for (int i = 0; i < parentCount; i++) {
|
|
strcat(parentPath, "/..");
|
|
func(parentPath, preserveUnc, hasMountName);
|
|
}
|
|
}
|
|
|
|
void CreateTestItemWithParentDirs(char const* path, bool preserveUnc, bool hasMountName, void (*func)(char const*, bool, bool)) {
|
|
CreateTestItemWithParentDirs(path, preserveUnc, hasMountName, func, 3);
|
|
}
|
|
|
|
void CreateNormalizationTestData(void (*func)(char const*, bool, bool)) {
|
|
Buf[0] = '\n';
|
|
BufPos = 1;
|
|
|
|
bool preserveUnc = false;
|
|
|
|
func("", preserveUnc, false);
|
|
func("/", preserveUnc, false);
|
|
func("/.", preserveUnc, false);
|
|
func("/a/b/c", preserveUnc, false);
|
|
func("/a/b/../c", preserveUnc, false);
|
|
func("/a/b/c/..", preserveUnc, false);
|
|
func("/a/b/c/.", preserveUnc, false);
|
|
func("/a/../../..", preserveUnc, false);
|
|
func("/a/../../../a/b/c", preserveUnc, false);
|
|
func("//a/b//.//c", preserveUnc, false);
|
|
func("/../a/b/c/.", preserveUnc, false);
|
|
func("/./aaa/bbb/ccc/.", preserveUnc, false);
|
|
func("/a/b/c/", preserveUnc, false);
|
|
func("a/b/c/", preserveUnc, false);
|
|
func("/aa/./bb/../cc/", preserveUnc, false);
|
|
func("/./b/../c/", preserveUnc, false);
|
|
func("/a/../../../", preserveUnc, false);
|
|
func("//a/b//.//c/", preserveUnc, false);
|
|
func("/tmp/../", preserveUnc, false);
|
|
func("a", preserveUnc, false);
|
|
func("a/../../../a/b/c", preserveUnc, false);
|
|
func("./b/../c/", preserveUnc, false);
|
|
func(".", preserveUnc, false);
|
|
func("..", preserveUnc, false);
|
|
func("../a/b/c/.", preserveUnc, false);
|
|
func("./a/b/c/.", preserveUnc, false);
|
|
func("abc", preserveUnc, false);
|
|
func("mount:/a/b/../c", preserveUnc, true);
|
|
func("a:/a/b/c", preserveUnc, true);
|
|
func("mount:/a/b/../c", preserveUnc, true);
|
|
func("mount:/a/b/../c", preserveUnc, false);
|
|
func("mount:\\a/b/../c", preserveUnc, true);
|
|
func("mount:\\a/b\\../c", preserveUnc, true);
|
|
func("mount:\\a/b/c", preserveUnc, true);
|
|
func("mount:/a\\../b\\..c", preserveUnc, true);
|
|
func("mount:/a\\../b/..cd", preserveUnc, true);
|
|
func("mount:/a\\..d/b/c\\..", preserveUnc, true);
|
|
func("mount:", preserveUnc, true);
|
|
func("abc:/a/../../../a/b/c", preserveUnc, true);
|
|
func("abc:/./b/../c/", preserveUnc, true);
|
|
func("abc:/.", preserveUnc, true);
|
|
func("abc:/..", preserveUnc, true);
|
|
func("abc:/", preserveUnc, true);
|
|
func("abc://a/b//.//c", preserveUnc, true);
|
|
func("abc:/././/././a/b//.//c", preserveUnc, true);
|
|
func("mount:/d./aa", preserveUnc, true);
|
|
func("mount:/d/..", preserveUnc, true);
|
|
func("/path/aaa/bbb\\..\\h/ddd", preserveUnc, false);
|
|
func("/path/aaa/bbb/../h/ddd", preserveUnc, false);
|
|
func("/path/aaa/bbb\\.\\h/ddd", preserveUnc, false);
|
|
func("/path/aaa/bbb\\./h/ddd", preserveUnc, false);
|
|
func("/path/aaa/bbb/./h/ddd", preserveUnc, false);
|
|
func("mount:abcd", preserveUnc, true);
|
|
func("mount:", preserveUnc, true);
|
|
func("mount:/", preserveUnc, true);
|
|
func("mount:\\..", preserveUnc, true);
|
|
func("mount:/a/b\\..", preserveUnc, true);
|
|
func("mount:/dir", preserveUnc, true);
|
|
func("mount:/dir/", preserveUnc, true);
|
|
func("mount:\\", preserveUnc, true);
|
|
func("mo.unt:\\", preserveUnc, true);
|
|
func("mount.:\\", preserveUnc, true);
|
|
func("mount:./aa/bb", preserveUnc, true);
|
|
//func("mount:../aa/bb", preserveUnc, true); // crashes nnsdk
|
|
func("mount:.../aa/bb", preserveUnc, true);
|
|
func("mount:...aa/bb", preserveUnc, true);
|
|
func("...aa/bb", preserveUnc, false);
|
|
func("mount01234567890/aa/bb", preserveUnc, true);
|
|
func("mount01234567890:/aa/bb", preserveUnc, true);
|
|
func("mount0123456789:/aa/bb", preserveUnc, true);
|
|
func("mount012345678:/aa/bb", preserveUnc, true);
|
|
func("mount:aa/..\\bb", preserveUnc, true);
|
|
func("mount:..\\bb", preserveUnc, true);
|
|
func("mount:/..\\bb", preserveUnc, true);
|
|
func("mount:/.\\bb", preserveUnc, true);
|
|
func("mount:\\..\\bb", preserveUnc, true);
|
|
func("mount:\\.\\bb", preserveUnc, true);
|
|
func("mount:/a\\..\\bb", preserveUnc, true);
|
|
func("mount:/a\\.\\bb", preserveUnc, true);
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
preserveUnc = (bool)i;
|
|
|
|
CreateTestItemWithParentDirs("//$abc/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//:abc/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("\\\\\\asd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("\\\\/asd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("\\\\//asd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a/b/cc/../d", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("c:/aa/bb", preserveUnc, true, func);
|
|
CreateTestItemWithParentDirs("mount:\\c:/aa", preserveUnc, true, func);
|
|
CreateTestItemWithParentDirs("mount:/c:\\aa/bb", preserveUnc, true, func);
|
|
CreateTestItemWithParentDirs("mount:////c:\\aa/bb", preserveUnc, true, func);
|
|
CreateTestItemWithParentDirs("mount:/\\aa/bb", preserveUnc, true, func);
|
|
CreateTestItemWithParentDirs("mount:/c:/aa/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("mount:c:/aa/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("mount:c:/aa/bb", preserveUnc, true, func, 0);
|
|
CreateTestItemWithParentDirs("mount:/\\aa/../b", preserveUnc, true, func, 2);
|
|
CreateTestItemWithParentDirs("mount://aa/bb", preserveUnc, true, func, 1);
|
|
CreateTestItemWithParentDirs("//aa/bb", preserveUnc, true, func, 1);
|
|
CreateTestItemWithParentDirs("//aa/bb", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("/aa/bb", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("c:/aa", preserveUnc, false, func, 2);
|
|
CreateTestItemWithParentDirs("c:abcde/aa/bb", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("c:abcde", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("c:abcde/", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("///aa", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa//bb", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//./bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//../bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//.../bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa$abc/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa$/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa:/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb$b/cc$", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc$c", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc$c/dd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc//dd", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc\\/dd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc//dd", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc/dd", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("//aa/bb/cc/\\dd", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("//aa/../", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa//", preserveUnc, false, func, 0);
|
|
CreateTestItemWithParentDirs("//aa/bb..", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//aa/bb../", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("/\\\\aa/bb/cc/..", preserveUnc, true, func);
|
|
|
|
CreateTestItemWithParentDirs("c:aa\\bb/cc", preserveUnc, false, func);
|
|
CreateTestItemWithParentDirs("c:\\//\\aa\\bb", preserveUnc, false, func, 1);
|
|
|
|
CreateTestItemWithParentDirs("mount://////a/bb/c", preserveUnc, true, func, 2);
|
|
|
|
CreateTestItemWithParentDirs("//", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a/", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a/b", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a/b/", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("//a/b/c", preserveUnc, false, func, 2);
|
|
CreateTestItemWithParentDirs("//a/b/c/", preserveUnc, false, func, 2);
|
|
|
|
CreateTestItemWithParentDirs("\\\\", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a/", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a/b", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a/b/", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a/b/c", preserveUnc, false, func, 2);
|
|
CreateTestItemWithParentDirs("\\\\a/b/c/", preserveUnc, false, func, 2);
|
|
|
|
CreateTestItemWithParentDirs("\\\\", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a\\", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a\\b", preserveUnc, false, func, 1);
|
|
CreateTestItemWithParentDirs("\\\\a\\b\\", preserveUnc, false, func, 1); // "\\a\b\/../.." crashes nnsdk
|
|
CreateTestItemWithParentDirs("\\\\a\\b\\c", preserveUnc, false, func, 2);
|
|
CreateTestItemWithParentDirs("\\\\a\\b\\c\\", preserveUnc, false, func, 2);
|
|
}
|
|
|
|
svcOutputDebugString(Buf, BufPos);
|
|
}
|
|
|
|
void CreateSubpathTestData() {
|
|
Buf[0] = '\n';
|
|
BufPos = 1;
|
|
|
|
CreateIsSubpathTestItem("//a/b", "/a");
|
|
CreateIsSubpathTestItem("/a", "//a/b");
|
|
CreateIsSubpathTestItem("//a/b", "\\\\a");
|
|
CreateIsSubpathTestItem("//a/b", "//a");
|
|
CreateIsSubpathTestItem("/", "/a");
|
|
CreateIsSubpathTestItem("/a", "/");
|
|
CreateIsSubpathTestItem("/", "/");
|
|
CreateIsSubpathTestItem("", "");
|
|
CreateIsSubpathTestItem("/", "");
|
|
CreateIsSubpathTestItem("/", "mount:/a");
|
|
CreateIsSubpathTestItem("mount:/", "mount:/");
|
|
CreateIsSubpathTestItem("mount:/a/b", "mount:/a/b");
|
|
CreateIsSubpathTestItem("mount:/a/b", "mount:/a/b/c");
|
|
CreateIsSubpathTestItem("/a/b", "/a/b/c");
|
|
CreateIsSubpathTestItem("/a/b/c", "/a/b");
|
|
CreateIsSubpathTestItem("/a/b", "/a/b");
|
|
CreateIsSubpathTestItem("/a/b", "/a/b\\c");
|
|
|
|
svcOutputDebugString(Buf, BufPos);
|
|
}
|
|
|
|
extern "C" void nnMain(void) {
|
|
//setAllocators();
|
|
nn::fs::detail::IsEnabledAccessLog(); // Adds the sdk version to the output when not calling setAllocators
|
|
CreateNormalizationTestData(CreateNormalizeTestItem);
|
|
CreateNormalizationTestData(CreateIsNormalizedTestItem);
|
|
CreateSubpathTestData();
|
|
} |