mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-08 19:42:12 +00:00
CP4.1: review — a staging folder left by an earlier process with the same id is cleared before use
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FypgCX8LsYYE8fsj4byBm2
This commit is contained in:
1 parent
98321781d9
commit
1704bef581
2 files changed
+19
No files matched your search
@@ -318,3 +318,18 @@ fn hostile_archives_are_refused() {
|
||||
unpack(&pack_archive("nl", "x"), &dest).unwrap();
|
||||
assert!(dest.join("LICENCES/COPYING").is_file());
|
||||
}
|
||||
|
||||
/// A staging folder an earlier process with the same id left behind is cleared, so an unpack
|
||||
/// (`create_new`) can't fail on, or mix in, its files.
|
||||
#[test]
|
||||
fn a_stale_stage_folder_is_cleared() {
|
||||
let store = temp("stale-stage");
|
||||
let staging = store.join(".staging");
|
||||
for n in 0..512 {
|
||||
let d = staging.join(format!("{}-{n}", std::process::id()));
|
||||
std::fs::create_dir_all(d.join("nl")).unwrap();
|
||||
std::fs::write(d.join("nl/pack.toml"), b"old").unwrap();
|
||||
}
|
||||
let stage = Stage::new(&store).unwrap();
|
||||
assert_eq!(std::fs::read_dir(&stage.dir).unwrap().count(), 0, "{}", stage.dir.display());
|
||||
}
|
||||
@@ -840,6 +840,10 @@ impl Stage {
|
||||
pub(crate) fn new(store: &Path) -> Result<Self, Error> {
|
||||
static N: AtomicU64 = AtomicU64::new(0);
|
||||
let dir = store.join(STAGING).join(format!("{}-{}", std::process::id(), N.fetch_add(1, Ordering::Relaxed)));
|
||||
// A folder left by an earlier process with the same id is cleared, not mixed in.
|
||||
if std::fs::symlink_metadata(&dir).is_ok() {
|
||||
std::fs::remove_dir_all(&dir).map_err(io("clearing an old download folder"))?;
|
||||
}
|
||||
std::fs::create_dir_all(&dir).map_err(io("creating a download folder"))?;
|
||||
Ok(Self { dir })
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user