Check to see if object is None before traversing

Closes #2915

When using the C API directly, the intended way to call `visitproc` is
via the `Py_VISIT` macro, which checks to see that the provided pointer
is not null before passing it along to `visitproc`. Because PyO3 isn't
using the macro, it needs to manually check that the pointer isn't null.
Without this check, calling `visit.call(&obj)` where `let obj = None;`
will segfault.
This commit is contained in:
Nate Kent 2023-01-26 11:21:20 -08:00
parent 98b12973fc
commit f38841a8e2
No known key found for this signature in database
GPG key ID: 8B0077E00820E61C
2 changed files with 10 additions and 4 deletions

View file

@ -0,0 +1 @@
Traversal visit calls to `Option<T: AsPyPointer>` no longer segfaults when `None`.

View file

@ -23,11 +23,16 @@ impl<'p> PyVisit<'p> {
where
T: AsPyPointer,
{
let r = unsafe { (self.visit)(obj.as_ptr(), self.arg) };
if r == 0 {
Ok(())
let ptr = obj.as_ptr();
if !ptr.is_null() {
let r = unsafe { (self.visit)(ptr, self.arg) };
if r == 0 {
Ok(())
} else {
Err(PyTraverseError(r))
}
} else {
Err(PyTraverseError(r))
Ok(())
}
}