Skip to content

Commit

Permalink
fix(cli): ENOENT during asset publishing (#25869)
Browse files Browse the repository at this point in the history
There was still a TOCTOU error in the file asset publishing, which could lead to `ENOENT: no such file or directory` when assets were being published in parallel.

The whole `if (fileExists) { delete; }` logic was actually not necessary, as `fs.rename` will atomically overwrite existing files already, so we can just call it directly.

Closes #25293.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
rix0rrr committed Jun 6, 2023
1 parent 60699f4 commit 1668dbd
Showing 1 changed file with 6 additions and 17 deletions.
23 changes: 6 additions & 17 deletions packages/cdk-assets/lib/private/archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@ function writeZipFile(directory: string, outputFile: string): Promise<void> {
}

/**
* Rename the file to the target location, taking into account that we may see EPERM on Windows
* while an Antivirus scanner still has the file open, so retry a couple of times.
* Rename the file to the target location, taking into account:
*
* - That we may see EPERM on Windows while an Antivirus scanner still has the
* file open, so retry a couple of times.
* - This same function may be called in parallel and be interrupted at any point.
*/
async function moveIntoPlace(source: string, target: string, logger: Logger) {
let delay = 100;
let attempts = 5;
while (true) {
try {
if (await pathExists(target)) {
await fs.unlink(target);
}
// 'rename' is guaranteed to overwrite an existing target, as long as it is a file (not a directory)
await fs.rename(source, target);
return;
} catch (e: any) {
Expand All @@ -86,18 +87,6 @@ function sleep(ms: number) {
return new Promise(ok => setTimeout(ok, ms));
}

async function pathExists(x: string) {
try {
await fs.stat(x);
return true;
} catch (e: any) {
if (e.code === 'ENOENT') {
return false;
}
throw e;
}
}

function randomString() {
return Math.random().toString(36).replace(/[^a-z0-9]+/g, '');
}

0 comments on commit 1668dbd

Please sign in to comment.