Skip to content

Commit 91f54b2

Browse files
authored
Merge pull request #36 from omeg/omeg/fix-str-leak
Fix temporary object leak in MyString_AsEncodedPath()
2 parents 2bd2229 + 14f9f8f commit 91f54b2

1 file changed

Lines changed: 55 additions & 16 deletions

File tree

fuseparts/_fusemodule.c

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,29 +85,39 @@
8585
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
8686
#if PY_MINOR_VERSION >= 6
8787
#define FIX_PATH_DECODING
88+
8889
PyObject* Path_AsDecodedUnicode(void* path) {
8990
if (path) {
9091
return PyUnicode_DecodeFSDefault(path);
91-
goto ERROR;
9292
}
93-
ERROR:
9493
PyErr_SetString(PyExc_ValueError, "non-decodable filename");
9594
return NULL;
9695
}
9796

98-
char* MyString_AsEncodedPath(PyObject *unicode) {
99-
return PyBytes_AsString(PyUnicode_EncodeFSDefault(unicode));
100-
}
101-
102-
// use appropriate utf-8 conversion
103-
#define PyString_AsString MyString_AsEncodedPath
10497
#else
10598
#define PyString_AsString PyUnicode_AsUTF8
10699
#endif
107100
#define PyString_Check PyUnicode_Check
108101
#define PyString_Size PyUnicode_GET_SIZE
109102
#endif
110103

104+
#ifdef FIX_PATH_DECODING
105+
// use appropriate utf-8 conversion
106+
#define PATH_AS_STR_BEGIN(py_obj, str) \
107+
PyObject *py_bytes_tmp = PyUnicode_EncodeFSDefault(py_obj); \
108+
str = PyBytes_AsString(py_bytes_tmp);
109+
#else
110+
#define PATH_AS_STR_BEGIN(py_obj, str) \
111+
str = PyString_AsString(py_obj);
112+
#endif
113+
114+
#ifdef FIX_PATH_DECODING
115+
#define PATH_AS_STR_END \
116+
Py_DECREF(py_bytes_tmp);
117+
#else
118+
#define PATH_AS_STR_END
119+
#endif
120+
111121
static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *readdir_cb=NULL,
112122
*mknod_cb=NULL, *mkdir_cb=NULL, *unlink_cb=NULL, *rmdir_cb=NULL,
113123
*symlink_cb=NULL, *rename_cb=NULL, *link_cb=NULL, *chmod_cb=NULL,
@@ -362,8 +372,10 @@ readlink_func(const char *path, char *link, size_t size)
362372
ret = -EINVAL;
363373
goto OUT_DECREF;
364374
}
365-
s = PyString_AsString(v);
375+
376+
PATH_AS_STR_BEGIN(v, s);
366377
strncpy(link, s, size);
378+
PATH_AS_STR_END;
367379
link[size-1] = '\0';
368380
ret = 0;
369381

@@ -443,14 +455,16 @@ dir_add_entry(PyObject *v, fuse_dirh_t buf, fuse_dirfil_t df)
443455
goto OUT_DECREF;
444456
}
445457

458+
char *s;
459+
PATH_AS_STR_BEGIN(pytmp, s);
446460
#if FUSE_VERSION >= 23
447-
ret = df(buf, PyString_AsString(pytmp), &st, offs.offset);
461+
ret = df(buf, s, &st, offs.offset);
448462
#elif FUSE_VERSION >= 21
449-
ret = df(buf, PyString_AsString(pytmp), (st.st_mode & 0170000) >> 12,
450-
st.st_ino);
463+
ret = df(buf, s, (st.st_mode & 0170000) >> 12, st.st_ino);
451464
#else
452-
ret = df(buf, PyString_AsString(pytmp), (st.st_mode & 0170000) >> 12);
465+
ret = df(buf, s, (st.st_mode & 0170000) >> 12);
453466
#endif
467+
PATH_AS_STR_END;
454468
Py_DECREF(pytmp);
455469

456470
OUT_DECREF:
@@ -923,7 +937,10 @@ getxattr_func(const char *path, const char *name, char *value, size_t size)
923937
goto OUT_DECREF;
924938
}
925939

926-
memcpy(value, PyString_AsString(v), PyString_Size(v));
940+
char *s;
941+
PATH_AS_STR_BEGIN(v, s);
942+
memcpy(value, s, PyString_Size(v));
943+
PATH_AS_STR_END;
927944
ret = PyString_Size(v);
928945
}
929946

@@ -970,7 +987,10 @@ listxattr_func(const char *path, char *list, size_t size)
970987
break;
971988
}
972989

973-
strncpy(lx, PyString_AsString(w), ilen + 1);
990+
char *s;
991+
PATH_AS_STR_BEGIN(w, s);
992+
strncpy(lx, s, ilen + 1);
993+
PATH_AS_STR_END;
974994
lx += ilen + 1;
975995

976996
Py_DECREF(w);
@@ -1407,6 +1427,11 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
14071427
fargv = malloc(fargc * sizeof(char *));
14081428
if (!fargv)
14091429
return(PyErr_NoMemory());
1430+
#ifdef FIX_PATH_DECODING
1431+
PyObject **tmp_bytes = malloc(fargc * sizeof(PyObject *));
1432+
if (!tmp_bytes)
1433+
return(PyErr_NoMemory());
1434+
#endif
14101435

14111436
if (fargseq) {
14121437
for (i=0; i < fargc; i++) {
@@ -1420,7 +1445,12 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
14201445
"fuse argument is not a string");
14211446
return(NULL);
14221447
}
1448+
#ifdef FIX_PATH_DECODING
1449+
tmp_bytes[i] = PyUnicode_EncodeFSDefault(pa);
1450+
fargv[i] = PyBytes_AsString(tmp_bytes[i]);
1451+
#else
14231452
fargv[i] = PyString_AsString(pa);
1453+
#endif
14241454

14251455
Py_DECREF(pa);
14261456
}
@@ -1438,6 +1468,14 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
14381468
#else
14391469
fuse = __fuse_setup(fargc, fargv, &op, &fmp, &mthp, &fd);
14401470
#endif
1471+
1472+
#ifdef FIX_PATH_DECODING
1473+
for (i=0; i < fargc; i++)
1474+
Py_DECREF(tmp_bytes[i]);
1475+
1476+
free(tmp_bytes);
1477+
#endif
1478+
14411479
free(fargv);
14421480

14431481
if (fuse == NULL) {
@@ -1503,9 +1541,10 @@ FuseInvalidate(PyObject *self, PyObject *args)
15031541
return(NULL);
15041542
}
15051543

1506-
path = PyString_AsString(arg1);
1544+
PATH_AS_STR_BEGIN(arg1, path);
15071545

15081546
err = fuse_invalidate(fuse, path);
1547+
PATH_AS_STR_END;
15091548

15101549
ret = PyInt_FromLong(err);
15111550

0 commit comments

Comments
 (0)