mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Fix for mysterious crash in podofo module
This commit is contained in:
parent
5e07f19848
commit
957126c11a
@ -9,13 +9,19 @@
|
|||||||
|
|
||||||
using namespace PoDoFo;
|
using namespace PoDoFo;
|
||||||
|
|
||||||
|
#define NUKE(x) { Py_XDECREF(x); x = NULL; }
|
||||||
|
|
||||||
class pyerr : public std::exception {
|
class pyerr : public std::exception {
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutputDevice : public PdfOutputDevice {
|
class OutputDevice : public PdfOutputDevice {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PyObject *file;
|
PyObject *tell_func;
|
||||||
|
PyObject *seek_func;
|
||||||
|
PyObject *read_func;
|
||||||
|
PyObject *write_func;
|
||||||
|
PyObject *flush_func;
|
||||||
size_t written;
|
size_t written;
|
||||||
|
|
||||||
void update_written() {
|
void update_written() {
|
||||||
@ -25,8 +31,17 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OutputDevice(PyObject *f) : file(f), written(0) { Py_XINCREF(file); }
|
OutputDevice(PyObject *file) : tell_func(0), seek_func(0), read_func(0), write_func(0), flush_func(0), written(0) {
|
||||||
~OutputDevice() { Py_XDECREF(file); file = NULL; }
|
#define GA(f, a) { if((f = PyObject_GetAttrString(file, a)) == NULL) throw pyerr(); }
|
||||||
|
GA(tell_func, "tell");
|
||||||
|
GA(seek_func, "seek");
|
||||||
|
GA(read_func, "read");
|
||||||
|
GA(write_func, "write");
|
||||||
|
GA(flush_func, "flush");
|
||||||
|
}
|
||||||
|
~OutputDevice() {
|
||||||
|
NUKE(tell_func); NUKE(seek_func); NUKE(read_func); NUKE(write_func); NUKE(flush_func);
|
||||||
|
}
|
||||||
|
|
||||||
size_t GetLength() const { return written; }
|
size_t GetLength() const { return written; }
|
||||||
|
|
||||||
@ -87,11 +102,13 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Read( char* pBuffer, size_t lLen ) {
|
size_t Read( char* pBuffer, size_t lLen ) {
|
||||||
PyObject *ret;
|
PyObject *ret, *temp;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
Py_ssize_t len = 0;
|
Py_ssize_t len = 0;
|
||||||
|
|
||||||
ret = PyObject_CallMethod(file, (char*)"read", (char*)"n", static_cast<Py_ssize_t>(lLen));
|
if ((temp = PyInt_FromSize_t(lLen)) == NULL) throw pyerr();
|
||||||
|
ret = PyObject_CallFunctionObjArgs(read_func, temp, NULL);
|
||||||
|
NUKE(temp);
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
if (PyBytes_AsStringAndSize(ret, &buf, &len) != -1) {
|
if (PyBytes_AsStringAndSize(ret, &buf, &len) != -1) {
|
||||||
memcpy(pBuffer, buf, len);
|
memcpy(pBuffer, buf, len);
|
||||||
@ -109,8 +126,10 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Seek(size_t offset) {
|
void Seek(size_t offset) {
|
||||||
PyObject *ret;
|
PyObject *ret, *temp;
|
||||||
ret = PyObject_CallMethod(file, (char*)"seek", (char*)"n", static_cast<Py_ssize_t>(offset));
|
if ((temp = PyInt_FromSize_t(offset)) == NULL) throw pyerr();
|
||||||
|
ret = PyObject_CallFunctionObjArgs(seek_func, temp, NULL);
|
||||||
|
NUKE(temp);
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
if (PyErr_Occurred() == NULL)
|
if (PyErr_Occurred() == NULL)
|
||||||
PyErr_SetString(PyExc_Exception, "Failed to seek in python file object");
|
PyErr_SetString(PyExc_Exception, "Failed to seek in python file object");
|
||||||
@ -123,7 +142,7 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
unsigned long ans;
|
unsigned long ans;
|
||||||
|
|
||||||
ret = PyObject_CallMethod(file, (char*)"tell", NULL);
|
ret = PyObject_CallFunctionObjArgs(tell_func, NULL);
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
if (PyErr_Occurred() == NULL)
|
if (PyErr_Occurred() == NULL)
|
||||||
PyErr_SetString(PyExc_Exception, "Failed to call tell() on python file object");
|
PyErr_SetString(PyExc_Exception, "Failed to call tell() on python file object");
|
||||||
@ -142,9 +161,14 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Write(const char* pBuffer, size_t lLen) {
|
void Write(const char* pBuffer, size_t lLen) {
|
||||||
PyObject *ret;
|
PyObject *ret, *temp = NULL;
|
||||||
|
|
||||||
|
temp = PyBytes_FromStringAndSize(pBuffer, static_cast<Py_ssize_t>(lLen));
|
||||||
|
if (temp == NULL) throw pyerr();
|
||||||
|
|
||||||
|
ret = PyObject_CallFunctionObjArgs(write_func, temp, NULL);
|
||||||
|
NUKE(temp);
|
||||||
|
|
||||||
ret = PyObject_CallMethod(file, (char*)"write", (char*)"s#", pBuffer, (int)lLen);
|
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
if (PyErr_Occurred() == NULL)
|
if (PyErr_Occurred() == NULL)
|
||||||
PyErr_SetString(PyExc_Exception, "Failed to call write() on python file object");
|
PyErr_SetString(PyExc_Exception, "Failed to call write() on python file object");
|
||||||
@ -155,7 +179,7 @@ class OutputDevice : public PdfOutputDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Flush() {
|
void Flush() {
|
||||||
Py_XDECREF(PyObject_CallMethod(file, (char*)"flush", NULL));
|
Py_XDECREF(PyObject_CallFunctionObjArgs(flush_func, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user