From c5ef24bbea51426333038a5b5b621d743fbf2037 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Fri, 11 Feb 2022 22:17:00 +0000 Subject: [PATCH] fix: memory leak in Option::as_ptr --- CHANGELOG.md | 1 + src/conversion.rs | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 627dcf5fae0..a8b3201034f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix panic in `#[pyfunction]` generated code when a required argument following an `Option` was not provided. [#2093](https://github.com/PyO3/pyo3/pull/2093) - Fixed undefined behaviour caused by incorrect `ExactSizeIterator` implementations. [#2124](https://github.com/PyO3/pyo3/pull/2124) - Add missing FFI definitions `_PyLong_NumBits` and `_PyLong_AsByteArray` on PyPy. [#2146](https://github.com/PyO3/pyo3/pull/2146) +- Fix memory leak in implementation of `AsPyPointer` for `Option`. [#2160](https://github.com/PyO3/pyo3/pull/2160) ## [0.15.1] - 2021-11-19 diff --git a/src/conversion.rs b/src/conversion.rs index ccd690bee15..ff4c4b268f2 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -44,7 +44,7 @@ where #[inline] fn as_ptr(&self) -> *mut ffi::PyObject { self.as_ref() - .map_or_else(std::ptr::null_mut, |t| t.into_ptr()) + .map_or_else(std::ptr::null_mut, |t| t.as_ptr()) } } @@ -555,7 +555,7 @@ where #[cfg(test)] mod tests { use crate::types::{IntoPyDict, PyAny, PyDict, PyList}; - use crate::{Python, ToPyObject}; + use crate::{AsPyPointer, PyObject, Python, ToPyObject}; use super::PyTryFrom; @@ -595,4 +595,21 @@ mod tests { assert_eq!(list, val); }); } + + #[test] + fn test_option_as_ptr() { + Python::with_gil(|py| { + let mut option: Option = None; + assert_eq!(option.as_ptr(), std::ptr::null_mut()); + + let none = py.None(); + option = Some(none.clone()); + + let ref_cnt = none.get_refcnt(py); + assert_eq!(option.as_ptr(), none.as_ptr()); + + // Ensure ref count not changed by as_ptr call + assert_eq!(none.get_refcnt(py), ref_cnt); + }); + } }