fix: reject empty coverage counters

This commit is contained in:
DongHyeonka
2026-08-02 09:10:35 +09:00
parent 8d6fbb97e9
commit 6e05a35790
5 changed files with 505 additions and 39 deletions
+13 -9
View File
@@ -90,16 +90,16 @@ function hasStableIdentity(metadata: Stats): boolean {
return (
Number.isSafeInteger(metadata.dev) &&
Number.isSafeInteger(metadata.ino) &&
(metadata.dev !== 0 || metadata.ino !== 0)
metadata.dev > 0 &&
metadata.ino > 0
);
}
function sameFileIdentity(before: Stats, after: Stats): boolean {
return (
!hasStableIdentity(before) ||
!hasStableIdentity(after) ||
(before.dev === after.dev && before.ino === after.ino)
);
if (!hasStableIdentity(before) || !hasStableIdentity(after)) {
throw new TypeError("stable file identity unavailable");
}
return before.dev === after.dev && before.ino === after.ino;
}
async function rejectSymlinkAncestors(
@@ -251,16 +251,20 @@ export async function resolveRiskCoverageArtifactPath(input: Readonly<{
if (!hasErrorCode(error, "ENOENT")) throw error;
}
if (destinationMetadata) {
if (!hasStableIdentity(destinationMetadata)) {
throw new TypeError("artifact stable file identity unavailable");
}
const destinationRealpath = await realpath(absolutePath);
for (const inputPath of normalizedInputs) {
const inputAbsolutePath = path.resolve(repositoryRoot, inputPath);
const inputRealpath = await realpath(inputAbsolutePath);
const inputMetadata = await lstat(inputAbsolutePath);
if (!hasStableIdentity(inputMetadata)) {
throw new TypeError(`input stable file identity unavailable: ${inputPath}`);
}
if (
inputRealpath === destinationRealpath ||
(hasStableIdentity(inputMetadata) &&
hasStableIdentity(destinationMetadata) &&
inputMetadata.dev === destinationMetadata.dev &&
(inputMetadata.dev === destinationMetadata.dev &&
inputMetadata.ino === destinationMetadata.ino)
) {
throw new TypeError(`artifact path is the same file as an input: ${inputPath}`);