From c69962610f8eb4136ab1881f2735082b5bc2404e Mon Sep 17 00:00:00 2001 From: Greg Oster Date: Tue, 26 Mar 2024 11:15:44 -0600 Subject: [PATCH 1/2] Truncate UIDs and GIDs larger than 999999 so they do not overflow the 6-character field. --- src/header.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/header.rs b/src/header.rs index 9462650..9d9d556 100644 --- a/src/header.rs +++ b/src/header.rs @@ -242,11 +242,11 @@ impl Header { let padded_length = self.identifier.len() + padding_length; writeln!( writer, - "#1/{:<13}{:<12}{:<6}{:<6}{:<8o}{:<10}`", + "#1/{:<13}{:<12}{:<6.6}{:<6.6}{:<8o}{:<10}`", padded_length, self.mtime, - self.uid, - self.gid, + self.uid.to_string(), + self.gid.to_string(), self.mode, self.size + padded_length as u64 )?; @@ -257,8 +257,12 @@ impl Header { writer.write_all(&vec![b' '; 16 - self.identifier.len()])?; writeln!( writer, - "{:<12}{:<6}{:<6}{:<8o}{:<10}`", - self.mtime, self.uid, self.gid, self.mode, self.size + "{:<12}{:<6.6}{:<6.6}{:<8o}{:<10}`", + self.mtime, + self.uid.to_string(), + self.gid.to_string(), + self.mode, + self.size )?; } Ok(()) @@ -282,8 +286,12 @@ impl Header { } writeln!( writer, - "{:<12}{:<6}{:<6}{:<8o}{:<10}`", - self.mtime, self.uid, self.gid, self.mode, self.size + "{:<12}{:<6.6}{:<6.6}{:<8o}{:<10}`", + self.mtime, + self.uid.to_string(), + self.gid.to_string(), + self.mode, + self.size )?; Ok(()) } From 954adb8027511c06e131401ebe50f77eec96a1d9 Mon Sep 17 00:00:00 2001 From: Greg Oster Date: Tue, 26 Mar 2024 18:16:41 -0600 Subject: [PATCH 2/2] Add a test for uid/gid overflow being handled correctly. --- src/builder.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/builder.rs b/src/builder.rs index 45809e8..95a16b8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -281,6 +281,27 @@ mod tests { assert_eq!(str::from_utf8(&actual).unwrap(), expected); } + #[test] + fn build_common_archive_with_uid_gid_overflow() { + let mut builder = Builder::new(Vec::new()); + let mut header1 = Header::new(b"foo.txt".to_vec(), 7); + header1.set_mtime(1487552916); + header1.set_uid(1234567); + header1.set_gid(7654321); + header1.set_mode(0o100644); + builder.append(&header1, "foobar\n".as_bytes()).unwrap(); + let header2 = Header::new(b"baz.txt".to_vec(), 4); + builder.append(&header2, "baz\n".as_bytes()).unwrap(); + let actual = builder.into_inner().unwrap(); + let expected = "\ + !\n\ + foo.txt 1487552916 123456765432100644 7 `\n\ + foobar\n\n\ + baz.txt 0 0 0 0 4 `\n\ + baz\n"; + assert_eq!(str::from_utf8(&actual).unwrap(), expected); + } + #[test] fn build_bsd_archive_with_long_filenames() { let mut builder = Builder::new(Vec::new());