LibHac/tests/LibHac.Tests/Fs/PathToolTestGenerator.cpp
Alex Barney 0c255e0f49 Update common path handling code
- Updates path handling code to system version 11.0.0.
- Changes InMemoryFileSystem to normalize all incoming paths.
2021-03-28 16:03:05 -07:00

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();
}