pull: keep self-prefixed multi-orig components in place
A component tarball whose entries already carry the addon prefix
('www/...' in sqlite3's 'sqlite3_3.53.4.orig-www.tar.xz') extracts
to its end state, but the wrapper detection named it a wrapper and
unwrap_into then cleared the addon target - destroying the component
just extracted into it - and unwrapped the emptied directory into
itself: no 'www' at all, and the deb failed at dh_installdocs over
the missing 'www/*' docs.
dpkg-source unpacks a component into '<root>/<addon>': when the
tarball's own layout already is that, the extraction is the end
state; leave it alone.
This commit is contained in:
+45
-5
@@ -167,18 +167,23 @@ fn component_addon(name: &str) -> Option<&str> {
|
|||||||
/// `dir/<addon>` for a multi-orig component, replacing any pre-existing
|
/// `dir/<addon>` for a multi-orig component, replacing any pre-existing
|
||||||
/// addon directory.
|
/// addon directory.
|
||||||
fn unwrap_into(dir: &Path, wrapper: &Path, addon: Option<&str>) -> Result<(), Box<dyn Error>> {
|
fn unwrap_into(dir: &Path, wrapper: &Path, addon: Option<&str>) -> Result<(), Box<dyn Error>> {
|
||||||
let target = match addon {
|
match addon {
|
||||||
|
// dpkg-source unpacks a component into '<root>/<addon>': a tarball
|
||||||
|
// whose entries already carry that prefix ('www/...' in
|
||||||
|
// 'sqlite3_3.53.4.orig-www.tar.xz') extracts to its end state, and
|
||||||
|
// unwrapping it would clear the target and move the cleared
|
||||||
|
// directory into itself.
|
||||||
|
Some(addon) if wrapper.file_name().is_some_and(|name| name == addon) => Ok(()),
|
||||||
Some(addon) => {
|
Some(addon) => {
|
||||||
let target = dir.join(addon);
|
let target = dir.join(addon);
|
||||||
if target.is_dir() {
|
if target.is_dir() {
|
||||||
std::fs::remove_dir_all(&target)?;
|
std::fs::remove_dir_all(&target)?;
|
||||||
}
|
}
|
||||||
std::fs::create_dir_all(&target)?;
|
std::fs::create_dir_all(&target)?;
|
||||||
target
|
unwrap_wrapper(&target, wrapper)
|
||||||
}
|
}
|
||||||
None => dir.to_path_buf(),
|
None => unwrap_wrapper(dir, wrapper),
|
||||||
};
|
}
|
||||||
unwrap_wrapper(&target, wrapper)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the contents of an archive's wrapper directory up into `dir` itself.
|
/// Move the contents of an archive's wrapper directory up into `dir` itself.
|
||||||
@@ -1450,6 +1455,41 @@ mod tests {
|
|||||||
assert!(!tree.join("dovecot-pigeonhole-2.4.5").exists());
|
assert!(!tree.join("dovecot-pigeonhole-2.4.5").exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unwrap_component_already_prefixed_with_addon() {
|
||||||
|
// Regression: a component tarball whose entries already carry the
|
||||||
|
// addon prefix ('www/...' in 'sqlite3_3.53.4.orig-www.tar.xz')
|
||||||
|
// extracts to its end state. It used to be treated as a wrapper of
|
||||||
|
// the same name as the addon: unwrap_into cleared the target —
|
||||||
|
// destroying the component just extracted into it — and unwrapped
|
||||||
|
// the emptied directory into itself, leaving no 'www' at all.
|
||||||
|
let temp_dir = tempfile::tempdir().unwrap();
|
||||||
|
let tar_path = temp_dir.path().join("pkg_1.0.orig-www.tar.gz");
|
||||||
|
std::fs::write(
|
||||||
|
&tar_path,
|
||||||
|
build_tar(&[("www/README", b"docs"), ("www/img/x", b"img")]),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tree = temp_dir.path().join("tree");
|
||||||
|
let extracted = extract_tar_archive(&tar_path, &tree, None, |f| f).unwrap();
|
||||||
|
unwrap_into(
|
||||||
|
&tree,
|
||||||
|
&extracted.wrapper.unwrap(),
|
||||||
|
component_addon("pkg_1.0.orig-www.tar.gz"),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
std::fs::read_to_string(tree.join("www/README")).unwrap(),
|
||||||
|
"docs"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
std::fs::read_to_string(tree.join("www/img/x")).unwrap(),
|
||||||
|
"img"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// A minimal ustar archive of `pkg-1.0/{Makefile,doc/readme}`,
|
/// A minimal ustar archive of `pkg-1.0/{Makefile,doc/readme}`,
|
||||||
/// bz2-compressed.
|
/// bz2-compressed.
|
||||||
const BZ2_TAR_WRAPPED: &[u8] = &[
|
const BZ2_TAR_WRAPPED: &[u8] = &[
|
||||||
|
|||||||
Reference in New Issue
Block a user