Skip to content

Commit ab0922d

Browse files
committed
PATCH: Fix Conffiles corruption bug
1 parent de0bc08 commit ab0922d

4 files changed

Lines changed: 83 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ members = [
66
]
77

88
[workspace.package]
9-
version = "0.6.3"
9+
version = "0.6.4"
1010
edition = "2021"
1111
license = "Apache-2.0"
1212
authors = ["Ryan Draga <ryan.draga@boxingoctop.us>"]

crates/raptor-core/src/dpkg_status.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ fn format_stanza(fields: &BTreeMap<String, String>) -> String {
130130
}
131131

132132
fn append_field(lines: &mut Vec<String>, key: &str, value: &str) {
133+
// dpkg requires every Conffiles entry on a continuation line beginning with a space.
134+
if key == "Conffiles" {
135+
lines.push(format!("{key}:"));
136+
for line in value.lines() {
137+
let line = line.trim();
138+
if !line.is_empty() {
139+
lines.push(format!(" {line}"));
140+
}
141+
}
142+
return;
143+
}
144+
133145
if !value.contains('\n') {
134146
lines.push(format!("{key}: {value}"));
135147
return;
@@ -172,4 +184,28 @@ mod tests {
172184
Some("line one\nline two")
173185
);
174186
}
187+
188+
#[test]
189+
fn round_trips_conffiles_with_leading_space_lines() {
190+
let content = "\
191+
Package: adduser
192+
Status: install ok installed
193+
Version: 3.137ubuntu1
194+
Architecture: all
195+
Conffiles:
196+
/etc/adduser.conf deadbeef0123456789deadbeef0123456789
197+
/etc/deluser.conf cafebabe0123456789cafebabe0123456789
198+
Description: add and remove users and groups
199+
";
200+
let stanzas = parse_status_file(&format!("{content}\n")).unwrap();
201+
let adduser = stanzas.get("adduser").unwrap();
202+
let formatted = format_stanza(adduser);
203+
assert!(formatted.contains("Conffiles:\n /etc/adduser.conf"));
204+
assert!(!formatted.contains("Conffiles: /etc/"));
205+
let reparsed = parse_stanza(&formatted).unwrap();
206+
assert_eq!(
207+
reparsed.get("Conffiles").map(String::as_str),
208+
adduser.get("Conffiles").map(String::as_str)
209+
);
210+
}
175211
}

crates/raptor-core/src/state.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,50 @@ mod tests {
316316
let _ = fs::remove_dir_all(&dir);
317317
}
318318

319+
#[test]
320+
fn save_preserves_conffiles_format_for_other_packages() {
321+
let dir = std::env::temp_dir().join(format!("raptor-dpkg-conffiles-{}", std::process::id()));
322+
let _ = fs::remove_dir_all(&dir);
323+
fs::create_dir_all(&dir).unwrap();
324+
let path = dir.join("status");
325+
326+
fs::write(
327+
&path,
328+
"\
329+
Package: adduser
330+
Status: install ok installed
331+
Version: 3.137ubuntu1
332+
Architecture: all
333+
Conffiles:
334+
/etc/adduser.conf deadbeef0123456789deadbeef0123456789
335+
Description: add and remove users
336+
337+
Package: hello
338+
Status: install ok installed
339+
Version: 1.0
340+
Architecture: all
341+
Description: hi
342+
343+
",
344+
)
345+
.unwrap();
346+
347+
let mut state = State::load(&path).unwrap();
348+
state.install(&ControlFile {
349+
package: "raptor".into(),
350+
version: "0.6.3".into(),
351+
architecture: "arm64".into(),
352+
..Default::default()
353+
});
354+
state.save().unwrap();
355+
356+
let saved = fs::read_to_string(&path).unwrap();
357+
assert!(saved.contains("Conffiles:\n /etc/adduser.conf"));
358+
assert!(!saved.contains("Conffiles: /etc/"));
359+
360+
let _ = fs::remove_dir_all(&dir);
361+
}
362+
319363
#[test]
320364
fn deb_architecture_maps_rust_targets() {
321365
assert_eq!(deb_architecture("x86_64"), "amd64");

0 commit comments

Comments
 (0)