fix(ci): canonicalize 8.3 short paths in cutter matrix ownership checks
Windows CI / verify (push) Failing after 1m26s

assertPathInside compared managed-tool paths with path.resolve only, so
on runners whose temporary directory surfaces as a Windows 8.3 short
path (RUNNER~1) the canonical long executable paths appeared to live
outside the owned root and the cutter matrix provisioning contract
failed. Resolve both sides through fs.realpathSync.native, walking up
through not-yet-existing segments so planned directories keep working,
and cover the contract with a real ShortPath regression test plus
mixed-existence canonicalization cases.
This commit is contained in:
Sucukdeluxe
2026-08-14 13:06:52 +02:00
parent 0f845f0735
commit 6547e6dbbc
2 changed files with 102 additions and 2 deletions
+18 -2
View File
@@ -41,9 +41,25 @@ const markerTimes = Object.freeze({
});
const markerAudioSampleRate = 48000;
function resolveCanonicalPath(candidatePath) {
let existingPath = path.resolve(candidatePath);
const missingSegments = [];
while (true) {
try {
return path.join(fs.realpathSync.native(existingPath), ...missingSegments.reverse());
} catch (error) {
if (error?.code !== 'ENOENT') throw error;
const parentPath = path.dirname(existingPath);
if (parentPath === existingPath) return path.resolve(candidatePath);
missingSegments.push(path.basename(existingPath));
existingPath = parentPath;
}
}
}
function assertPathInside(targetPath, parentPath, label) {
const resolvedTarget = path.resolve(targetPath);
const resolvedParent = path.resolve(parentPath);
const resolvedTarget = resolveCanonicalPath(targetPath);
const resolvedParent = resolveCanonicalPath(parentPath);
const relative = path.relative(resolvedParent, resolvedTarget);
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
throw new Error(`${label} is outside the owned managed-tool directory: ${resolvedTarget}`);