mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
75 lines
3.0 KiB
C++
75 lines
3.0 KiB
C++
#include <io/FileReader.hpp>
|
|
#include <io/FileWriter.hpp>
|
|
#include <io/NativePath.hpp>
|
|
#include <chrono>
|
|
#include <filesystem>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace {
|
|
|
|
void Require(bool condition, const std::string& message) {
|
|
if (!condition) throw std::runtime_error(message);
|
|
}
|
|
|
|
template<typename TAction>
|
|
void RequireInvalidPath(TAction action) {
|
|
try {
|
|
action();
|
|
} catch (const std::invalid_argument& error) {
|
|
Require(std::string(error.what()).find("NUL") != std::string::npos, "Path error does not identify the NUL byte");
|
|
return;
|
|
}
|
|
throw std::runtime_error("A path containing a NUL byte was accepted");
|
|
}
|
|
|
|
void Conversions() {
|
|
for (const std::string path : {"", "relative/file.bin", "a path with spaces", "caf\xc3\xa9/\xe6\x97\xa5\xe6\x9c\xac.bin"})
|
|
Require(Io::Utf8Path(Io::NativePath(path)) == path, "Valid path did not round-trip");
|
|
for (const std::string prefix : {"", "file", "directory/file"}) {
|
|
for (const auto& suffix : std::vector<std::string>{"", "suffix", std::string(1, '\0')}) {
|
|
const auto path = prefix + '\0' + suffix;
|
|
RequireInvalidPath([&] { Io::NativePath(path); });
|
|
}
|
|
}
|
|
}
|
|
|
|
void FileAccess(const std::filesystem::path& directory) {
|
|
const auto original = directory / Io::NativePath("caf\xc3\xa9-\xe6\x97\xa5\xe6\x9c\xac.bin");
|
|
const auto originalPath = Io::Utf8Path(original);
|
|
const std::vector<std::uint8_t> expected{0, 1, 10, 13, 127, 128, 255};
|
|
Io::FileWriter().Write(originalPath, expected);
|
|
Require(Io::FileReader().Read(originalPath) == expected, "Valid UTF-8 file path did not preserve binary data");
|
|
const auto missingPath = Io::Utf8Path(directory / "missing.bin");
|
|
for (const auto& prefix : {originalPath, missingPath}) {
|
|
for (const std::string suffix : {"", ".other", "/other.bin"}) {
|
|
const auto path = prefix + '\0' + suffix;
|
|
RequireInvalidPath([&] { Io::FileReader().Read(path); });
|
|
RequireInvalidPath([&] { Io::FileWriter().Write(path, std::vector<std::uint8_t>{42}); });
|
|
RequireInvalidPath([&] { Io::FileWriter().Write(path, std::string("replacement")); });
|
|
Require(Io::FileReader().Read(originalPath) == expected, "Invalid path changed the file named before the NUL byte");
|
|
Require(!std::filesystem::exists(Io::NativePath(missingPath)), "Invalid path created the file named before the NUL byte");
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
const auto directory = std::filesystem::temp_directory_path() /
|
|
("anyps5-native-path-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
|
|
try {
|
|
Conversions();
|
|
std::filesystem::create_directory(directory);
|
|
FileAccess(directory);
|
|
} catch (const std::exception& error) {
|
|
std::cerr << error.what() << '\n';
|
|
std::error_code ignored;
|
|
std::filesystem::remove_all(directory, ignored);
|
|
return 1;
|
|
}
|
|
std::filesystem::remove_all(directory);
|
|
}
|