diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 30a51c02..ed7d3eb6 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -490,11 +490,16 @@ jobs: RUSTFLAGS: "-Ctarget-feature=+avx2,+bmi2,+bmi1" - name: Test allocator with miri run: "cargo +nightly miri nextest run -j4 -p zlib-rs --target ${{ matrix.target }} allocate::" - - name: Test gz logic with miri + - name: Test gz internals with miri working-directory: libz-rs-sys-cdylib run: "cargo +nightly miri nextest run -j4 -p libz-rs-sys-cdylib --target ${{ matrix.target }} --features=gz" env: MIRIFLAGS: "-Zmiri-tree-borrows -Zmiri-disable-isolation" + - name: Test gz api with miri + if: ${{ contains(matrix.target, 'linux') }} + run: "cargo +nightly miri nextest run -j4 -p test-libz-rs-sys --target ${{ matrix.target }} gz::" + env: + MIRIFLAGS: "-Zmiri-no-short-fd-operations -Zmiri-disable-isolation" miri-avx512: name: "Miri avx512" diff --git a/libz-rs-sys-cdylib/src/gz.rs b/libz-rs-sys-cdylib/src/gz.rs index f3ca173b..db69293a 100644 --- a/libz-rs-sys-cdylib/src/gz.rs +++ b/libz-rs-sys-cdylib/src/gz.rs @@ -2588,7 +2588,7 @@ pub unsafe extern "C-unwind" fn gzseek64( // Rewind, then skip to offset. // Safety: `file` points to an initialized `GzState`. - if unsafe { gzrewind(file) } == -1 { + if unsafe { gzrewind_help(state) } == -1 { return -1; } } @@ -2665,6 +2665,10 @@ pub unsafe extern "C-unwind" fn gzrewind(file: gzFile) -> c_int { return -1; }; + unsafe { gzrewind_help(state) } +} + +unsafe fn gzrewind_help(state: &mut GzState) -> c_int { // Check that we're reading and that there's no error. if state.mode != GzMode::GZ_READ || (state.err != Z_OK && state.err != Z_BUF_ERROR) { return -1; diff --git a/test-libz-rs-sys/src/gz.rs b/test-libz-rs-sys/src/gz.rs index f26ee364..913801e1 100644 --- a/test-libz-rs-sys/src/gz.rs +++ b/test-libz-rs-sys/src/gz.rs @@ -964,15 +964,8 @@ fn gzputc_basic() { assert_eq!(unsafe { gzclose(file) }, Z_OK); // Validate that the file contains the expected bytes. - let mode = binary_mode(libc::O_RDONLY); - let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) }; - assert_ne!(fd, -1); - // Try to read more than the expected amount of data, to ensure we get everything. - let mut buf = [0u8; CONTENT.len() + 1]; - let bytes_read = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as _) }; - assert_ne!(bytes_read, -1); - assert_eq!(&buf[..bytes_read as usize], CONTENT); - assert_eq!(unsafe { libc::close(fd) }, 0); + let actual = std::fs::read(file_name).unwrap(); + assert_eq!(actual, CONTENT); } #[test] @@ -1036,15 +1029,8 @@ fn gzputs_basic() { // Validate that the file contains the expected bytes. const EXPECTED: &str = "zlib string larger than the buffer size"; - let mode = binary_mode(libc::O_RDONLY); - let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) }; - assert_ne!(fd, -1); - // Try to read more than the expected amount of data, to ensure we get everything. - let mut buf = [0u8; EXPECTED.len() + 1]; - let bytes_read = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as _) }; - assert_ne!(bytes_read, -1); - assert_eq!(&buf[..bytes_read as usize], EXPECTED.as_bytes()); - assert_eq!(unsafe { libc::close(fd) }, 0); + let actual = std::fs::read(file_name).unwrap(); + assert_eq!(actual, EXPECTED.as_bytes()); } #[test] @@ -1489,16 +1475,9 @@ fn gzfwrite_basic() { assert_eq!(unsafe { gzclose(file) }, Z_OK); // Read in the file and verify that the contents match what was passed to gzfwrite. - let mode = binary_mode(libc::O_RDONLY); - let fd = unsafe { libc::open(CString::new(file_name.as_str()).unwrap().as_ptr(), mode) }; - assert_ne!(fd, -1); const EXPECTED: &[u8] = b"test of gzfwrite"; - let mut buf = [0u8; EXPECTED.len() + 1]; - let ret = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as _) }; - assert_eq!(ret, EXPECTED.len() as _); - assert_eq!(&buf[..EXPECTED.len()], EXPECTED); - - assert_eq!(unsafe { libc::close(fd) }, 0); + let actual = std::fs::read(file_name).unwrap(); + assert_eq!(actual, EXPECTED); } #[test] @@ -2033,25 +2012,8 @@ fn gzrewind_error() { // // - `Ok(size)` on success. // - `Err` on error. -fn file_size(path: &str) -> Result { - let mut result = Err(()); - let stat_ptr = unsafe { libc::calloc(1, core::mem::size_of::() as _) }; - if stat_ptr.is_null() { - return result; - } - let ret = unsafe { - libc::stat( - CString::new(path).unwrap().as_ptr(), - stat_ptr.cast::(), - ) - }; - if ret == 0 { - if let Some(stat_info) = unsafe { stat_ptr.cast::().as_ref() } { - result = Ok(stat_info.st_size as usize); - } - } - unsafe { libc::free(stat_ptr) }; - result +fn file_size(path: &str) -> Result { + Ok(std::fs::metadata(path)?.len() as usize) } #[cfg(feature = "gzprintf")]