summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog2
-rw-r--r--python/tarfile.cc73
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