Skip to content

Commit f572794

Browse files
committed
Additional gz test coverage
1 parent 3983883 commit f572794

File tree

2 files changed

+87
-42
lines changed

2 files changed

+87
-42
lines changed

libz-rs-sys/src/gz.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,6 @@ unsafe fn gz_look(state: &mut GzState) -> Result<(), ()> {
12491249

12501250
// No gzip header. If we were decoding gzip before, the remaining bytes
12511251
// are trailing garbage that can be ignored.
1252-
// FIXME: Add test coverage for this case (which may require the remaining decompression logic).
12531252
if !state.direct {
12541253
state.stream.avail_in = 0;
12551254
state.eof = true;

test-libz-rs-sys/src/gz.rs

Lines changed: 87 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ fn path(prefix: &Path, file: &str) -> String {
2323
path_buf.as_path().to_str().unwrap().to_owned()
2424
}
2525

26+
// Return an open(2) mode, modified as needed to support binary files on the target platform.
27+
fn binary_mode(mode: c_int) -> c_int {
28+
#[cfg(target_os = "windows")]
29+
{
30+
mode | libc::O_BINARY
31+
}
32+
33+
#[cfg(not(target_os = "windows"))]
34+
{
35+
mode
36+
}
37+
}
38+
2639
// Try to gzopen a file path with a specified mode, and panic if the result is unexpected.
2740
// NOTE: This is a macro, instead of a function, so that the test runner will report errors
2841
// with the line number where it is invoked.
@@ -287,6 +300,58 @@ fn gzread_special_cases() {
287300
);
288301
assert_eq!(unsafe { gzclose(file) }, Z_ERRNO);
289302
}
303+
304+
// Create a gzip file with some junk data after the end of the deflate stream.
305+
// gzread should ignore the junk data.
306+
// Create a temporary directory that will be automatically removed when
307+
// temp_dir goes out of scope.
308+
let temp_dir_path = temp_base();
309+
let temp_dir = tempfile::TempDir::new_in(temp_dir_path).unwrap();
310+
let temp_path = temp_dir.path();
311+
let file_name = path(temp_path, "output.gz");
312+
let file = unsafe {
313+
gzopen(
314+
CString::new(file_name.as_str()).unwrap().as_ptr(),
315+
CString::new("w").unwrap().as_ptr(),
316+
)
317+
};
318+
assert!(!file.is_null());
319+
const STRING1: &[u8] = b"deflated contents";
320+
const STRING2: &[u8] = b"\ntrailing data";
321+
assert_eq!(
322+
unsafe { gzwrite(file, STRING1.as_ptr().cast::<c_void>(), STRING1.len() as _) },
323+
STRING1.len() as _
324+
);
325+
assert_eq!(unsafe { gzclose(file) }, Z_OK);
326+
let old_size = file_size(&file_name).unwrap();
327+
let fd = unsafe {
328+
libc::open(
329+
CString::new(file_name.as_str()).unwrap().as_ptr(),
330+
binary_mode(libc::O_APPEND | libc::O_WRONLY),
331+
)
332+
};
333+
assert_ne!(fd, -1);
334+
assert_eq!(
335+
unsafe { libc::write(fd, STRING2.as_ptr().cast::<c_void>(), STRING2.len() as _) },
336+
STRING2.len() as _
337+
);
338+
assert_eq!(unsafe { libc::close(fd) }, 0);
339+
let new_size = file_size(&file_name).unwrap();
340+
assert_eq!(new_size, old_size + STRING2.len());
341+
let file = unsafe {
342+
gzopen(
343+
CString::new(file_name.as_str()).unwrap().as_ptr(),
344+
CString::new("r").unwrap().as_ptr(),
345+
)
346+
};
347+
assert!(!file.is_null());
348+
// Read more than expected to make sure we get everything.
349+
let mut buf = [0u8; STRING1.len() + 1];
350+
assert_eq!(
351+
unsafe { gzread(file, buf.as_mut_ptr().cast::<c_void>(), buf.len() as _) },
352+
STRING1.len() as _
353+
);
354+
assert_eq!(unsafe { gzclose(file) }, Z_OK);
290355
}
291356

292357
#[test]
@@ -720,16 +785,10 @@ fn gzoffset_gztell_read() {
720785
// header. This should affect the return values of gzoffset but not gztell.
721786
const OFFSET: usize = 123;
722787
const PADDING: &[u8] = &[0u8; OFFSET];
723-
let mut mode = libc::O_CREAT;
724-
mode |= libc::O_WRONLY;
725-
#[cfg(target_os = "windows")]
726-
{
727-
mode |= libc::O_BINARY;
728-
}
729788
let fd = unsafe {
730789
libc::open(
731790
CString::new(file_name.as_str()).unwrap().as_ptr(),
732-
mode,
791+
binary_mode(libc::O_CREAT | libc::O_WRONLY),
733792
0o644,
734793
)
735794
};
@@ -739,11 +798,7 @@ fn gzoffset_gztell_read() {
739798
OFFSET as _
740799
);
741800
let source_name = crate_path("src/test-data/issue-109.gz");
742-
mode = libc::O_RDONLY;
743-
#[cfg(target_os = "windows")]
744-
{
745-
mode |= libc::O_BINARY;
746-
}
801+
let mode = binary_mode(libc::O_RDONLY);
747802
let source_fd =
748803
unsafe { libc::open(CString::new(source_name.as_str()).unwrap().as_ptr(), mode) };
749804
assert_ne!(source_fd, -1);
@@ -910,12 +965,7 @@ fn gzputc_basic() {
910965
assert_eq!(unsafe { gzclose(file) }, Z_OK);
911966

912967
// Validate that the file contains the expected bytes.
913-
let mut mode = 0;
914-
#[cfg(target_os = "windows")]
915-
{
916-
mode |= libc::O_BINARY;
917-
}
918-
mode |= libc::O_RDONLY;
968+
let mode = binary_mode(libc::O_RDONLY);
919969
let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) };
920970
assert_ne!(fd, -1);
921971
// Try to read more than the expected amount of data, to ensure we get everything.
@@ -988,12 +1038,7 @@ fn gzputs_basic() {
9881038

9891039
// Validate that the file contains the expected bytes.
9901040
const EXPECTED: &str = "zlib string larger than the buffer size";
991-
let mut mode = 0;
992-
#[cfg(target_os = "windows")]
993-
{
994-
mode |= libc::O_BINARY;
995-
}
996-
mode |= libc::O_RDONLY;
1041+
let mode = binary_mode(libc::O_RDONLY);
9971042
let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) };
9981043
assert_ne!(fd, -1);
9991044
// Try to read more than the expected amount of data, to ensure we get everything.
@@ -1446,12 +1491,7 @@ fn gzfwrite_basic() {
14461491
assert_eq!(unsafe { gzclose(file) }, Z_OK);
14471492

14481493
// Read in the file and verify that the contents match what was passed to gzfwrite.
1449-
let mut mode = 0;
1450-
#[cfg(target_os = "windows")]
1451-
{
1452-
mode |= libc::O_BINARY;
1453-
}
1454-
mode |= libc::O_RDONLY;
1494+
let mode = binary_mode(libc::O_RDONLY);
14551495
let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) };
14561496
assert_ne!(fd, -1);
14571497
const EXPECTED: &[u8] = b"test of gzfwrite";
@@ -1642,16 +1682,10 @@ fn gzseek_read() {
16421682
// all the implementation paths for gzseek.
16431683
let gzip_file_name = crate_path("src/test-data/issue-109.gz");
16441684
let direct_file_name = path(temp_path, "uncompressed");
1645-
let mut mode = libc::O_CREAT;
1646-
#[cfg(target_os = "windows")]
1647-
{
1648-
mode |= libc::O_BINARY;
1649-
}
1650-
mode |= libc::O_WRONLY;
16511685
let fd = unsafe {
16521686
libc::open(
16531687
CString::new(direct_file_name.as_str()).unwrap().as_ptr(),
1654-
mode,
1688+
binary_mode(libc::O_CREAT | libc::O_WRONLY),
16551689
0o644,
16561690
)
16571691
};
@@ -1883,7 +1917,10 @@ fn gzseek_gzsetparams() {
18831917

18841918
// Write some content to the file handle.
18851919
const STRING1: &[u8] = b"hello";
1886-
assert_eq!(unsafe { gzwrite(file, STRING1.as_ptr().cast::<c_void>(), STRING1.len() as _) }, STRING1.len() as _);
1920+
assert_eq!(
1921+
unsafe { gzwrite(file, STRING1.as_ptr().cast::<c_void>(), STRING1.len() as _) },
1922+
STRING1.len() as _
1923+
);
18871924

18881925
// Call gzseek to schedule a pending write of some zeros to the compressed stream.
18891926
const SEEK_AMOUNT: usize = 4;
@@ -1897,7 +1934,10 @@ fn gzseek_gzsetparams() {
18971934
// Write some more content to the file handle. This will end up in the second gzip stream
18981935
// in the file.
18991936
const STRING2: &[u8] = b"world";
1900-
assert_eq!(unsafe { gzwrite(file, STRING2.as_ptr().cast::<c_void>(), STRING2.len() as _) }, STRING2.len() as _);
1937+
assert_eq!(
1938+
unsafe { gzwrite(file, STRING2.as_ptr().cast::<c_void>(), STRING2.len() as _) },
1939+
STRING2.len() as _
1940+
);
19011941

19021942
// Close the file handle to flush any buffered output to the file.
19031943
assert_eq!(unsafe { gzclose(file) }, Z_OK);
@@ -1913,13 +1953,19 @@ fn gzseek_gzsetparams() {
19131953

19141954
// Read back the content to validate that it was written correctly.
19151955
let mut buf = [127u8; STRING1.len()];
1916-
assert_eq!(unsafe { gzread(file, buf.as_mut_ptr().cast::<c_void>(), buf.len() as _) }, buf.len() as _);
1956+
assert_eq!(
1957+
unsafe { gzread(file, buf.as_mut_ptr().cast::<c_void>(), buf.len() as _) },
1958+
buf.len() as _
1959+
);
19171960
assert_eq!(&buf, STRING1);
19181961
for _ in 0..SEEK_AMOUNT {
19191962
assert_eq!(unsafe { gzgetc(file) }, 0);
19201963
}
19211964
let mut buf = [127u8; STRING2.len() + 1];
1922-
assert_eq!(unsafe { gzread(file, buf.as_mut_ptr().cast::<c_void>(), buf.len() as _) }, (buf.len() - 1) as _);
1965+
assert_eq!(
1966+
unsafe { gzread(file, buf.as_mut_ptr().cast::<c_void>(), buf.len() as _) },
1967+
(buf.len() - 1) as _
1968+
);
19231969
assert_eq!(&buf[..STRING2.len()], STRING2);
19241970

19251971
assert_eq!(unsafe { gzclose(file) }, Z_OK);

0 commit comments

Comments
 (0)