diff --git a/src/builder.rs b/src/builder.rs index 4a581ce7..36f35bef 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -120,9 +120,8 @@ impl Builder { /// header will be modified. /// /// Then it will append the header, followed by contents of the stream - /// specified by `data`, with the `size` field of `header` enforced as an - /// upper limit. To produce a valid archive the `size` field of `header` - /// must be less than or equal to the length of the stream that's being + /// specified by `data`. To produce a valid archive the `size` field of + /// `header` must be the same as the length of the stream that's being /// written. /// /// Note that this will not attempt to seek the archive to a valid position, @@ -407,13 +406,9 @@ impl Builder { } } -fn append(mut dst: &mut dyn Write, header: &Header, data: &mut dyn Read) -> io::Result<()> { +fn append(mut dst: &mut dyn Write, header: &Header, mut data: &mut dyn Read) -> io::Result<()> { dst.write_all(header.as_bytes())?; - // Guards against there being more data than the header indicates in the case where contents - // have been appended to the file since the header was created. - let size = header.size()?; - let mut limited = data.take(size); - let len = io::copy(&mut limited, &mut dst)?; + let len = io::copy(&mut data, &mut dst)?; // Pad with zeros if necessary. let buf = [0; 512]; @@ -449,7 +444,8 @@ fn append_path_with_name( }; let ar_name = name.unwrap_or(path); if stat.is_file() { - append_fs(dst, ar_name, &stat, &mut fs::File::open(path)?, mode, None) + let file = fs::File::open(path)?; + append_fs(dst, ar_name, &stat, &mut file.take(stat.len()), mode, None) } else if stat.is_dir() { append_fs(dst, ar_name, &stat, &mut io::empty(), mode, None) } else if stat.file_type().is_symlink() { @@ -525,7 +521,7 @@ fn append_file( mode: HeaderMode, ) -> io::Result<()> { let stat = file.metadata()?; - append_fs(dst, path, &stat, file, mode, None) + append_fs(dst, path, &stat, &mut file.take(stat.len()), mode, None) } fn append_dir( diff --git a/tests/all.rs b/tests/all.rs index a5fc97c6..11103bd6 100644 --- a/tests/all.rs +++ b/tests/all.rs @@ -1279,12 +1279,10 @@ fn append_long_multibyte() { let mut x = tar::Builder::new(Vec::new()); let mut name = String::new(); let data: &[u8] = &[]; - let mut header = Header::new_gnu(); - header.set_size(data.len() as u64); for _ in 0..512 { name.push('a'); name.push('ð‘¢®'); - x.append_data(&mut header, &name, data).unwrap(); + x.append_data(&mut Header::new_gnu(), &name, data).unwrap(); name.pop(); } } @@ -1387,31 +1385,3 @@ fn header_size_overflow() { err ); } - -#[test] -fn file_contents_appended_after_header_creation() { - let mut data = String::from("Hello"); - - let mut header = Header::new_gnu(); - header.set_size(data.len() as u64); - header.set_cksum(); - - // Additional data is appended after header creation - data.push_str(", World!"); - - let mut ar = Builder::new(Vec::new()); - t!(ar.append_data(&mut header, "test2", data.as_bytes())); - - let raw = t!(ar.into_inner()); - let mut ar = Archive::new(Cursor::new(raw)); - let mut entries = t!(ar.entries()); - let entry = t!(entries.next().unwrap()); - let offset = entry.raw_file_position(); - let mut raw = ar.into_inner(); - - let mut s = String::new(); - raw.set_position(offset); - t!(raw.read_to_string(&mut s)); - let s = s.trim_end_matches(char::from(0)); - assert_eq!(s, "Hello"); -}