build: check stat's exit status and honor DPKG_ORIGINS_DIR

hashes_in_context never checked stat's exit status and parsed its size
with unwrap_or(0), silently recording zero-size artifacts in the
generated .changes/.buildinfo; stat failures and unparsable sizes are
now errors naming the file. current_vendor hardcoded
/etc/dpkg/origins/default while dpkg honors DPKG_ORIGINS_DIR (already
in the file's own ENV_ALLOWED list); the origins default is now
resolved against it with the usual fallback.
This commit is contained in:
2026-09-17 18:56:32 +02:00
parent 22e43741f3
commit fa39851783
2 changed files with 56 additions and 7 deletions
+16 -3
View File
@@ -332,21 +332,34 @@ fn hashes_in_context(
.map(|n| (n.clone(), ArtifactHashes::default()))
.collect();
// Sizes.
// Sizes. A failed `stat` must fail the metadata generation: an unchecked
// exit status would leave the default size 0 in the produced
// `.changes`/`.buildinfo` checksum entries.
let output = ctx
.command("stat")
.current_dir(dir)
.arg("-c")
.arg("%s %n")
.args(names)
.output()?;
.output()
.map_err(|e| format!("failed to run 'stat' inside the build context: {e}"))?;
if !output.status.success() {
return Err(format!(
"'stat' failed inside the build context: {}",
String::from_utf8_lossy(&output.stderr).trim()
)
.into());
}
let stdout = String::from_utf8_lossy(&output.stdout);
for line in stdout.lines() {
let Some((size, name)) = line.trim().split_once(' ') else {
continue;
};
let size = size
.parse::<u64>()
.map_err(|_| format!("'stat' reported an invalid size '{size}' for '{name}'"))?;
if let Some(slot) = out.get_mut(name) {
slot.size = size.parse().unwrap_or(0);
slot.size = size;
}
}