Blob Blame History Raw
From 3538b0aa88af689284d7d2e84b9f1f375b909ff2 Mon Sep 17 00:00:00 2001
From: Kovid Goyal <kovid@kovidgoyal.net>
Date: Wed, 31 Jul 2019 18:05:19 +0530
Subject: [PATCH 33/71] Cleanup conversion of python strings to podofo strings

---
 src/calibre/utils/podofo/doc.cpp     | 40 +++++++++++-----------------
 src/calibre/utils/podofo/global.h    | 11 +++-----
 src/calibre/utils/podofo/outline.cpp | 14 +++++-----
 src/calibre/utils/podofo/utils.cpp   | 30 ++++++++-------------
 4 files changed, 38 insertions(+), 57 deletions(-)

diff --git a/src/calibre/utils/podofo/doc.cpp b/src/calibre/utils/podofo/doc.cpp
index 8eb48d97f9..60bb6d69b9 100644
--- a/src/calibre/utils/podofo/doc.cpp
+++ b/src/calibre/utils/podofo/doc.cpp
@@ -243,35 +243,35 @@ static PyObject *
 PDFDoc_create_outline(PDFDoc *self, PyObject *args) {
     PyObject *p;
     PDFOutlineItem *ans;
-    PdfString *title;
     int pagenum;
 
     if (!PyArg_ParseTuple(args, "Ui", &p, &pagenum)) return NULL;
-    title = podofo_convert_pystring(p);
-    if (title == NULL) return NULL;
 
     ans = PyObject_New(PDFOutlineItem, &PDFOutlineItemType);
     if (ans == NULL) goto error;
 
     try {
+        const PdfString title = podofo_convert_pystring(p);
         PdfOutlines *outlines = self->doc->GetOutlines();
         if (outlines == NULL) {PyErr_NoMemory(); goto error;}
-        ans->item = outlines->CreateRoot(*title);
+        ans->item = outlines->CreateRoot(title);
         if (ans->item == NULL) {PyErr_NoMemory(); goto error;}
         ans->doc = self->doc;
         PdfDestination dest(self->doc->GetPage(pagenum));
         ans->item->SetDestination(dest);
     } catch(const PdfError & err) {
         podofo_set_exception(err); goto error;
+    } catch(const std::exception & err) {
+        PyErr_Format(PyExc_ValueError, "An error occurred while trying to create the outline: %s", err.what());
+        goto error;
     } catch (...) {
         PyErr_SetString(PyExc_ValueError, "An unknown error occurred while trying to create the outline");
         goto error;
     }
 
-    delete title;
     return (PyObject*)ans;
 error:
-    Py_XDECREF(ans); delete title;
+    Py_XDECREF(ans);
     return NULL;
 
 } // }}}
@@ -427,33 +427,25 @@ PDFDoc_setter(PDFDoc *self, PyObject *val, int field) {
         PyErr_SetString(PyExc_ValueError, "Must use unicode objects to set metadata");
         return -1;
     }
-    PdfInfo *info = new PdfInfo(*self->doc->GetInfo());
-    if (info == NULL) {
-        PyErr_SetString(PyExc_Exception, "You must first load a PDF Document");
-        return -1;
-    }
-    PdfString *s = NULL;
-
-    if (self->doc->GetEncrypted()) s = podofo_convert_pystring_single_byte(val);
-    else s = podofo_convert_pystring(val);
-    if (s == NULL) return -1;
-
+    PdfInfo *info = self->doc->GetInfo();
+    if (!info) { PyErr_SetString(Error, "You must first load a PDF Document"); return -1; }
+    const PdfString s = podofo_convert_pystring(val);
 
     switch (field) {
         case 0:
-            info->SetTitle(*s); break;
+            info->SetTitle(s); break;
         case 1:
-            info->SetAuthor(*s); break;
+            info->SetAuthor(s); break;
         case 2:
-            info->SetSubject(*s); break;
+            info->SetSubject(s); break;
         case 3:
-            info->SetKeywords(*s); break;
+            info->SetKeywords(s); break;
         case 4:
-            info->SetCreator(*s); break;
+            info->SetCreator(s); break;
         case 5:
-            info->SetProducer(*s); break;
+            info->SetProducer(s); break;
         default:
-            PyErr_SetString(PyExc_Exception, "Bad field");
+            PyErr_SetString(Error, "Bad field");
             return -1;
     }
 
diff --git a/src/calibre/utils/podofo/global.h b/src/calibre/utils/podofo/global.h
index 4a180d86a0..6d97159c18 100644
--- a/src/calibre/utils/podofo/global.h
+++ b/src/calibre/utils/podofo/global.h
@@ -37,11 +37,8 @@ extern PyTypeObject PDFOutlineItemType;
 extern PyObject *Error;
 
 // Utilities
-extern void podofo_set_exception(const PdfError &err);
-extern PyObject * podofo_convert_pdfstring(const PdfString &s);
-extern PdfString * podofo_convert_pystring(PyObject *py);
-extern PdfString * podofo_convert_pystring_single_byte(PyObject *py);
-extern PyObject* write_doc(PdfMemDocument *doc, PyObject *f);
-
+void podofo_set_exception(const PdfError &err);
+PyObject * podofo_convert_pdfstring(const PdfString &s);
+const PdfString podofo_convert_pystring(PyObject *py);
+PyObject* write_doc(PdfMemDocument *doc, PyObject *f);
 }
-
diff --git a/src/calibre/utils/podofo/outline.cpp b/src/calibre/utils/podofo/outline.cpp
index 01a3b186d9..d7a4d8a79b 100644
--- a/src/calibre/utils/podofo/outline.cpp
+++ b/src/calibre/utils/podofo/outline.cpp
@@ -47,36 +47,36 @@ create(PDFOutlineItem *self, PyObject *args) {
     PyObject *ptitle, *as_child = NULL;
     PDFOutlineItem *ans;
     int num;
-    PdfString *title;
     PdfPage *page;
 
     if (!PyArg_ParseTuple(args, "Ui|O", &ptitle, &num, &as_child)) return NULL;
-    title = podofo_convert_pystring(ptitle);
-    if (title == NULL) return NULL;
 
     ans = PyObject_New(PDFOutlineItem, &PDFOutlineItemType);
     if (ans == NULL) goto error;
     ans->doc = self->doc;
 
     try {
+        const PdfString title = podofo_convert_pystring(ptitle);
         page = self->doc->GetPage(num);
         if (page == NULL) { PyErr_Format(PyExc_ValueError, "Invalid page number: %d", num); goto error; }
         PdfDestination dest(page);
         if (as_child != NULL && PyObject_IsTrue(as_child)) {
-            ans->item = self->item->CreateChild(*title, dest);
+            ans->item = self->item->CreateChild(title, dest);
         } else
-            ans->item = self->item->CreateNext(*title, dest);
+            ans->item = self->item->CreateNext(title, dest);
     } catch (const PdfError &err) {
         podofo_set_exception(err); goto error;
+    } catch(const std::exception & err) {
+        PyErr_Format(PyExc_ValueError, "An error occurred while trying to create the outline: %s", err.what());
+        goto error;
     } catch (...) {
         PyErr_SetString(PyExc_Exception, "An unknown error occurred while trying to create the outline item");
         goto error;
     }
 
-    delete title;
     return (PyObject*) ans;
 error:
-    Py_XDECREF(ans); delete title;
+    Py_XDECREF(ans);
     return NULL;
 }
 
diff --git a/src/calibre/utils/podofo/utils.cpp b/src/calibre/utils/podofo/utils.cpp
index 6ecf1ec7fd..830fc5052e 100644
--- a/src/calibre/utils/podofo/utils.cpp
+++ b/src/calibre/utils/podofo/utils.cpp
@@ -28,23 +28,15 @@ pdf::podofo_convert_pdfstring(const PdfString &s) {
     return PyUnicode_FromString(s.GetStringUtf8().c_str());
 }
 
-PdfString *
-pdf::podofo_convert_pystring(PyObject *py) {
-    PyObject *u8 = PyUnicode_AsEncodedString(py, "UTF-8", "replace");
-    if (u8 == NULL) { return NULL; }
-    pdf_utf8 *s8 = reinterpret_cast<pdf_utf8 *>(PyBytes_AS_STRING(u8));
-    PdfString *ans = new PdfString(s8);
-    Py_DECREF(u8);
-    if (ans == NULL) PyErr_NoMemory();
-    return ans;
-}
-
-PdfString *
-pdf::podofo_convert_pystring_single_byte(PyObject *py) {
-    PyObject *s = PyUnicode_AsEncodedString(py, "cp1252", "replace");
-    if (s == NULL) { return NULL; }
-    PdfString *ans = new PdfString(PyBytes_AS_STRING(s));
-    Py_DECREF(s);
-    if (ans == NULL) PyErr_NoMemory();
-    return ans;
+const PdfString
+pdf::podofo_convert_pystring(PyObject *val) {
+#if PY_MAJOR_VERSION > 2
+    return s(reinterpret_cast<const pdf_utf8*>(PyUnicode_AsUTF8(val)));
+#else
+    PyObject *temp = PyUnicode_AsUTF8String(val);
+    if (!temp) throw std::bad_alloc();
+    PdfString s(reinterpret_cast<const pdf_utf8*>(PyBytes_AS_STRING(temp)));
+    Py_DECREF(temp);
+    return s;
+#endif
 }