Skip to content

Commit 89a4b84

Browse files
committed
libarchive-c: fix seek() handling
seek() handling had two problems: - seek callback had too short lifetime: it was garbage collected before C code gets executed during archive iteration. - seek callback had wrong prototype: context pointer was passed as 'int' As a result test suite was occasionally crashing in NixOS: ============================= test session starts ============================== platform linux -- Python 3.9.6, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 rootdir: /build/source collected 33 items tests/test_atime_mtime_ctime.py ........ [ 24%] tests/test_convert.py . [ 27%] tests/test_entry.py ....... [ 48%] tests/test_errors.py .... [ 60%] tests/test_rwx.py ... Program received signal SIGSEGV, Segmentation fault. 0x00007fffe9314381 in classify_argument () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 0 0x00007fffe9314381 in classify_argument () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 1 0x00007fffe9315462 in ffi_closure_unix64_inner () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 2 0x00007fffe93159a0 in ffi_closure_unix64 () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 3 0x00007fffe9226287 in __archive_read_filter_seek () from /nix/store/...-libarchive-3.5.2-lib/lib/libarchive.so 4 0x00007fffe925ff8a in archive_read_format_zip_seekable_bid () from /nix/store/...-libarchive-3.5.2-lib/lib/libarchive.so 5 0x00007fffe92265e5 in archive_read_open1 () from /nix/store/...-libarchive-3.5.2-lib/lib/libarchive.so 6 0x00007fffe931580a in ffi_call_unix64 () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 7 0x00007fffe9314943 in ffi_call_int () from /nix/store/...-libffi-3.4.2/lib/libffi.so.8 8 0x00007fffe932e015 in _ctypes_callproc () from /nix/store/...-python3-3.9.6/lib/python3.9/lib-dynload/_ctypes.cpython-39-x86_64-linux-gnu.so 9 0x00007fffe932f992 in PyCFuncPtr_call () from /nix/store/...-python3-3.9.6/lib/python3.9/lib-dynload/_ctypes.cpython-39-x86_64-linux-gnu.so 10 0x00007ffff7ca0750 in _PyObject_MakeTpCall () from /nix/store/...-python3-3.9.6/lib/libpython3.9.so.1.0 11 0x00007ffff7c57f36 in _PyEval_EvalFrameDefault () from /nix/store/...-python3-3.9.6/lib/libpython3.9.so.1.0 ... The change fixes crashes for me.
1 parent 222f41a commit 89a4b84

2 files changed

Lines changed: 3 additions & 2 deletions

File tree

libarchive/ffi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
c_ssize_t, c_void_p, c_void_p, POINTER(c_void_p)
4848
)
4949
SEEK_CALLBACK = CFUNCTYPE(
50-
c_longlong, c_int, c_void_p, c_longlong, c_int
50+
c_longlong, c_void_p, c_void_p, c_longlong, c_int
5151
)
5252
OPEN_CALLBACK = CFUNCTYPE(c_int, c_void_p, c_void_p)
5353
CLOSE_CALLBACK = CFUNCTYPE(c_int, c_void_p, c_void_p)

libarchive/read.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,10 @@ def seek_func(archive_p, context, offset, whence):
143143
open_cb = NO_OPEN_CB
144144
read_cb = READ_CALLBACK(read_func)
145145
close_cb = NO_CLOSE_CB
146+
seek_cb = SEEK_CALLBACK(seek_func)
146147
with new_archive_read(format_name, filter_name, passphrase) as archive_p:
147148
if stream.seekable():
148-
ffi.read_set_seek_callback(archive_p, SEEK_CALLBACK(seek_func))
149+
ffi.read_set_seek_callback(archive_p, seek_cb)
149150
ffi.read_open(archive_p, None, open_cb, read_cb, close_cb)
150151
yield ArchiveRead(archive_p)
151152

0 commit comments

Comments
 (0)