diff options
| -rw-r--r-- | debian/changelog | 2 | ||||
| -rw-r--r-- | python/tarfile.cc | 73 |
2 files changed, 45 insertions, 30 deletions
diff --git a/debian/changelog b/debian/changelog index f766ef24..276f1e89 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,8 @@ python-apt (0.7.93.1) UNRELEASED; urgency=low * python/tarfile.cc: - When extracting, only allocate a new buffer if the old one was too small. - Do not segfault if TarFile.go() is called without a member name. + - Clone all pkgDirStream::Item's so apt_pkg.TarMember object can be used + outside of the callback function passed to go(). -- Julian Andres Klode <jak@debian.org> Sat, 23 Jan 2010 15:35:55 +0100 diff --git a/python/tarfile.cc b/python/tarfile.cc index c1e5f48d..775ae22e 100644 --- a/python/tarfile.cc +++ b/python/tarfile.cc @@ -40,8 +40,6 @@ class PyDirStream : public pkgDirStream public: PyObject *callback; - // The current member and data. - CppOwnedPyObject<Item*> *py_member; PyObject *py_data; // The requested member or NULL. const char *member; @@ -58,14 +56,13 @@ public: unsigned long Size,unsigned long Pos); PyDirStream(PyObject *callback, const char *member=0) : callback(callback), - py_member(0), py_data(0), member(member), error(false), copy(0) + py_data(0), member(member), error(false), copy(0) { Py_XINCREF(callback); } virtual ~PyDirStream() { Py_XDECREF(callback); - Py_XDECREF(py_member); Py_XDECREF(py_data); delete[] copy; } @@ -98,33 +95,49 @@ bool PyDirStream::FinishedFile(Item &Itm,int Fd) // Skip non-matching Items, if a specific one is requested. return true; - // Clear the old objects and create new ones. - Py_XDECREF(py_member); Py_XDECREF(py_data); - py_member = CppOwnedPyObject_NEW<Item*>(0, &PyTarMember_Type, &Itm); - py_member->NoDelete = true; py_data = PyBytes_FromStringAndSize(copy, Itm.Size); if (!callback) return true; + + // The current member and data. + CppOwnedPyObject<Item> *py_member; + py_member = CppOwnedPyObject_NEW<Item>(0, &PyTarMember_Type); + // Clone our object, including the strings in it. + py_member->Object = Itm; + py_member->Object.Name = new char[strlen(Itm.Name)+1]; + py_member->Object.LinkTarget = new char[strlen(Itm.LinkTarget)+1]; + strcpy(py_member->Object.Name, Itm.Name); + strcpy(py_member->Object.LinkTarget,Itm.LinkTarget); + py_member->NoDelete = true; error = PyObject_CallFunctionObjArgs(callback, py_member, py_data, 0) == 0; + // Clear the old objects and create new ones. + Py_XDECREF(py_member); return (!error); } +void tarmember_dealloc(PyObject *self) { + // We cloned those strings, delete them again. + delete[] GetCpp<pkgDirStream::Item>(self).Name; + delete[] GetCpp<pkgDirStream::Item>(self).LinkTarget; + CppOwnedDealloc<pkgDirStream::Item>(self); +} + // The tarfile.TarInfo interface for our TarMember class. static PyObject *tarmember_isblk(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::BlockDevice); } static PyObject *tarmember_ischr(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::CharDevice); } static PyObject *tarmember_isdev(PyObject *self, PyObject *args) { - pkgDirStream::Item::Type_t type = GetCpp<pkgDirStream::Item*>(self)->Type; + pkgDirStream::Item::Type_t type = GetCpp<pkgDirStream::Item>(self).Type; return PyBool_FromLong(type == pkgDirStream::Item::CharDevice || type == pkgDirStream::Item::BlockDevice || type == pkgDirStream::Item::FIFO); @@ -132,24 +145,24 @@ static PyObject *tarmember_isdev(PyObject *self, PyObject *args) static PyObject *tarmember_isdir(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::Directory); } static PyObject *tarmember_isfifo(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::FIFO); } static PyObject *tarmember_isfile(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::File); } static PyObject *tarmember_islnk(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::HardLink); } static PyObject *tarmember_isreg(PyObject *self, PyObject *args) @@ -158,58 +171,58 @@ static PyObject *tarmember_isreg(PyObject *self, PyObject *args) } static PyObject *tarmember_issym(PyObject *self, PyObject *args) { - return PyBool_FromLong(GetCpp<pkgDirStream::Item*>(self)->Type == + return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type == pkgDirStream::Item::SymbolicLink); } static PyObject *tarmember_get_name(PyObject *self, void *closure) { - return PyString_FromString(GetCpp<pkgDirStream::Item*>(self)->Name); + return PyString_FromString(GetCpp<pkgDirStream::Item>(self).Name); } static PyObject *tarmember_get_linkname(PyObject *self, void *closure) { - return Safe_FromString(GetCpp<pkgDirStream::Item*>(self)->LinkTarget); + return Safe_FromString(GetCpp<pkgDirStream::Item>(self).LinkTarget); } static PyObject *tarmember_get_mode(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->Mode); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Mode); } static PyObject *tarmember_get_uid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->UID); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).UID); } static PyObject *tarmember_get_gid(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->GID); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).GID); } static PyObject *tarmember_get_size(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->Size); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Size); } static PyObject *tarmember_get_mtime(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->MTime); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).MTime); } static PyObject *tarmember_get_major(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->Major); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Major); } static PyObject *tarmember_get_minor(PyObject *self, void *closure) { - return Py_BuildValue("k", GetCpp<pkgDirStream::Item*>(self)->Minor); + return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Minor); } static PyObject *tarmember_repr(PyObject *self) { return PyString_FromFormat("<%s object: name:'%s'>", self->ob_type->tp_name, - GetCpp<pkgDirStream::Item*>(self)->Name); + GetCpp<pkgDirStream::Item>(self).Name); } @@ -256,10 +269,10 @@ static const char *tarmember_doc = PyTypeObject PyTarMember_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_inst.TarMember", // tp_name - sizeof(CppOwnedPyObject<pkgDirStream::Item*>), // tp_basicsize + sizeof(CppOwnedPyObject<pkgDirStream::Item>), // tp_basicsize 0, // tp_itemsize // Methods - CppOwnedDealloc<pkgDirStream::Item*>, // tp_dealloc + tarmember_dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr @@ -277,8 +290,8 @@ PyTypeObject PyTarMember_Type = { Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_HAVE_GC, tarmember_doc, // tp_doc - CppOwnedTraverse<pkgDirStream::Item*>, // tp_traverse - CppOwnedClear<pkgDirStream::Item*>, // tp_clear + CppOwnedTraverse<pkgDirStream::Item>, // tp_traverse + CppOwnedClear<pkgDirStream::Item>, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter |
