mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
Merge pull request #9469 from Gruzzberry/fix/chflags-dangling-link
fix(libkernel): fail chflags through a dangling Windows symbolic link with ENOENT
This commit is contained in:
2 files changed
+30
No files matched your search
@@ -662,6 +662,15 @@ int File::DuplicateFrom(int fd, int start) {
|
||||
}
|
||||
|
||||
static int LookupError(const std::filesystem::path& native) {
|
||||
#ifdef _WIN32
|
||||
const auto named = native.has_filename() ? native : WithoutTrailingSeparator(native);
|
||||
const DWORD attributes = GetFileAttributesW(named.c_str());
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
|
||||
FileStat target{};
|
||||
if (!File::TryFillFileStat(named, &target)) return SceErrorFromErrno(errno) & 0xffff;
|
||||
return native.has_filename() || (target.st_mode & 0170000) == 0040000 ? 0 : GUEST_ENOTDIR;
|
||||
}
|
||||
#endif
|
||||
std::error_code error;
|
||||
const auto status = std::filesystem::status(native, error);
|
||||
if (std::filesystem::exists(status)) return native.has_filename() || std::filesystem::is_directory(status) ? 0 : GUEST_ENOTDIR;
|
||||
|
||||
@@ -634,6 +634,27 @@ int main() {
|
||||
Require(chflags_nid_postfix(file.string().c_str(), 0x200000) == -1 && *__error_nid_postfix() == 1);
|
||||
Require(ChflagsThrows(file, 0x2, "UF_IMMUTABLE"));
|
||||
Require(ChflagsThrows(file, 0x1000 | 0x40000, "UF_READONLY|SF_APPEND"));
|
||||
const auto chflagsDangling = root / "dangling.link";
|
||||
const auto chflagsPointing = root / "file.link";
|
||||
#ifdef _WIN32
|
||||
const bool chflagsLinked = CreateSymbolicLinkW(chflagsDangling.wstring().c_str(), L"missing.bin", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) != 0 &&
|
||||
CreateSymbolicLinkW(chflagsPointing.wstring().c_str(), L"file.txt", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) != 0;
|
||||
#else
|
||||
std::error_code chflagsLinkError;
|
||||
std::filesystem::create_symlink("missing.bin", chflagsDangling, chflagsLinkError);
|
||||
if (!chflagsLinkError) std::filesystem::create_symlink("file.txt", chflagsPointing, chflagsLinkError);
|
||||
const bool chflagsLinked = !chflagsLinkError;
|
||||
#endif
|
||||
if (chflagsLinked) {
|
||||
Require(chflags_nid_postfix(chflagsDangling.string().c_str(), 0) == -1 && *__error_nid_postfix() == 2);
|
||||
Require(chflags_nid_postfix(chflagsPointing.string().c_str(), 0) == 0);
|
||||
Require(chflags_nid_postfix((chflagsPointing.string() + "/").c_str(), 0) == -1 && *__error_nid_postfix() == 20);
|
||||
Require(chflags_nid_postfix(chflagsPointing.string().c_str(), 0x20) == -1 && *__error_nid_postfix() == 45);
|
||||
Require(unlink_nid_postfix(chflagsDangling.string().c_str()) == 0 && unlink_nid_postfix(chflagsPointing.string().c_str()) == 0);
|
||||
} else {
|
||||
unlink_nid_postfix(chflagsDangling.string().c_str());
|
||||
std::fprintf(stderr, "symbolic links unavailable: the chflags link cases not tested\n");
|
||||
}
|
||||
const int flagged = open_nid_postfix(file.string().c_str(), 0, 0);
|
||||
Require(flagged >= 0 && fchflags_nid_postfix(flagged, 0) == 0);
|
||||
Require(fchflags_nid_postfix(flagged, 0x20) == -1 && *__error_nid_postfix() == 45);
|
||||
|
||||
Reference in new issue
Block a user