summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2022-10-26 22:44:13 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-11-05 08:32:05 +0000
commit9e7610f972f3ba770dae3a99ec7a803171396165 (patch)
treecbaf72f0ae512a401b13f5028e113e84f56b7640 /Lib
parent24b0e6839113d69a7d60cd30d7b17cbdbd325355 (diff)
downloadswig-9e7610f972f3ba770dae3a99ec7a803171396165.tar.gz
Fix memory leak in R shared_ptr wrappers
Fix leak when a cast up a class inheritance chain is required. Adds implementation of SWIG_ConvertPtrAndOwn for R. Closes #2386
Diffstat (limited to 'Lib')
-rw-r--r--Lib/r/rrun.swg18
-rw-r--r--Lib/r/std_vector.i4
2 files changed, 16 insertions, 6 deletions
diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg
index 798446128..3ffc02f28 100644
--- a/Lib/r/rrun.swg
+++ b/Lib/r/rrun.swg
@@ -15,8 +15,9 @@ extern "C" {
#endif
/* for raw pointer */
+#define SWIG_R_ConvertPtr(obj, pptr, type, flags) SWIG_R_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_R_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_R_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_R_ConvertPtrAndOwn(obj, pptr, type, flags, own)
#define SWIG_NewPointerObj(ptr, type, flags) SWIG_R_NewPointerObj(ptr, type, flags)
#include <stdio.h>
@@ -314,9 +315,11 @@ SWIG_R_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
/* Convert a pointer value */
SWIGRUNTIMEINLINE int
-SWIG_R_ConvertPtr(SEXP obj, void **ptr, swig_type_info *ty, int flags) {
+SWIG_R_ConvertPtrAndOwn(SEXP obj, void **ptr, swig_type_info *ty, int flags, int *own) {
void *vptr;
if (!obj) return SWIG_ERROR;
+ if (own)
+ *own = 0;
if (obj == R_NilValue) {
if (ptr) *ptr = NULL;
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
@@ -331,8 +334,15 @@ SWIG_R_ConvertPtr(SEXP obj, void **ptr, swig_type_info *ty, int flags) {
} else {
swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
int newmemory = 0;
- if (ptr) *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc, vptr, &newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
}
} else {
if (ptr) *ptr = vptr;
diff --git a/Lib/r/std_vector.i b/Lib/r/std_vector.i
index 62478fe6a..98840c5dc 100644
--- a/Lib/r/std_vector.i
+++ b/Lib/r/std_vector.i
@@ -544,7 +544,7 @@
struct traits_asptr < std::vector<T> > {
static int asptr(SEXP obj, std::vector<T> **val) {
std::vector<T> *p;
- int res = SWIG_R_ConvertPtr(obj, (void**)&p, type_info< std::vector<T> >(), 0);
+ int res = SWIG_ConvertPtr(obj, (void**)&p, type_info< std::vector<T> >(), 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
@@ -827,7 +827,7 @@
static int asptr(SEXP obj, std::vector< std::vector<T> > **val) {
std::vector< std::vector<T> > *p;
Rprintf("vector of vectors - unsupported content\n");
- int res = SWIG_R_ConvertPtr(obj, (void**)&p, type_info< std::vector< std::vector<T> > > (), 0);
+ int res = SWIG_ConvertPtr(obj, (void**)&p, type_info< std::vector< std::vector<T> > > (), 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
}