test(windows): probe readonly files with no other attributes
This commit is contained in:
1 parent
84b35d8e7f
commit
0b46b37d37
2 files changed
+17
-3
No files matched your search
@@ -473,6 +473,9 @@ static void dispose(HANDLE handle, const std::wstring& path) {
|
||||
require(GetFileInformationByHandleEx(handle, FileBasicInfo, &info, sizeof(info)), "Read cleanup attributes failed", path);
|
||||
if ((info.FileAttributes & FILE_ATTRIBUTE_READONLY) != 0) {
|
||||
info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
|
||||
// Zero means "leave attributes unchanged" to FileBasicInfo. A file whose
|
||||
// sole attribute was READONLY needs NORMAL to actually clear that marker.
|
||||
if (info.FileAttributes == 0) info.FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
require(SetFileInformationByHandle(handle, FileBasicInfo, &info, sizeof(info)), "Clear owned readonly attribute failed", path);
|
||||
}
|
||||
FILE_DISPOSITION_INFO deletion{TRUE};
|
||||
|
||||
@@ -30,7 +30,7 @@ const attributes = (path, readonly) => {
|
||||
const script = `$ErrorActionPreference='Stop';
|
||||
$path=$env:REA_OWNED_ATTRIBUTE_PROBE;
|
||||
$current=[int][IO.File]::GetAttributes($path);
|
||||
$next=if($env:REA_ATTRIBUTE_PROBE_MODE -eq 'set'){ $current -bor 1 }else{ $current -band (-bnot 1) };
|
||||
$next=if($env:REA_ATTRIBUTE_PROBE_MODE -eq 'only'){1}elseif($env:REA_ATTRIBUTE_PROBE_MODE -eq 'set'){ $current -bor 1 }else{ $current -band (-bnot 1) };
|
||||
[IO.File]::SetAttributes($path,[IO.FileAttributes]$next);
|
||||
$observed=[int][IO.File]::GetAttributes($path);
|
||||
@{readonly=(($observed -band 1) -ne 0); attributes=$observed} | ConvertTo-Json -Compress`;
|
||||
@@ -45,12 +45,12 @@ $observed=[int][IO.File]::GetAttributes($path);
|
||||
env: {
|
||||
...process.env,
|
||||
REA_OWNED_ATTRIBUTE_PROBE: path,
|
||||
REA_ATTRIBUTE_PROBE_MODE: readonly ? "set" : "clear",
|
||||
REA_ATTRIBUTE_PROBE_MODE: readonly === "only" ? "only" : readonly ? "set" : "clear",
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
assert.equal(result.readonly, readonly);
|
||||
assert.equal(result.readonly, Boolean(readonly));
|
||||
return result;
|
||||
};
|
||||
const create = () => {
|
||||
@@ -139,6 +139,16 @@ try {
|
||||
}
|
||||
close(children);
|
||||
await assert.rejects(access(children.currentPath), { code: "ENOENT" });
|
||||
const onlyReadonly = create();
|
||||
native.call("runtime_write", [onlyReadonly.runtime.handle, "only-readonly.txt", Buffer.from("owned file")]);
|
||||
const onlyReadonlyPath = join(onlyReadonly.currentPath, "only-readonly.txt");
|
||||
assert.equal(attributes(onlyReadonlyPath, "only").attributes, 1);
|
||||
if (expected === "deny-clear") {
|
||||
assert.throws(() => close(onlyReadonly), error => error.win32Code === 5 && error.constraint === "Delete owned object by handle failed");
|
||||
attributes(onlyReadonlyPath, false);
|
||||
}
|
||||
close(onlyReadonly);
|
||||
await assert.rejects(access(onlyReadonly.currentPath), { code: "ENOENT" });
|
||||
console.log(
|
||||
JSON.stringify({
|
||||
ok: true,
|
||||
@@ -149,6 +159,7 @@ try {
|
||||
renamedOwnedRootRemoved: true,
|
||||
unrelatedReplacementPreserved: true,
|
||||
readonlyChildFileAndDirectoryRemoved: true,
|
||||
readonlyFileWithoutOtherAttributesRemoved: true,
|
||||
baselineConstraint: failure?.constraint ?? null,
|
||||
baselineWin32: failure?.win32Code ?? null,
|
||||
originalIssueDeleteDenialReproduced: false,
|
||||
|
||||
Reference in new issue
Block a user