diff mbox series

[meta-oe,kirkstone,1/1] poppler: fix CVE-2025-52886

Message ID 20250716144033.1780473-1-yogita.urade@windriver.com
State New
Headers show
Series [meta-oe,kirkstone,1/1] poppler: fix CVE-2025-52886 | expand

Commit Message

yurade July 16, 2025, 2:40 p.m. UTC
From: Yogita Urade <yogita.urade@windriver.com>

Poppler is a PDF rendering library. Versions prior to 25.06.0
use `std::atomic_int` for reference counting. Because
`std::atomic_int` is only 32 bits, it is possible to overflow
the reference count and trigger a use-after-free. Version 25.06.0
patches the issue.

CVE-2025-52886-0001 and CVE-2025-52886-0002 are dependent commits
while rest are actual CVE fixes.

References:
https://nvd.nist.gov/vuln/detail/CVE-2025-52886
https://security-tracker.debian.org/tracker/CVE-2025-52886

Upstream patches:
https://gitlab.freedesktop.org/poppler/poppler/-/commit/d35e11a8f84d396a9d9ef43ef852d377adc3830a
https://gitlab.freedesktop.org/poppler/poppler/-/commit/af3e1e1a3577c4e1c66cbe69ebdc6a632038e299
https://gitlab.freedesktop.org/poppler/poppler/-/commit/3449a16d3b1389870eb3e20795e802c6ae8bc04f
https://gitlab.freedesktop.org/poppler/poppler/-/commit/ac36affcc8486de38e8905a8d6547a3464ff46e5

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 .../poppler/poppler/CVE-2025-52886-0001.patch |  318 ++
 .../poppler/poppler/CVE-2025-52886-0002.patch |  108 +
 .../poppler/poppler/CVE-2025-52886-0003.patch | 4201 +++++++++++++++++
 .../poppler/poppler/CVE-2025-52886-0004.patch |   58 +
 .../poppler/poppler_22.04.0.bb                |    4 +
 5 files changed, 4689 insertions(+)
 create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0001.patch
 create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0002.patch
 create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0003.patch
 create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0004.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0001.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0001.patch
new file mode 100644
index 0000000000..d7d5921943
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0001.patch
@@ -0,0 +1,318 @@ 
+From d35e11a8f84d396a9d9ef43ef852d377adc3830a Mon Sep 17 00:00:00 2001
+From: Albert Astals Cid <aacid@kde.org>
+Date: Fri, 1 Apr 2022 16:26:25 +0200
+Subject: [PATCH] Annots: Just return the std::vector instead of two getters
+
+Simpler code to use and solves the int vs size_t mismatch by not having a
+type involved at all
+
+CVE: CVE-2025-52886
+Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/d35e11a8f84d396a9d9ef43ef852d377adc3830a]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ glib/poppler-page.cc          |  5 +----
+ poppler/Annot.cc              |  4 ++--
+ poppler/Annot.h               |  5 ++---
+ poppler/FontInfo.cc           |  4 ++--
+ poppler/Form.cc               |  7 +++----
+ poppler/JSInfo.cc             | 14 +++++++-------
+ poppler/Link.cc               |  3 +--
+ poppler/PSOutputDev.cc        |  4 ++--
+ poppler/Page.cc               | 17 ++++-------------
+ qt5/src/poppler-annotation.cc | 10 ++--------
+ qt6/src/poppler-annotation.cc | 10 ++--------
+ utils/pdfdetach.cc            |  4 +---
+ 12 files changed, 29 insertions(+), 58 deletions(-)
+
+diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
+index d075502..f0b7245 100644
+--- a/glib/poppler-page.cc
++++ b/glib/poppler-page.cc
+@@ -1285,7 +1285,6 @@ GList *poppler_page_get_annot_mapping(PopplerPage *page)
+ {
+     GList *map_list = nullptr;
+     double width, height;
+-    gint i;
+     Annots *annots;
+     const PDFRectangle *crop_box;
+
+@@ -1299,14 +1298,12 @@ GList *poppler_page_get_annot_mapping(PopplerPage *page)
+     poppler_page_get_size(page, &width, &height);
+     crop_box = page->page->getCropBox();
+
+-    for (i = 0; i < annots->getNumAnnots(); i++) {
++    for (Annot *annot : annots->getAnnots()) {
+         PopplerAnnotMapping *mapping;
+         PopplerRectangle rect;
+-        Annot *annot;
+         gboolean flag_no_rotate;
+         gint rotation = 0;
+
+-        annot = annots->getAnnot(i);
+         flag_no_rotate = annot->getFlags() & Annot::flagNoRotate;
+
+         /* Create the mapping */
+diff --git a/poppler/Annot.cc b/poppler/Annot.cc
+index 60c023d..366e7de 100644
+--- a/poppler/Annot.cc
++++ b/poppler/Annot.cc
+@@ -1087,8 +1087,8 @@ void AnnotAppearance::removeStream(Ref refToStream)
+             continue;
+         }
+         Annots *annots = page->getAnnots();
+-        for (int i = 0; i < annots->getNumAnnots(); ++i) {
+-            AnnotAppearance *annotAp = annots->getAnnot(i)->getAppearStreams();
++        for (Annot *annot : annots->getAnnots()) {
++            AnnotAppearance *annotAp = annot->getAppearStreams();
+             if (annotAp && annotAp != this && annotAp->referencesStream(refToStream)) {
+                 return; // Another annotation points to the stream -> Don't delete it
+             }
+diff --git a/poppler/Annot.h b/poppler/Annot.h
+index 9ae274d..8d1f18b 100644
+--- a/poppler/Annot.h
++++ b/poppler/Annot.h
+@@ -1766,9 +1766,8 @@ public:
+     Annots(const Annots &) = delete;
+     Annots &operator=(const Annots &) = delete;
+
+-    // Iterate through list of annotations.
+-    int getNumAnnots() const { return annots.size(); }
+-    Annot *getAnnot(int i) { return annots[i]; }
++    const std::vector<Annot *> &getAnnots() { return annots; }
++
+     void appendAnnot(Annot *annot);
+     bool removeAnnot(Annot *annot);
+
+diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
+index 23425f6..309ec6d 100644
+--- a/poppler/FontInfo.cc
++++ b/poppler/FontInfo.cc
+@@ -82,8 +82,8 @@ std::vector<FontInfo *> FontInfoScanner::scan(int nPages)
+             delete resDict;
+         }
+         annots = page->getAnnots();
+-        for (int i = 0; i < annots->getNumAnnots(); ++i) {
+-            Object obj1 = annots->getAnnot(i)->getAppearanceResDict();
++        for (Annot *annot : annots->getAnnots()) {
++            Object obj1 = annot->getAppearanceResDict();
+             if (obj1.isDict()) {
+                 scanFonts(xrefA.get(), obj1.getDict(), &result);
+             }
+diff --git a/poppler/Form.cc b/poppler/Form.cc
+index 97b5be0..b88972a 100644
+--- a/poppler/Form.cc
++++ b/poppler/Form.cc
+@@ -2732,14 +2732,13 @@ FormPageWidgets::FormPageWidgets(Annots *annots, unsigned int page, Form *form)
+     widgets = nullptr;
+     size = 0;
+
+-    if (annots && annots->getNumAnnots() > 0 && form) {
+-        size = annots->getNumAnnots();
++    if (annots && !annots->getAnnots().empty() > 0 && form) {
++        size = annots->getAnnots().size();
+         widgets = (FormWidget **)greallocn(widgets, size, sizeof(FormWidget *));
+
+         /* For each entry in the page 'Annots' dict, try to find
+            a matching form field */
+-        for (int i = 0; i < size; ++i) {
+-            Annot *annot = annots->getAnnot(i);
++        for (Annot *annot : annots->getAnnots()) {
+
+             if (annot->getType() != Annot::typeWidget) {
+                 continue;
+diff --git a/poppler/JSInfo.cc b/poppler/JSInfo.cc
+index 6607085..eaef33e 100644
+--- a/poppler/JSInfo.cc
++++ b/poppler/JSInfo.cc
+@@ -191,15 +191,15 @@ void JSInfo::scan(int nPages)
+         }
+         // annotation actions (links, screen, widget)
+         annots = page->getAnnots();
+-        for (int i = 0; i < annots->getNumAnnots(); ++i) {
+-            if (annots->getAnnot(i)->getType() == Annot::typeLink) {
+-                AnnotLink *annot = static_cast<AnnotLink *>(annots->getAnnot(i));
++        for (Annot *a : annots->getAnnots()) {
++            if (a->getType() == Annot::typeLink) {
++                AnnotLink *annot = static_cast<AnnotLink *>(a);
+                 scanLinkAction(annot->getAction(), "Link Annotation Activated");
+                 if (onlyFirstJS && hasJS) {
+                     return;
+                 }
+-            } else if (annots->getAnnot(i)->getType() == Annot::typeScreen) {
+-                AnnotScreen *annot = static_cast<AnnotScreen *>(annots->getAnnot(i));
++            } else if (a->getType() == Annot::typeScreen) {
++                AnnotScreen *annot = static_cast<AnnotScreen *>(a);
+                 scanLinkAction(annot->getAction(), "Screen Annotation Activated");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Screen Annotation Cursor Enter");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Screen Annotation Cursor Leave");
+@@ -215,8 +215,8 @@ void JSInfo::scan(int nPages)
+                 if (onlyFirstJS && hasJS) {
+                     return;
+                 }
+-            } else if (annots->getAnnot(i)->getType() == Annot::typeWidget) {
+-                AnnotWidget *annot = static_cast<AnnotWidget *>(annots->getAnnot(i));
++            } else if (a->getType() == Annot::typeWidget) {
++                AnnotWidget *annot = static_cast<AnnotWidget *>(a);
+                 scanLinkAction(annot->getAction(), "Widget Annotation Activated");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Widget Annotation Cursor Enter");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Widget Annotation Cursor Leave");
+diff --git a/poppler/Link.cc b/poppler/Link.cc
+index b2e48cb..8aca0b9 100644
+--- a/poppler/Link.cc
++++ b/poppler/Link.cc
+@@ -890,8 +890,7 @@ Links::Links(Annots *annots)
+         return;
+     }
+
+-    for (int i = 0; i < annots->getNumAnnots(); ++i) {
+-        Annot *annot = annots->getAnnot(i);
++    for (Annot *annot : annots->getAnnots()) {
+
+         if (annot->getType() != Annot::typeLink) {
+             continue;
+diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
+index 111b472..9db6229 100644
+--- a/poppler/PSOutputDev.cc
++++ b/poppler/PSOutputDev.cc
+@@ -1745,8 +1745,8 @@ void PSOutputDev::writeDocSetup(Catalog *catalog, const std::vector<int> &pageLi
+             setupResources(resDict);
+         }
+         annots = page->getAnnots();
+-        for (int i = 0; i < annots->getNumAnnots(); ++i) {
+-            Object obj1 = annots->getAnnot(i)->getAppearanceResDict();
++        for (Annot *annot : annots->getAnnots()) {
++            Object obj1 = annot->getAppearanceResDict();
+             if (obj1.isDict()) {
+                 setupResources(obj1.getDict());
+             }
+diff --git a/poppler/Page.cc b/poppler/Page.cc
+index 727dd28..6b33500 100644
+--- a/poppler/Page.cc
++++ b/poppler/Page.cc
+@@ -367,16 +367,9 @@ void Page::replaceXRef(XRef *xrefA)
+ /* Loads standalone fields into Page, should be called once per page only */
+ void Page::loadStandaloneFields(Annots *annotations, Form *form)
+ {
+-    const int numAnnots = annotations ? annotations->getNumAnnots() : 0;
+-
+-    if (numAnnots < 1) {
+-        return;
+-    }
+-
+     /* Look for standalone annots, identified by being: 1) of type Widget
+      * 2) not referenced from the Catalog's Form Field array */
+-    for (int i = 0; i < numAnnots; ++i) {
+-        Annot *annot = annotations->getAnnot(i);
++    for (Annot *annot : annots->getAnnots()) {
+
+         if (annot->getType() != Annot::typeWidget || !annot->getHasRef()) {
+             continue;
+@@ -564,7 +557,6 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, int rotate, bo
+ {
+     Gfx *gfx;
+     Annots *annotList;
+-    int i;
+
+     if (!out->checkPageSlice(this, hDPI, vDPI, rotate, useMediaBox, crop, sliceX, sliceY, sliceW, sliceH, printing, abortCheckCbk, abortCheckCbkData, annotDisplayDecideCbk, annotDisplayDecideCbkData)) {
+         return;
+@@ -591,14 +583,13 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, int rotate, bo
+     // draw annotations
+     annotList = getAnnots();
+
+-    if (annotList->getNumAnnots() > 0) {
++    if (!annotList->getAnnots().empty()) {
+         if (globalParams->getPrintCommands()) {
+             printf("***** Annotations\n");
+         }
+-        for (i = 0; i < annotList->getNumAnnots(); ++i) {
+-            Annot *annot = annotList->getAnnot(i);
++        for (Annot *annot : annots->getAnnots()) {
+             if ((annotDisplayDecideCbk && (*annotDisplayDecideCbk)(annot, annotDisplayDecideCbkData)) || !annotDisplayDecideCbk) {
+-                annotList->getAnnot(i)->draw(gfx, printing);
++                annot->draw(gfx, printing);
+             }
+         }
+         out->dump();
+diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc
+index ab45673..cdf25da 100644
+--- a/qt5/src/poppler-annotation.cc
++++ b/qt5/src/poppler-annotation.cc
+@@ -438,10 +438,6 @@ AnnotPath *AnnotationPrivate::toAnnotPath(const QLinkedList<QPointF> &list) cons
+ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, DocumentData *doc, const QSet<Annotation::SubType> &subtypes, int parentID)
+ {
+     Annots *annots = pdfPage->getAnnots();
+-    const uint numAnnotations = annots->getNumAnnots();
+-    if (numAnnotations == 0) {
+-        return QList<Annotation *>();
+-    }
+
+     const bool wantTextAnnotations = subtypes.isEmpty() || subtypes.contains(Annotation::AText);
+     const bool wantLineAnnotations = subtypes.isEmpty() || subtypes.contains(Annotation::ALine);
+@@ -459,11 +455,9 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+
+     // Create Annotation objects and tie to their native Annot
+     QList<Annotation *> res;
+-    for (uint k = 0; k < numAnnotations; k++) {
+-        // get the j-th annotation
+-        Annot *ann = annots->getAnnot(k);
++    for (Annot *ann : annots->getAnnots()) {
+         if (!ann) {
+-            error(errInternal, -1, "Annot {0:ud} is null", k);
++            error(errInternal, -1, "Annot is null");
+             continue;
+         }
+
+diff --git a/qt6/src/poppler-annotation.cc b/qt6/src/poppler-annotation.cc
+index b92b76b..5770be6 100644
+--- a/qt6/src/poppler-annotation.cc
++++ b/qt6/src/poppler-annotation.cc
+@@ -360,10 +360,6 @@ AnnotPath *AnnotationPrivate::toAnnotPath(const QVector<QPointF> &list) const
+ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Page *pdfPage, DocumentData *doc, const QSet<Annotation::SubType> &subtypes, int parentID)
+ {
+     Annots *annots = pdfPage->getAnnots();
+-    const uint numAnnotations = annots->getNumAnnots();
+-    if (numAnnotations == 0) {
+-        return std::vector<std::unique_ptr<Annotation>>();
+-    }
+
+     const bool wantTextAnnotations = subtypes.isEmpty() || subtypes.contains(Annotation::AText);
+     const bool wantLineAnnotations = subtypes.isEmpty() || subtypes.contains(Annotation::ALine);
+@@ -381,11 +377,9 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+
+     // Create Annotation objects and tie to their native Annot
+     std::vector<std::unique_ptr<Annotation>> res;
+-    for (uint k = 0; k < numAnnotations; k++) {
+-        // get the j-th annotation
+-        Annot *ann = annots->getAnnot(k);
++    for (Annot *ann : annots->getAnnots()) {
+         if (!ann) {
+-            error(errInternal, -1, "Annot {0:ud} is null", k);
++            error(errInternal, -1, "Annot is null");
+             continue;
+         }
+
+diff --git a/utils/pdfdetach.cc b/utils/pdfdetach.cc
+index 61c3728..247c2c1 100644
+--- a/utils/pdfdetach.cc
++++ b/utils/pdfdetach.cc
+@@ -85,7 +85,6 @@ int main(int argc, char *argv[])
+     int nFiles, nPages, n, i, j;
+     Page *page;
+     Annots *annots;
+-    Annot *annot;
+     const GooString *s1;
+     Unicode u;
+     bool isUnicode;
+@@ -151,8 +150,7 @@ int main(int argc, char *argv[])
+             break;
+         }
+
+-        for (j = 0; j < annots->getNumAnnots(); ++j) {
+-            annot = annots->getAnnot(j);
++        for (Annot *annot : annots->getAnnots()) {
+             if (annot->getType() != Annot::typeFileAttachment) {
+                 continue;
+             }
+--
+2.40.0
diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0002.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0002.patch
new file mode 100644
index 0000000000..5c8b6c0a8b
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0002.patch
@@ -0,0 +1,108 @@ 
+From af3e1e1a3577c4e1c66cbe69ebdc6a632038e299 Mon Sep 17 00:00:00 2001
+From: Albert Astals Cid <aacid@kde.org>
+Date: Fri, 1 Apr 2022 16:03:46 +0200
+Subject: [PATCH] Link: Just return the std::vector instead of two getters
+
+Simpler code to use and solves the int vs size_t mismatch by not having a
+type involved at all
+
+CVE: CVE-2025-52886
+Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/af3e1e1a3577c4e1c66cbe69ebdc6a632038e299]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ glib/poppler-page.cc   | 5 +----
+ poppler/Link.h         | 4 +---
+ poppler/Page.cc        | 4 ++--
+ utils/HtmlOutputDev.cc | 4 ++--
+ utils/pdfinfo.cc       | 3 +--
+ 5 files changed, 7 insertions(+), 13 deletions(-)
+
+diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
+index f0b7245..a9515f3 100644
+--- a/glib/poppler-page.cc
++++ b/glib/poppler-page.cc
+@@ -1119,7 +1119,6 @@ static void poppler_page_init(PopplerPage *page) { }
+ GList *poppler_page_get_link_mapping(PopplerPage *page)
+ {
+     GList *map_list = nullptr;
+-    gint i;
+     Links *links;
+     double width, height;
+
+@@ -1133,13 +1132,11 @@ GList *poppler_page_get_link_mapping(PopplerPage *page)
+
+     poppler_page_get_size(page, &width, &height);
+
+-    for (i = 0; i < links->getNumLinks(); i++) {
++    for (AnnotLink *link : links->getLinks()) {
+         PopplerLinkMapping *mapping;
+         PopplerRectangle rect;
+         LinkAction *link_action;
+-        AnnotLink *link;
+
+-        link = links->getLink(i);
+         link_action = link->getAction();
+
+         /* Create the mapping */
+diff --git a/poppler/Link.h b/poppler/Link.h
+index 0c4677c..204207b 100644
+--- a/poppler/Link.h
++++ b/poppler/Link.h
+@@ -555,9 +555,7 @@ public:
+     Links(const Links &) = delete;
+     Links &operator=(const Links &) = delete;
+
+-    // Iterate through list of links.
+-    int getNumLinks() const { return links.size(); }
+-    AnnotLink *getLink(int i) const { return links[i]; }
++    const std::vector<AnnotLink *> &getLinks() const { return links; }
+
+ private:
+     std::vector<AnnotLink *> links;
+diff --git a/poppler/Page.cc b/poppler/Page.cc
+index 6b33500..c256d39 100644
+--- a/poppler/Page.cc
++++ b/poppler/Page.cc
+@@ -778,8 +778,8 @@ void Page::makeBox(double hDPI, double vDPI, int rotate, bool useMediaBox, bool
+ void Page::processLinks(OutputDev *out)
+ {
+     std::unique_ptr<Links> links = getLinks();
+-    for (int i = 0; i < links->getNumLinks(); ++i) {
+-        out->processLink(links->getLink(i));
++    for (AnnotLink *link : links->getLinks()) {
++        out->processLink(link);
+     }
+ }
+
+diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
+index 71fe672..2056188 100644
+--- a/utils/HtmlOutputDev.cc
++++ b/utils/HtmlOutputDev.cc
+@@ -1247,8 +1247,8 @@ void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref)
+ void HtmlOutputDev::endPage()
+ {
+     std::unique_ptr<Links> linksList = docPage->getLinks();
+-    for (int i = 0; i < linksList->getNumLinks(); ++i) {
+-        doProcessLink(linksList->getLink(i));
++    for (AnnotLink *link : linksList->getLinks()) {
++        doProcessLink(link);
+     }
+
+     pages->conv();
+diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
+index 4b9166f..5f96b41 100644
+--- a/utils/pdfinfo.cc
++++ b/utils/pdfinfo.cc
+@@ -415,8 +415,7 @@ static void printUrlList(PDFDoc *doc)
+         Page *page = doc->getPage(pg);
+         if (page) {
+             std::unique_ptr<Links> links = page->getLinks();
+-            for (int i = 0; i < links->getNumLinks(); i++) {
+-                AnnotLink *annot = links->getLink(i);
++            for (AnnotLink *annot : links->getLinks()) {
+                 LinkAction *action = annot->getAction();
+                 if (action->getKind() == actionURI) {
+                     LinkURI *linkUri = dynamic_cast<LinkURI *>(action);
+--
+2.40.0
diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0003.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0003.patch
new file mode 100644
index 0000000000..11cd286223
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0003.patch
@@ -0,0 +1,4201 @@ 
+From 3449a16d3b1389870eb3e20795e802c6ae8bc04f Mon Sep 17 00:00:00 2001
+From: Sune Vuorela <sune@vuorela.dk>
+Date: Wed, 2 Apr 2025 16:19:28 +0200
+Subject: [PATCH] Annot: Do refcount with shared_ptr
+
+Manage annots by shared_ptr rather than the manual ref/deref usage.
+
+Also do a bit more documentation of ownerships with unique ptr's
+
+CVE: CVE-2025-52886
+Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/3449a16d3b1389870eb3e20795e802c6ae8bc04f]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ glib/poppler-annot.cc                | 132 +++++----
+ glib/poppler-page.cc                 |   8 +-
+ glib/poppler-private.h               |  22 +-
+ poppler/Annot.cc                     | 143 ++++------
+ poppler/Annot.h                      |  34 +--
+ poppler/FontInfo.cc                  |   2 +-
+ poppler/Form.cc                      |  11 +-
+ poppler/Form.h                       |   6 +-
+ poppler/JSInfo.cc                    |   8 +-
+ poppler/Link.cc                      |  13 +-
+ poppler/Link.h                       |   4 +-
+ poppler/PDFDoc.cc                    |   2 +-
+ poppler/PSOutputDev.cc               |   2 +-
+ poppler/Page.cc                      |  39 ++-
+ poppler/Page.h                       |   8 +-
+ qt5/src/poppler-annotation-private.h |  10 +-
+ qt5/src/poppler-annotation.cc        | 385 ++++++++++++--------------
+ qt5/src/poppler-form.cc              |   4 +-
+ qt6/src/poppler-annotation-private.h |  10 +-
+ qt6/src/poppler-annotation.cc        | 393 +++++++++++++--------------
+ qt6/src/poppler-form.cc              |   4 +-
+ utils/HtmlOutputDev.cc               |   4 +-
+ utils/pdfdetach.cc                   |   4 +-
+ utils/pdfinfo.cc                     |   2 +-
+ 24 files changed, 564 insertions(+), 686 deletions(-)
+
+diff --git a/glib/poppler-annot.cc b/glib/poppler-annot.cc
+index 2c9a760..33a0709 100644
+--- a/glib/poppler-annot.cc
++++ b/glib/poppler-annot.cc
+@@ -19,6 +19,7 @@
+  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+  */
+
++#include "AnnotStampImageHelper.h"
+ #include "config.h"
+ #include "poppler.h"
+ #include "poppler-private.h"
+@@ -166,13 +167,12 @@ G_DEFINE_TYPE(PopplerAnnotLine, poppler_annot_line, POPPLER_TYPE_ANNOT_MARKUP)
+ G_DEFINE_TYPE(PopplerAnnotCircle, poppler_annot_circle, POPPLER_TYPE_ANNOT_MARKUP)
+ G_DEFINE_TYPE(PopplerAnnotSquare, poppler_annot_square, POPPLER_TYPE_ANNOT_MARKUP)
+
+-static PopplerAnnot *_poppler_create_annot(GType annot_type, Annot *annot)
++static PopplerAnnot *_poppler_create_annot(GType annot_type, std::shared_ptr<Annot> annot)
+ {
+     PopplerAnnot *poppler_annot;
+
+     poppler_annot = POPPLER_ANNOT(g_object_new(annot_type, nullptr));
+-    poppler_annot->annot = annot;
+-    annot->incRefCnt();
++    poppler_annot->annot = std::move(annot);
+
+     return poppler_annot;
+ }
+@@ -182,8 +182,7 @@ static void poppler_annot_finalize(GObject *object)
+     PopplerAnnot *poppler_annot = POPPLER_ANNOT(object);
+
+     if (poppler_annot->annot) {
+-        poppler_annot->annot->decRefCnt();
+-        poppler_annot->annot = nullptr;
++        poppler_annot->annot.reset();
+     }
+
+     G_OBJECT_CLASS(poppler_annot_parent_class)->finalize(object);
+@@ -198,7 +197,7 @@ static void poppler_annot_class_init(PopplerAnnotClass *klass)
+     gobject_class->finalize = poppler_annot_finalize;
+ }
+
+-PopplerAnnot *_poppler_annot_new(Annot *annot)
++PopplerAnnot *_poppler_annot_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT, annot);
+ }
+@@ -211,7 +210,7 @@ static void poppler_annot_text_init(PopplerAnnotText *poppler_annot) { }
+
+ static void poppler_annot_text_class_init(PopplerAnnotTextClass *klass) { }
+
+-PopplerAnnot *_poppler_annot_text_new(Annot *annot)
++PopplerAnnot *_poppler_annot_text_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT, annot);
+ }
+@@ -231,15 +230,14 @@ PopplerAnnot *_poppler_annot_text_new(Annot *annot)
+  */
+ PopplerAnnot *poppler_annot_text_new(PopplerDocument *doc, PopplerRectangle *rect)
+ {
+-    Annot *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+-    annot = new AnnotText(doc->doc, &pdf_rect);
++    auto annot = std::make_shared<AnnotText>(doc->doc, &pdf_rect);
+
+     return _poppler_annot_text_new(annot);
+ }
+
+-PopplerAnnot *_poppler_annot_text_markup_new(Annot *annot)
++PopplerAnnot *_poppler_annot_text_markup_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT_MARKUP, annot);
+ }
+@@ -312,10 +310,9 @@ static void poppler_annot_text_markup_class_init(PopplerAnnotTextMarkupClass *kl
+ PopplerAnnot *poppler_annot_text_markup_new_highlight(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
+ {
+     PopplerAnnot *poppler_annot;
+-    AnnotTextMarkup *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+-    annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeHighlight);
++    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeHighlight);
+
+     poppler_annot = _poppler_annot_text_markup_new(annot);
+     poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
+@@ -339,12 +336,11 @@ PopplerAnnot *poppler_annot_text_markup_new_highlight(PopplerDocument *doc, Popp
+ PopplerAnnot *poppler_annot_text_markup_new_squiggly(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
+ {
+     PopplerAnnot *poppler_annot;
+-    AnnotTextMarkup *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+     g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
+
+-    annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeSquiggly);
++    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeSquiggly);
+
+     poppler_annot = _poppler_annot_text_markup_new(annot);
+     poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
+@@ -368,12 +364,11 @@ PopplerAnnot *poppler_annot_text_markup_new_squiggly(PopplerDocument *doc, Poppl
+ PopplerAnnot *poppler_annot_text_markup_new_strikeout(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
+ {
+     PopplerAnnot *poppler_annot;
+-    AnnotTextMarkup *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+     g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
+
+-    annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeStrikeOut);
++    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeStrikeOut);
+
+     poppler_annot = _poppler_annot_text_markup_new(annot);
+     poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
+@@ -397,12 +392,11 @@ PopplerAnnot *poppler_annot_text_markup_new_strikeout(PopplerDocument *doc, Popp
+ PopplerAnnot *poppler_annot_text_markup_new_underline(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
+ {
+     PopplerAnnot *poppler_annot;
+-    AnnotTextMarkup *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+     g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
+
+-    annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeUnderline);
++    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeUnderline);
+
+     poppler_annot = _poppler_annot_text_markup_new(annot);
+     poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
+@@ -413,7 +407,7 @@ static void poppler_annot_free_text_init(PopplerAnnotFreeText *poppler_annot) {
+
+ static void poppler_annot_free_text_class_init(PopplerAnnotFreeTextClass *klass) { }
+
+-PopplerAnnot *_poppler_annot_free_text_new(Annot *annot)
++PopplerAnnot *_poppler_annot_free_text_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_FREE_TEXT, annot);
+ }
+@@ -422,7 +416,7 @@ static void poppler_annot_file_attachment_init(PopplerAnnotFileAttachment *poppl
+
+ static void poppler_annot_file_attachment_class_init(PopplerAnnotFileAttachmentClass *klass) { }
+
+-PopplerAnnot *_poppler_annot_file_attachment_new(Annot *annot)
++PopplerAnnot *_poppler_annot_file_attachment_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_FILE_ATTACHMENT, annot);
+ }
+@@ -448,13 +442,13 @@ static void poppler_annot_movie_class_init(PopplerAnnotMovieClass *klass)
+     gobject_class->finalize = poppler_annot_movie_finalize;
+ }
+
+-PopplerAnnot *_poppler_annot_movie_new(Annot *annot)
++PopplerAnnot *_poppler_annot_movie_new(const std::shared_ptr<Annot> &annot)
+ {
+     PopplerAnnot *poppler_annot;
+     AnnotMovie *annot_movie;
+
+     poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_MOVIE, annot);
+-    annot_movie = static_cast<AnnotMovie *>(poppler_annot->annot);
++    annot_movie = static_cast<AnnotMovie *>(poppler_annot->annot.get());
+     POPPLER_ANNOT_MOVIE(poppler_annot)->movie = _poppler_movie_new(annot_movie->getMovie());
+
+     return poppler_annot;
+@@ -481,14 +475,14 @@ static void poppler_annot_screen_class_init(PopplerAnnotScreenClass *klass)
+     gobject_class->finalize = poppler_annot_screen_finalize;
+ }
+
+-PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, Annot *annot)
++PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, const std::shared_ptr<Annot> &annot)
+ {
+     PopplerAnnot *poppler_annot;
+     AnnotScreen *annot_screen;
+     LinkAction *action;
+
+     poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_SCREEN, annot);
+-    annot_screen = static_cast<AnnotScreen *>(poppler_annot->annot);
++    annot_screen = static_cast<AnnotScreen *>(poppler_annot->annot.get());
+     action = annot_screen->getAction();
+     if (action) {
+         POPPLER_ANNOT_SCREEN(poppler_annot)->action = _poppler_action_new(doc, action, nullptr);
+@@ -497,7 +491,7 @@ PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, Annot *annot)
+     return poppler_annot;
+ }
+
+-PopplerAnnot *_poppler_annot_line_new(Annot *annot)
++PopplerAnnot *_poppler_annot_line_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_LINE, annot);
+ }
+@@ -524,17 +518,16 @@ static void poppler_annot_line_class_init(PopplerAnnotLineClass *klass) { }
+ PopplerAnnot *poppler_annot_line_new(PopplerDocument *doc, PopplerRectangle *rect, PopplerPoint *start, PopplerPoint *end)
+ {
+     PopplerAnnot *poppler_annot;
+-    Annot *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+-    annot = new AnnotLine(doc->doc, &pdf_rect);
++    auto annot = std::make_shared<AnnotLine>(doc->doc, &pdf_rect);
+
+     poppler_annot = _poppler_annot_line_new(annot);
+     poppler_annot_line_set_vertices(POPPLER_ANNOT_LINE(poppler_annot), start, end);
+     return poppler_annot;
+ }
+
+-PopplerAnnot *_poppler_annot_circle_new(Annot *annot)
++PopplerAnnot *_poppler_annot_circle_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_CIRCLE, annot);
+ }
+@@ -558,15 +551,14 @@ static void poppler_annot_circle_class_init(PopplerAnnotCircleClass *klass) { }
+  **/
+ PopplerAnnot *poppler_annot_circle_new(PopplerDocument *doc, PopplerRectangle *rect)
+ {
+-    Annot *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+-    annot = new AnnotGeometry(doc->doc, &pdf_rect, Annot::typeCircle);
++    auto annot = std::make_shared<AnnotGeometry>(doc->doc, &pdf_rect, Annot::typeCircle);
+
+     return _poppler_annot_circle_new(annot);
+ }
+
+-PopplerAnnot *_poppler_annot_square_new(Annot *annot)
++PopplerAnnot *_poppler_annot_square_new(const std::shared_ptr<Annot> &annot)
+ {
+     return _poppler_create_annot(POPPLER_TYPE_ANNOT_SQUARE, annot);
+ }
+@@ -590,10 +582,9 @@ static void poppler_annot_square_class_init(PopplerAnnotSquareClass *klass) { }
+  **/
+ PopplerAnnot *poppler_annot_square_new(PopplerDocument *doc, PopplerRectangle *rect)
+ {
+-    Annot *annot;
+     PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
+
+-    annot = new AnnotGeometry(doc->doc, &pdf_rect, Annot::typeSquare);
++    auto annot = std::make_shared<AnnotGeometry>(doc->doc, &pdf_rect, Annot::typeSquare);
+
+     return _poppler_annot_square_new(annot);
+ }
+@@ -982,7 +973,7 @@ void poppler_annot_set_rectangle(PopplerAnnot *poppler_annot, PopplerRectangle *
+     if (page && SUPPORTED_ROTATION(page->getRotate())) {
+         /* annot is inside a rotated page, as core poppler rect must be saved
+          * un-rotated, let's proceed to un-rotate rect before saving */
+-        _unrotate_rect_for_annot_and_page(page, poppler_annot->annot, &x1, &y1, &x2, &y2);
++        _unrotate_rect_for_annot_and_page(page, poppler_annot->annot.get(), &x1, &y1, &x2, &y2);
+     }
+
+     poppler_annot->annot->setRect(x1 + crop_box->x1, y1 + crop_box->y1, x2 + crop_box->x1, y2 + crop_box->y1);
+@@ -1004,7 +995,7 @@ gchar *poppler_annot_markup_get_label(PopplerAnnotMarkup *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     text = annot->getLabel();
+
+@@ -1028,7 +1019,7 @@ void poppler_annot_markup_set_label(PopplerAnnotMarkup *poppler_annot, const gch
+
+     g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     tmp = label ? g_convert(label, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr;
+     annot->setLabel(std::make_unique<GooString>(tmp, length));
+@@ -1051,7 +1042,7 @@ gboolean poppler_annot_markup_has_popup(PopplerAnnotMarkup *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     return annot->getPopup() != nullptr;
+ }
+@@ -1073,8 +1064,8 @@ void poppler_annot_markup_set_popup(PopplerAnnotMarkup *poppler_annot, PopplerRe
+
+     g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
+-    annot->setPopup(std::make_unique<AnnotPopup>(annot->getDoc(), &pdf_rect));
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
++    annot->setPopup(std::make_shared<AnnotPopup>(annot->getDoc(), &pdf_rect));
+ }
+
+ /**
+@@ -1093,9 +1084,9 @@ gboolean poppler_annot_markup_get_popup_is_open(PopplerAnnotMarkup *poppler_anno
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+-    if ((annot_popup = annot->getPopup())) {
++    if ((annot_popup = annot->getPopup().get())) {
+         return annot_popup->getOpen();
+     }
+
+@@ -1118,9 +1109,9 @@ void poppler_annot_markup_set_popup_is_open(PopplerAnnotMarkup *poppler_annot, g
+
+     g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+-    annot_popup = annot->getPopup();
++    annot_popup = annot->getPopup().get();
+     if (!annot_popup) {
+         return;
+     }
+@@ -1149,8 +1140,8 @@ gboolean poppler_annot_markup_get_popup_rectangle(PopplerAnnotMarkup *poppler_an
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
+     g_return_val_if_fail(poppler_rect != nullptr, FALSE);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
+-    annot_popup = annot->getPopup();
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
++    annot_popup = annot->getPopup().get();
+     if (!annot_popup) {
+         return FALSE;
+     }
+@@ -1184,8 +1175,8 @@ void poppler_annot_markup_set_popup_rectangle(PopplerAnnotMarkup *poppler_annot,
+     g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
+     g_return_if_fail(poppler_rect != nullptr);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
+-    annot_popup = annot->getPopup();
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
++    annot_popup = annot->getPopup().get();
+     if (!annot_popup) {
+         return;
+     }
+@@ -1208,7 +1199,7 @@ gdouble poppler_annot_markup_get_opacity(PopplerAnnotMarkup *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), 0);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     return annot->getOpacity();
+ }
+@@ -1230,7 +1221,7 @@ void poppler_annot_markup_set_opacity(PopplerAnnotMarkup *poppler_annot, gdouble
+
+     g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     annot->setOpacity(opacity);
+ }
+
+@@ -1251,7 +1242,7 @@ GDate *poppler_annot_markup_get_date(PopplerAnnotMarkup *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     annot_date = annot->getDate();
+     if (!annot_date) {
+         return nullptr;
+@@ -1284,7 +1275,7 @@ gchar *poppler_annot_markup_get_subject(PopplerAnnotMarkup *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     text = annot->getSubject();
+
+@@ -1305,7 +1296,7 @@ PopplerAnnotMarkupReplyType poppler_annot_markup_get_reply_to(PopplerAnnotMarkup
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_MARKUP_REPLY_TYPE_R);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     switch (annot->getReplyTo()) {
+     case AnnotMarkup::replyTypeR:
+@@ -1333,7 +1324,7 @@ PopplerAnnotExternalDataType poppler_annot_markup_get_external_data(PopplerAnnot
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN);
+
+-    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     switch (annot->getExData()) {
+     case annotExternalDataMarkup3D:
+@@ -1363,7 +1354,7 @@ gboolean poppler_annot_text_get_is_open(PopplerAnnotText *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), FALSE);
+
+-    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     return annot->getOpen();
+ }
+@@ -1383,7 +1374,7 @@ void poppler_annot_text_set_is_open(PopplerAnnotText *poppler_annot, gboolean is
+
+     g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));
+
+-    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     annot->setOpen(is_open);
+ }
+
+@@ -1402,7 +1393,7 @@ gchar *poppler_annot_text_get_icon(PopplerAnnotText *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     text = annot->getIcon();
+
+@@ -1455,7 +1446,7 @@ void poppler_annot_text_set_icon(PopplerAnnotText *poppler_annot, const gchar *i
+
+     g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));
+
+-    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     text = new GooString(icon);
+     annot->setIcon(text);
+@@ -1476,7 +1467,7 @@ PopplerAnnotTextState poppler_annot_text_get_state(PopplerAnnotText *poppler_ann
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), POPPLER_ANNOT_TEXT_STATE_UNKNOWN);
+
+-    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     switch (annot->getState()) {
+     case AnnotText::stateUnknown:
+@@ -1523,7 +1514,7 @@ void poppler_annot_text_markup_set_quadrilaterals(PopplerAnnotTextMarkup *popple
+     g_return_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot));
+     g_return_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0);
+
+-    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     crop_box = _poppler_annot_get_cropbox_and_page(POPPLER_ANNOT(poppler_annot), &page);
+     quads = create_annot_quads_from_poppler_quads(quadrilaterals);
+
+@@ -1562,7 +1553,7 @@ GArray *poppler_annot_text_markup_get_quadrilaterals(PopplerAnnotTextMarkup *pop
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     crop_box = _poppler_annot_get_cropbox(POPPLER_ANNOT(poppler_annot));
+     AnnotQuadrilaterals *quads = annot->getQuadrilaterals();
+
+@@ -1584,7 +1575,7 @@ PopplerAnnotFreeTextQuadding poppler_annot_free_text_get_quadding(PopplerAnnotFr
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED);
+
+-    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     switch (annot->getQuadding()) {
+     case VariableTextQuadding::leftJustified:
+@@ -1618,7 +1609,7 @@ PopplerAnnotCalloutLine *poppler_annot_free_text_get_callout_line(PopplerAnnotFr
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     if ((line = annot->getCalloutLine())) {
+         AnnotCalloutMultiLine *multiline;
+@@ -1662,11 +1653,10 @@ PopplerAttachment *poppler_annot_file_attachment_get_attachment(PopplerAnnotFile
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+-    FileSpec *file = new FileSpec(annot->getFile());
+-    attachment = _poppler_attachment_new(file);
+-    delete file;
++    FileSpec file { annot->getFile() };
++    attachment = _poppler_attachment_new(&file);
+
+     return attachment;
+ }
+@@ -1688,7 +1678,7 @@ gchar *poppler_annot_file_attachment_get_name(PopplerAnnotFileAttachment *popple
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     name = annot->getName();
+
+     return name ? _poppler_goo_string_to_utf8(name) : nullptr;
+@@ -1760,7 +1750,7 @@ gchar *poppler_annot_movie_get_title(PopplerAnnotMovie *poppler_annot)
+
+     g_return_val_if_fail(POPPLER_IS_ANNOT_MOVIE(poppler_annot), NULL);
+
+-    annot = static_cast<AnnotMovie *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotMovie *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     title = annot->getTitle();
+
+@@ -1819,7 +1809,7 @@ void poppler_annot_line_set_vertices(PopplerAnnotLine *poppler_annot, PopplerPoi
+     g_return_if_fail(start != nullptr);
+     g_return_if_fail(end != nullptr);
+
+-    annot = static_cast<AnnotLine *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotLine *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+     annot->setVertices(start->x, start->y, end->x, end->y);
+ }
+
+@@ -1828,7 +1818,7 @@ static PopplerColor *poppler_annot_geometry_get_interior_color(PopplerAnnot *pop
+ {
+     AnnotGeometry *annot;
+
+-    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     return create_poppler_color_from_annot_color(annot->getInteriorColor());
+ }
+@@ -1837,7 +1827,7 @@ static void poppler_annot_geometry_set_interior_color(PopplerAnnot *poppler_anno
+ {
+     AnnotGeometry *annot;
+
+-    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot);
++    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot.get());
+
+     annot->setInteriorColor(create_annot_color_from_poppler_color(poppler_color));
+ }
+diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
+index a9515f3..65e94ef 100644
+--- a/glib/poppler-page.cc
++++ b/glib/poppler-page.cc
+@@ -1132,7 +1132,7 @@ GList *poppler_page_get_link_mapping(PopplerPage *page)
+
+     poppler_page_get_size(page, &width, &height);
+
+-    for (AnnotLink *link : links->getLinks()) {
++    for (const std::shared_ptr<AnnotLink> &link : links->getLinks()) {
+         PopplerLinkMapping *mapping;
+         PopplerRectangle rect;
+         LinkAction *link_action;
+@@ -1295,7 +1295,7 @@ GList *poppler_page_get_annot_mapping(PopplerPage *page)
+     poppler_page_get_size(page, &width, &height);
+     crop_box = page->page->getCropBox();
+
+-    for (Annot *annot : annots->getAnnots()) {
++    for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+         PopplerAnnotMapping *mapping;
+         PopplerRectangle rect;
+         gboolean flag_no_rotate;
+@@ -1569,12 +1569,12 @@ void poppler_page_add_annot(PopplerPage *page, PopplerAnnot *annot)
+     if (page_is_rotated) {
+         /* annot is inside a rotated page, as core poppler rect must be saved
+          * un-rotated, let's proceed to un-rotate rect before saving */
+-        _unrotate_rect_for_annot_and_page(page->page, annot->annot, &x1, &y1, &x2, &y2);
++        _unrotate_rect_for_annot_and_page(page->page, annot->annot.get(), &x1, &y1, &x2, &y2);
+     }
+
+     annot->annot->setRect(x1 + page_crop_box->x1, y1 + page_crop_box->y1, x2 + page_crop_box->x1, y2 + page_crop_box->y1);
+
+-    AnnotTextMarkup *annot_markup = dynamic_cast<AnnotTextMarkup *>(annot->annot);
++    AnnotTextMarkup *annot_markup = dynamic_cast<AnnotTextMarkup *>(annot->annot.get());
+     if (annot_markup) {
+         AnnotQuadrilaterals *quads;
+         crop_box = _poppler_annot_get_cropbox(annot);
+diff --git a/glib/poppler-private.h b/glib/poppler-private.h
+index ce2c473..775d211 100644
+--- a/glib/poppler-private.h
++++ b/glib/poppler-private.h
+@@ -85,7 +85,7 @@ struct _PopplerFormField
+ struct _PopplerAnnot
+ {
+     GObject parent_instance;
+-    Annot *annot;
++    std::shared_ptr<Annot> annot;
+ };
+
+ typedef struct _Layer
+@@ -146,16 +146,16 @@ PopplerFormField *_poppler_form_field_new(PopplerDocument *document, FormWidget
+ PopplerAttachment *_poppler_attachment_new(FileSpec *file);
+ PopplerMovie *_poppler_movie_new(const Movie *movie);
+ PopplerMedia *_poppler_media_new(const MediaRendition *media);
+-PopplerAnnot *_poppler_annot_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_text_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_free_text_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_text_markup_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_file_attachment_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_movie_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, Annot *annot);
+-PopplerAnnot *_poppler_annot_line_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_circle_new(Annot *annot);
+-PopplerAnnot *_poppler_annot_square_new(Annot *annot);
++PopplerAnnot *_poppler_annot_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_text_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_free_text_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_text_markup_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_file_attachment_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_movie_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_line_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_circle_new(const std::shared_ptr<Annot> &annot);
++PopplerAnnot *_poppler_annot_square_new(const std::shared_ptr<Annot> &annot);
+
+ const PDFRectangle *_poppler_annot_get_cropbox(PopplerAnnot *poppler_annot);
+
+diff --git a/poppler/Annot.cc b/poppler/Annot.cc
+index 366e7de..19ec824 100644
+--- a/poppler/Annot.cc
++++ b/poppler/Annot.cc
+@@ -1087,7 +1087,7 @@ void AnnotAppearance::removeStream(Ref refToStream)
+             continue;
+         }
+         Annots *annots = page->getAnnots();
+-        for (Annot *annot : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+             AnnotAppearance *annotAp = annot->getAppearStreams();
+             if (annotAp && annotAp != this && annotAp->referencesStream(refToStream)) {
+                 return; // Another annotation points to the stream -> Don't delete it
+@@ -1286,7 +1286,6 @@ double AnnotAppearanceBBox::getPageYMax() const
+ Annot::Annot(PDFDoc *docA, PDFRectangle *rectA)
+ {
+
+-    refCnt = 1;
+     flags = flagUnknown;
+     type = typeUnknown;
+
+@@ -1307,7 +1306,6 @@ Annot::Annot(PDFDoc *docA, PDFRectangle *rectA)
+
+ Annot::Annot(PDFDoc *docA, Object &&dictObject)
+ {
+-    refCnt = 1;
+     hasRef = false;
+     flags = flagUnknown;
+     type = typeUnknown;
+@@ -1317,7 +1315,6 @@ Annot::Annot(PDFDoc *docA, Object &&dictObject)
+
+ Annot::Annot(PDFDoc *docA, Object &&dictObject, const Object *obj)
+ {
+-    refCnt = 1;
+     if (obj->isRef()) {
+         hasRef = true;
+         ref = obj->getRef();
+@@ -1691,18 +1688,6 @@ void Annot::removeReferencedObjects()
+     invalidateAppearance();
+ }
+
+-void Annot::incRefCnt()
+-{
+-    refCnt++;
+-}
+-
+-void Annot::decRefCnt()
+-{
+-    if (--refCnt == 0) {
+-        delete this;
+-    }
+-}
+-
+ Annot::~Annot() { }
+
+ void AnnotAppearanceBuilder::setDrawColor(const AnnotColor *drawColor, bool fill)
+@@ -2243,7 +2228,7 @@ void AnnotMarkup::setLabel(std::unique_ptr<GooString> &&new_label)
+     update("T", Object(label->copy()));
+ }
+
+-void AnnotMarkup::setPopup(std::unique_ptr<AnnotPopup> &&new_popup)
++void AnnotMarkup::setPopup(std::shared_ptr<AnnotPopup> new_popup)
+ {
+     // If there exists an old popup annotation that is already
+     // associated with a page, then we need to remove that
+@@ -2252,7 +2237,7 @@ void AnnotMarkup::setPopup(std::unique_ptr<AnnotPopup> &&new_popup)
+     if (popup && popup->getPageNum() != 0) {
+         Page *pageobj = doc->getPage(popup->getPageNum());
+         if (pageobj) {
+-            pageobj->removeAnnot(popup.get());
++            pageobj->removeAnnot(popup);
+         }
+     }
+
+@@ -2269,7 +2254,7 @@ void AnnotMarkup::setPopup(std::unique_ptr<AnnotPopup> &&new_popup)
+             Page *pageobj = doc->getPage(page);
+             assert(pageobj != nullptr); // pageobj should exist in doc (see setPage())
+
+-            pageobj->addAnnot(popup.get());
++            pageobj->addAnnot(popup);
+         }
+     } else {
+         popup = nullptr;
+@@ -2301,7 +2286,7 @@ void AnnotMarkup::removeReferencedObjects()
+
+     // Remove popup
+     if (popup) {
+-        pageobj->removeAnnot(popup.get());
++        pageobj->removeAnnot(popup);
+     }
+
+     Annot::removeReferencedObjects();
+@@ -2969,7 +2954,7 @@ void AnnotFreeText::setStyleString(GooString *new_string)
+     update("DS", Object(styleString->copy()));
+ }
+
+-void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line)
++void AnnotFreeText::setCalloutLine(std::unique_ptr<AnnotCalloutLine> &&line)
+ {
+     Object obj1;
+     if (line == nullptr) {
+@@ -2984,15 +2969,13 @@ void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line)
+         obj1.arrayAdd(Object(x2));
+         obj1.arrayAdd(Object(y2));
+
+-        AnnotCalloutMultiLine *mline = dynamic_cast<AnnotCalloutMultiLine *>(line);
++        AnnotCalloutMultiLine *mline = dynamic_cast<AnnotCalloutMultiLine *>(line.get());
+         if (mline) {
+             double x3 = mline->getX3(), y3 = mline->getY3();
+             obj1.arrayAdd(Object(x3));
+             obj1.arrayAdd(Object(y3));
+-            calloutLine = std::make_unique<AnnotCalloutMultiLine>(x1, y1, x2, y2, x3, y3);
+-        } else {
+-            calloutLine = std::make_unique<AnnotCalloutLine>(x1, y1, x2, y2);
+         }
++        calloutLine = std::move(line);
+     }
+
+     update("CL", std::move(obj1));
+@@ -5518,10 +5501,7 @@ AnnotStamp::AnnotStamp(PDFDoc *docA, Object &&dictObject, const Object *obj) : A
+     initialize(docA, annotObj.getDict());
+ }
+
+-AnnotStamp::~AnnotStamp()
+-{
+-    delete stampImageHelper;
+-}
++AnnotStamp::~AnnotStamp() = default;
+
+ void AnnotStamp::initialize(PDFDoc *docA, Dict *dict)
+ {
+@@ -5532,7 +5512,6 @@ void AnnotStamp::initialize(PDFDoc *docA, Dict *dict)
+         icon = std::make_unique<GooString>("Draft");
+     }
+
+-    stampImageHelper = nullptr;
+     updatedAppearanceStream = Ref::INVALID();
+ }
+
+@@ -5690,16 +5669,18 @@ void AnnotStamp::setIcon(GooString *new_icon)
+     invalidateAppearance();
+ }
+
+-void AnnotStamp::setCustomImage(AnnotStampImageHelper *stampImageHelperA)
++void AnnotStamp::setCustomImage(std::unique_ptr<AnnotStampImageHelper> &&stampImageHelperA)
+ {
+     if (!stampImageHelperA) {
+         return;
+     }
+
+     annotLocker();
+-    clearCustomImage();
++    if (stampImageHelper) {
++        stampImageHelper->removeAnnotStampImageObject();
++    }
+
+-    stampImageHelper = stampImageHelperA;
++    stampImageHelper = std::move(stampImageHelperA);
+     generateStampCustomAppearance();
+
+     if (updatedAppearanceStream == Ref::INVALID()) {
+@@ -5714,16 +5695,6 @@ void AnnotStamp::setCustomImage(AnnotStampImageHelper *stampImageHelperA)
+     update("AP", std::move(obj1));
+ }
+
+-void AnnotStamp::clearCustomImage()
+-{
+-    if (stampImageHelper != nullptr) {
+-        stampImageHelper->removeAnnotStampImageObject();
+-        delete stampImageHelper;
+-        stampImageHelper = nullptr;
+-        invalidateAppearance();
+-    }
+-}
+-
+ //------------------------------------------------------------------------
+ // AnnotGeometry
+ //------------------------------------------------------------------------
+@@ -7270,96 +7241,90 @@ const GooString *AnnotRichMedia::Params::getFlashVars() const
+
+ Annots::Annots(PDFDoc *docA, int page, Object *annotsObj)
+ {
+-    Annot *annot;
+-    int i;
+-
+     doc = docA;
+
+     if (annotsObj->isArray()) {
+-        for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
++        for (int i = 0; i < annotsObj->arrayGetLength(); ++i) {
+             // get the Ref to this annot and pass it to Annot constructor
+             // this way, it'll be possible for the annot to retrieve the corresponding
+             // form widget
+             Object obj1 = annotsObj->arrayGet(i);
+             if (obj1.isDict()) {
+                 const Object &obj2 = annotsObj->arrayGetNF(i);
+-                annot = createAnnot(std::move(obj1), &obj2);
++                std::shared_ptr<Annot> annot = createAnnot(std::move(obj1), &obj2);
+                 if (annot) {
+                     if (annot->isOk()) {
+                         annot->setPage(page, false); // Don't change /P
+                         appendAnnot(annot);
+                     }
+-                    annot->decRefCnt();
+                 }
+             }
+         }
+     }
+ }
+
+-void Annots::appendAnnot(Annot *annot)
++void Annots::appendAnnot(std::shared_ptr<Annot> annot)
+ {
+     if (annot && annot->isOk()) {
+-        annots.push_back(annot);
+-        annot->incRefCnt();
++        annots.push_back(std::move(annot));
+     }
+ }
+
+-bool Annots::removeAnnot(Annot *annot)
++bool Annots::removeAnnot(const std::shared_ptr<Annot> &annot)
+ {
+     auto idx = std::find(annots.begin(), annots.end(), annot);
+
+     if (idx == annots.end()) {
+         return false;
+     } else {
+-        annot->decRefCnt();
+         annots.erase(idx);
+         return true;
+     }
+ }
+
+-Annot *Annots::createAnnot(Object &&dictObject, const Object *obj)
++std::shared_ptr<Annot> Annots::createAnnot(Object &&dictObject, const Object *obj)
+ {
+-    Annot *annot = nullptr;
++    std::shared_ptr<Annot> annot = nullptr;
+     Object obj1 = dictObject.dictLookup("Subtype");
+     if (obj1.isName()) {
+         const char *typeName = obj1.getName();
+
+         if (!strcmp(typeName, "Text")) {
+-            annot = new AnnotText(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotText>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Link")) {
+-            annot = new AnnotLink(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotLink>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "FreeText")) {
+-            annot = new AnnotFreeText(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotFreeText>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Line")) {
+-            annot = new AnnotLine(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotLine>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Square")) {
+-            annot = new AnnotGeometry(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotGeometry>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Circle")) {
+-            annot = new AnnotGeometry(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotGeometry>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Polygon")) {
+-            annot = new AnnotPolygon(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotPolygon>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "PolyLine")) {
+-            annot = new AnnotPolygon(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotPolygon>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Highlight")) {
+-            annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotTextMarkup>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Underline")) {
+-            annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotTextMarkup>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Squiggly")) {
+-            annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotTextMarkup>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "StrikeOut")) {
+-            annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotTextMarkup>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Stamp")) {
+-            annot = new AnnotStamp(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotStamp>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Caret")) {
+-            annot = new AnnotCaret(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotCaret>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Ink")) {
+-            annot = new AnnotInk(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotInk>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "FileAttachment")) {
+-            annot = new AnnotFileAttachment(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotFileAttachment>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Sound")) {
+-            annot = new AnnotSound(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotSound>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Movie")) {
+-            annot = new AnnotMovie(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotMovie>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Widget")) {
+             // Find the annot in forms
+             if (obj->isRef()) {
+@@ -7368,25 +7333,24 @@ Annot *Annots::createAnnot(Object &&dictObject, const Object *obj)
+                     FormWidget *widget = form->findWidgetByRef(obj->getRef());
+                     if (widget) {
+                         annot = widget->getWidgetAnnotation();
+-                        annot->incRefCnt();
+                     }
+                 }
+             }
+             if (!annot) {
+-                annot = new AnnotWidget(doc, std::move(dictObject), obj);
++                annot = std::make_shared<AnnotWidget>(doc, std::move(dictObject), obj);
+             }
+         } else if (!strcmp(typeName, "Screen")) {
+-            annot = new AnnotScreen(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotScreen>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "PrinterMark")) {
+-            annot = new Annot(doc, std::move(dictObject), obj);
++            annot = std::make_shared<Annot>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "TrapNet")) {
+-            annot = new Annot(doc, std::move(dictObject), obj);
++            annot = std::make_shared<Annot>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Watermark")) {
+-            annot = new Annot(doc, std::move(dictObject), obj);
++            annot = std::make_shared<Annot>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "3D")) {
+-            annot = new Annot3D(doc, std::move(dictObject), obj);
++            annot = std::make_shared<Annot3D>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "RichMedia")) {
+-            annot = new AnnotRichMedia(doc, std::move(dictObject), obj);
++            annot = std::make_shared<AnnotRichMedia>(doc, std::move(dictObject), obj);
+         } else if (!strcmp(typeName, "Popup")) {
+             /* Popup annots are already handled by markup annots
+              * Here we only care about popup annots without a
+@@ -7394,21 +7358,21 @@ Annot *Annots::createAnnot(Object &&dictObject, const Object *obj)
+              */
+             Object obj2 = dictObject.dictLookup("Parent");
+             if (obj2.isNull()) {
+-                annot = new AnnotPopup(doc, std::move(dictObject), obj);
++                annot = std::make_shared<AnnotPopup>(doc, std::move(dictObject), obj);
+             } else {
+                 annot = nullptr;
+             }
+         } else {
+-            annot = new Annot(doc, std::move(dictObject), obj);
++            annot = std::make_shared<Annot>(doc, std::move(dictObject), obj);
+         }
+     }
+
+     return annot;
+ }
+
+-Annot *Annots::findAnnot(Ref *ref)
++std::shared_ptr<Annot> Annots::findAnnot(Ref *ref)
+ {
+-    for (auto *annot : annots) {
++    for (const auto &annot : annots) {
+         if (annot->match(ref)) {
+             return annot;
+         }
+@@ -7416,12 +7380,7 @@ Annot *Annots::findAnnot(Ref *ref)
+     return nullptr;
+ }
+
+-Annots::~Annots()
+-{
+-    for (auto *annot : annots) {
+-        annot->decRefCnt();
+-    }
+-}
++Annots::~Annots() = default;
+
+ //------------------------------------------------------------------------
+ // AnnotAppearanceBuilder
+diff --git a/poppler/Annot.h b/poppler/Annot.h
+index 8d1f18b..7885c4a 100644
+--- a/poppler/Annot.h
++++ b/poppler/Annot.h
+@@ -717,9 +717,6 @@ public:
+     Annot(PDFDoc *docA, Object &&dictObject, const Object *obj);
+     bool isOk() { return ok; }
+
+-    void incRefCnt();
+-    void decRefCnt();
+-
+     virtual void draw(Gfx *gfx, bool printing);
+     // Get the resource dict of the appearance stream
+     virtual Object getAppearanceResDict();
+@@ -774,6 +771,8 @@ public:
+
+     static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont &font, double *width, double widthLimit, int *charCount, bool noReencode);
+
++    virtual ~Annot();
++
+ private:
+     void readArrayNum(Object *pdfArray, int key, double *value);
+     // write vStr[i:j[ in appearBuf
+@@ -782,7 +781,6 @@ private:
+     void setPage(int pageIndex, bool updateP); // Called by Page::addAnnot and Annots ctor
+
+ protected:
+-    virtual ~Annot();
+     virtual void removeReferencedObjects(); // Called by Page::removeAnnot
+     Object createForm(const GooString *appearBuf, const double *bbox, bool transparencyGroup, Dict *resDict);
+     Object createForm(const GooString *appearBuf, const double *bbox, bool transparencyGroup, Object &&resDictObject); // overload to support incRef/decRef
+@@ -799,8 +797,6 @@ protected:
+
+     Object annotObj;
+
+-    std::atomic_int refCnt;
+-
+     // required data
+     AnnotSubtype type; // Annotation type
+     std::unique_ptr<PDFRectangle> rect; // Rect
+@@ -871,7 +867,7 @@ public:
+
+     // getters
+     const GooString *getLabel() const { return label.get(); }
+-    AnnotPopup *getPopup() const { return popup.get(); }
++    std::shared_ptr<AnnotPopup> getPopup() const { return popup; }
+     double getOpacity() const { return opacity; }
+     // getRC
+     const GooString *getDate() const { return date.get(); }
+@@ -882,7 +878,7 @@ public:
+     AnnotExternalDataType getExData() const { return exData; }
+
+     // The annotation takes the ownership of new_popup
+-    void setPopup(std::unique_ptr<AnnotPopup> &&new_popup);
++    void setPopup(std::shared_ptr<AnnotPopup> new_popup);
+     void setLabel(std::unique_ptr<GooString> &&new_label);
+     void setOpacity(double opacityA);
+     void setDate(GooString *new_date);
+@@ -891,7 +887,7 @@ protected:
+     void removeReferencedObjects() override;
+
+     std::unique_ptr<GooString> label; // T            (Default author)
+-    std::unique_ptr<AnnotPopup> popup; // Popup
++    std::shared_ptr<AnnotPopup> popup; // Popup
+     double opacity; // CA           (Default 1.0)
+     // RC
+     std::unique_ptr<GooString> date; // CreationDate
+@@ -1066,7 +1062,7 @@ public:
+     void setDefaultAppearance(const DefaultAppearance &da);
+     void setQuadding(VariableTextQuadding new_quadding);
+     void setStyleString(GooString *new_string);
+-    void setCalloutLine(AnnotCalloutLine *line);
++    void setCalloutLine(std::unique_ptr<AnnotCalloutLine> &&line);
+     void setIntent(AnnotFreeTextIntent new_intent);
+
+     // getters
+@@ -1222,9 +1218,7 @@ public:
+
+     void setIcon(GooString *new_icon);
+
+-    void setCustomImage(AnnotStampImageHelper *stampImageHelperA);
+-
+-    void clearCustomImage();
++    void setCustomImage(std::unique_ptr<AnnotStampImageHelper> &&stampImageHelperA);
+
+     // getters
+     const GooString *getIcon() const { return icon.get(); }
+@@ -1235,7 +1229,7 @@ private:
+     void generateStampCustomAppearance();
+
+     std::unique_ptr<GooString> icon; // Name       (Default Draft)
+-    AnnotStampImageHelper *stampImageHelper;
++    std::unique_ptr<AnnotStampImageHelper> stampImageHelper;
+     Ref updatedAppearanceStream;
+ };
+
+@@ -1766,17 +1760,17 @@ public:
+     Annots(const Annots &) = delete;
+     Annots &operator=(const Annots &) = delete;
+
+-    const std::vector<Annot *> &getAnnots() { return annots; }
++    const std::vector<std::shared_ptr<Annot>> &getAnnots() { return annots; }
+
+-    void appendAnnot(Annot *annot);
+-    bool removeAnnot(Annot *annot);
++    void appendAnnot(std::shared_ptr<Annot> annot);
++    bool removeAnnot(const std::shared_ptr<Annot> &annot);
+
+ private:
+-    Annot *createAnnot(Object &&dictObject, const Object *obj);
+-    Annot *findAnnot(Ref *ref);
++    std::shared_ptr<Annot> createAnnot(Object &&dictObject, const Object *obj);
++    std::shared_ptr<Annot> findAnnot(Ref *ref);
+
+     PDFDoc *doc;
+-    std::vector<Annot *> annots;
++    std::vector<std::shared_ptr<Annot>> annots;
+ };
+
+ #endif
+diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
+index 309ec6d..c8c1bdf 100644
+--- a/poppler/FontInfo.cc
++++ b/poppler/FontInfo.cc
+@@ -82,7 +82,7 @@ std::vector<FontInfo *> FontInfoScanner::scan(int nPages)
+             delete resDict;
+         }
+         annots = page->getAnnots();
+-        for (Annot *annot : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+             Object obj1 = annot->getAppearanceResDict();
+             if (obj1.isDict()) {
+                 scanFonts(xrefA.get(), obj1.getDict(), &result);
+diff --git a/poppler/Form.cc b/poppler/Form.cc
+index b88972a..9a55095 100644
+--- a/poppler/Form.cc
++++ b/poppler/Form.cc
+@@ -110,12 +110,7 @@ FormWidget::FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormF
+     widget = nullptr;
+ }
+
+-FormWidget::~FormWidget()
+-{
+-    if (widget) {
+-        widget->decRefCnt();
+-    }
+-}
++FormWidget::~FormWidget() = default;
+
+ void FormWidget::print(int indent)
+ {
+@@ -129,7 +124,7 @@ void FormWidget::createWidgetAnnotation()
+     }
+
+     Object obj1(ref);
+-    widget = new AnnotWidget(doc, &obj, &obj1, field);
++    widget = std::make_shared<AnnotWidget>(doc, &obj, &obj1, field);
+ }
+
+ bool FormWidget::inRect(double x, double y) const
+@@ -2738,7 +2733,7 @@ FormPageWidgets::FormPageWidgets(Annots *annots, unsigned int page, Form *form)
+
+         /* For each entry in the page 'Annots' dict, try to find
+            a matching form field */
+-        for (Annot *annot : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+
+             if (annot->getType() != Annot::typeWidget) {
+                 continue;
+diff --git a/poppler/Form.h b/poppler/Form.h
+index c48ae83..23f6a81 100644
+--- a/poppler/Form.h
++++ b/poppler/Form.h
+@@ -143,8 +143,8 @@ public:
+     static void decodeID(unsigned id, unsigned *pageNum, unsigned *fieldNum);
+
+     void createWidgetAnnotation();
+-    AnnotWidget *getWidgetAnnotation() const { return widget; }
+-    void setWidgetAnnotation(AnnotWidget *_widget) { widget = _widget; }
++    std::shared_ptr<AnnotWidget> getWidgetAnnotation() const { return widget; }
++    void setWidgetAnnotation(std::shared_ptr<AnnotWidget> _widget) { widget = std::move(_widget); }
+
+     virtual void updateWidgetAppearance() = 0;
+
+@@ -153,7 +153,7 @@ public:
+ protected:
+     FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormField *fieldA);
+
+-    AnnotWidget *widget;
++    std::shared_ptr<AnnotWidget> widget;
+     FormField *field;
+     FormFieldType type;
+     Object obj;
+diff --git a/poppler/JSInfo.cc b/poppler/JSInfo.cc
+index eaef33e..e4c4f37 100644
+--- a/poppler/JSInfo.cc
++++ b/poppler/JSInfo.cc
+@@ -191,15 +191,15 @@ void JSInfo::scan(int nPages)
+         }
+         // annotation actions (links, screen, widget)
+         annots = page->getAnnots();
+-        for (Annot *a : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> &a : annots->getAnnots()) {
+             if (a->getType() == Annot::typeLink) {
+-                AnnotLink *annot = static_cast<AnnotLink *>(a);
++                AnnotLink *annot = static_cast<AnnotLink *>(a.get());
+                 scanLinkAction(annot->getAction(), "Link Annotation Activated");
+                 if (onlyFirstJS && hasJS) {
+                     return;
+                 }
+             } else if (a->getType() == Annot::typeScreen) {
+-                AnnotScreen *annot = static_cast<AnnotScreen *>(a);
++                AnnotScreen *annot = static_cast<AnnotScreen *>(a.get());
+                 scanLinkAction(annot->getAction(), "Screen Annotation Activated");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Screen Annotation Cursor Enter");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Screen Annotation Cursor Leave");
+@@ -216,7 +216,7 @@ void JSInfo::scan(int nPages)
+                     return;
+                 }
+             } else if (a->getType() == Annot::typeWidget) {
+-                AnnotWidget *annot = static_cast<AnnotWidget *>(a);
++                AnnotWidget *annot = static_cast<AnnotWidget *>(a.get());
+                 scanLinkAction(annot->getAction(), "Widget Annotation Activated");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Widget Annotation Cursor Enter");
+                 scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Widget Annotation Cursor Leave");
+diff --git a/poppler/Link.cc b/poppler/Link.cc
+index 8aca0b9..0fbfc0c 100644
+--- a/poppler/Link.cc
++++ b/poppler/Link.cc
+@@ -35,6 +35,7 @@
+
+ #include <cstddef>
+ #include <cstring>
++#include <memory>
+ #include "goo/gmem.h"
+ #include "goo/GooString.h"
+ #include "Error.h"
+@@ -890,20 +891,14 @@ Links::Links(Annots *annots)
+         return;
+     }
+
+-    for (Annot *annot : annots->getAnnots()) {
++    for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+
+         if (annot->getType() != Annot::typeLink) {
+             continue;
+         }
+
+-        annot->incRefCnt();
+-        links.push_back(static_cast<AnnotLink *>(annot));
++        links.push_back(std::static_pointer_cast<AnnotLink>(annot));
+     }
+ }
+
+-Links::~Links()
+-{
+-    for (AnnotLink *link : links) {
+-        link->decRefCnt();
+-    }
+-}
++Links::~Links() = default;
+diff --git a/poppler/Link.h b/poppler/Link.h
+index 204207b..9bd01f0 100644
+--- a/poppler/Link.h
++++ b/poppler/Link.h
+@@ -555,10 +555,10 @@ public:
+     Links(const Links &) = delete;
+     Links &operator=(const Links &) = delete;
+
+-    const std::vector<AnnotLink *> &getLinks() const { return links; }
++    const std::vector<std::shared_ptr<AnnotLink>> &getLinks() const { return links; }
+
+ private:
+-    std::vector<AnnotLink *> links;
++    std::vector<std::shared_ptr<AnnotLink>> links;
+ };
+
+ #endif
+diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
+index 20bb191..47c0023 100644
+--- a/poppler/PDFDoc.cc
++++ b/poppler/PDFDoc.cc
+@@ -2150,7 +2150,7 @@ bool PDFDoc::sign(const char *saveFilename, const char *certNickname, const char
+     field->setImageResource(imageResourceRef);
+
+     Object refObj(ref);
+-    AnnotWidget *signatureAnnot = new AnnotWidget(this, &annotObj, &refObj, field.get());
++    auto signatureAnnot = std::make_shared<AnnotWidget>(this, &annotObj, &refObj, field.get());
+     signatureAnnot->setFlags(signatureAnnot->getFlags() | Annot::flagPrint | Annot::flagLocked | Annot::flagNoRotate);
+     Dict dummy(getXRef());
+     auto appearCharacs = std::make_unique<AnnotAppearanceCharacs>(&dummy);
+diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
+index 9db6229..541cae3 100644
+--- a/poppler/PSOutputDev.cc
++++ b/poppler/PSOutputDev.cc
+@@ -1745,7 +1745,7 @@ void PSOutputDev::writeDocSetup(Catalog *catalog, const std::vector<int> &pageLi
+             setupResources(resDict);
+         }
+         annots = page->getAnnots();
+-        for (Annot *annot : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> annot : annots->getAnnots()) {
+             Object obj1 = annot->getAppearanceResDict();
+             if (obj1.isDict()) {
+                 setupResources(obj1.getDict());
+diff --git a/poppler/Page.cc b/poppler/Page.cc
+index c256d39..b27c90d 100644
+--- a/poppler/Page.cc
++++ b/poppler/Page.cc
+@@ -319,14 +319,7 @@ err1:
+     ok = false;
+ }
+
+-Page::~Page()
+-{
+-    delete attrs;
+-    delete annots;
+-    for (auto frmField : standaloneFields) {
+-        delete frmField;
+-    }
+-}
++Page::~Page() = default;
+
+ Dict *Page::getResourceDict()
+ {
+@@ -365,11 +358,11 @@ void Page::replaceXRef(XRef *xrefA)
+ }
+
+ /* Loads standalone fields into Page, should be called once per page only */
+-void Page::loadStandaloneFields(Annots *annotations, Form *form)
++void Page::loadStandaloneFields(Form *form)
+ {
+     /* Look for standalone annots, identified by being: 1) of type Widget
+      * 2) not referenced from the Catalog's Form Field array */
+-    for (Annot *annot : annots->getAnnots()) {
++    for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+
+         if (annot->getType() != Annot::typeWidget || !annot->getHasRef()) {
+             continue;
+@@ -385,7 +378,7 @@ void Page::loadStandaloneFields(Annots *annotations, Form *form)
+
+         if (field && field->getNumWidgets() == 1) {
+
+-            static_cast<AnnotWidget *>(annot)->setField(field);
++            std::static_pointer_cast<AnnotWidget>(annot)->setField(field);
+
+             field->setStandAlone(true);
+             FormWidget *formWidget = field->getWidget(0);
+@@ -406,15 +399,15 @@ Annots *Page::getAnnots(XRef *xrefA)
+ {
+     if (!annots) {
+         Object obj = getAnnotsObject(xrefA);
+-        annots = new Annots(doc, num, &obj);
++        annots = std::make_unique<Annots>(doc, num, &obj);
+         // Load standalone fields once for the page
+-        loadStandaloneFields(annots, doc->getCatalog()->getForm());
++        loadStandaloneFields(doc->getCatalog()->getForm());
+     }
+
+-    return annots;
++    return annots.get();
+ }
+
+-void Page::addAnnot(Annot *annot)
++void Page::addAnnot(const std::shared_ptr<Annot> &annot)
+ {
+     const Ref annotRef = annot->getRef();
+
+@@ -451,21 +444,21 @@ void Page::addAnnot(Annot *annot)
+     // Popup annots are already handled by markup annots,
+     // so add to the list only Popup annots without a
+     // markup annotation associated.
+-    if (annot->getType() != Annot::typePopup || !static_cast<AnnotPopup *>(annot)->hasParent()) {
++    if (annot->getType() != Annot::typePopup || !static_cast<AnnotPopup *>(annot.get())->hasParent()) {
+         annots->appendAnnot(annot);
+     }
+     annot->setPage(num, true);
+
+-    AnnotMarkup *annotMarkup = dynamic_cast<AnnotMarkup *>(annot);
++    AnnotMarkup *annotMarkup = dynamic_cast<AnnotMarkup *>(annot.get());
+     if (annotMarkup) {
+-        AnnotPopup *annotPopup = annotMarkup->getPopup();
++        std::shared_ptr<AnnotPopup> annotPopup = annotMarkup->getPopup();
+         if (annotPopup) {
+             addAnnot(annotPopup);
+         }
+     }
+ }
+
+-void Page::removeAnnot(Annot *annot)
++void Page::removeAnnot(const std::shared_ptr<Annot> &annot)
+ {
+     Ref annotRef = annot->getRef();
+
+@@ -587,8 +580,8 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, int rotate, bo
+         if (globalParams->getPrintCommands()) {
+             printf("***** Annotations\n");
+         }
+-        for (Annot *annot : annots->getAnnots()) {
+-            if ((annotDisplayDecideCbk && (*annotDisplayDecideCbk)(annot, annotDisplayDecideCbkData)) || !annotDisplayDecideCbk) {
++        for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
++            if ((annotDisplayDecideCbk && (*annotDisplayDecideCbk)(annot.get(), annotDisplayDecideCbkData)) || !annotDisplayDecideCbk) {
+                 annot->draw(gfx, printing);
+             }
+         }
+@@ -778,8 +771,8 @@ void Page::makeBox(double hDPI, double vDPI, int rotate, bool useMediaBox, bool
+ void Page::processLinks(OutputDev *out)
+ {
+     std::unique_ptr<Links> links = getLinks();
+-    for (AnnotLink *link : links->getLinks()) {
+-        out->processLink(link);
++    for (const std::shared_ptr<AnnotLink> &link : links->getLinks()) {
++        out->processLink(link.get());
+     }
+ }
+
+diff --git a/poppler/Page.h b/poppler/Page.h
+index fbd2c16..3159e70 100644
+--- a/poppler/Page.h
++++ b/poppler/Page.h
+@@ -181,9 +181,9 @@ public:
+     // Get annotations array.
+     Object getAnnotsObject(XRef *xrefA = nullptr) { return annotsObj.fetch(xrefA ? xrefA : xref); }
+     // Add a new annotation to the page
+-    void addAnnot(Annot *annot);
++    void addAnnot(const std::shared_ptr<Annot> &annot);
+     // Remove an existing annotation from the page
+-    void removeAnnot(Annot *annot);
++    void removeAnnot(const std::shared_ptr<Annot> &annot);
+
+     // Return a list of links.
+     std::unique_ptr<Links> getLinks();
+@@ -252,7 +252,7 @@ private:
+     Ref pageRef; // page reference
+     int num; // page number
+     PageAttrs *attrs; // page attributes
+-    Annots *annots; // annotations
++    std::unique_ptr<Annots> annots; // annotations
+     Object annotsObj; // annotations array
+     Object contents; // page contents
+     Object thumb; // page thumbnail
+@@ -267,7 +267,7 @@ private:
+     // create standalone FormFields to contain those special FormWidgets, as
+     // they are 'de facto' being used to implement tooltips. See #34
+     std::vector<FormField *> standaloneFields;
+-    void loadStandaloneFields(Annots *annotations, Form *form);
++    void loadStandaloneFields(Form *form);
+ };
+
+ #endif
+diff --git a/qt5/src/poppler-annotation-private.h b/qt5/src/poppler-annotation-private.h
+index 1f8d756..ef0c8b4 100644
+--- a/qt5/src/poppler-annotation-private.h
++++ b/qt5/src/poppler-annotation-private.h
+@@ -57,7 +57,7 @@ public:
+
+     /* Returns an Annotation of the right subclass whose d_ptr points to
+      * this AnnotationPrivate */
+-    virtual Annotation *makeAlias() = 0;
++    virtual std::unique_ptr<Annotation> makeAlias() = 0;
+
+     /* properties: contents related */
+     QString author;
+@@ -77,18 +77,18 @@ public:
+     /* revisions */
+     Annotation::RevScope revisionScope;
+     Annotation::RevType revisionType;
+-    QList<Annotation *> revisions;
++    std::vector<std::unique_ptr<Annotation>> revisions;
+
+     /* After this call, the Annotation object will behave like a wrapper for
+      * the specified Annot object. All cached values are discarded */
+-    void tieToNativeAnnot(Annot *ann, ::Page *page, DocumentData *doc);
++    void tieToNativeAnnot(std::shared_ptr<Annot> ann, ::Page *page, DocumentData *doc);
+
+     /* Creates a new Annot object on the specified page, flushes current
+      * values to that object and ties this Annotation to that object */
+-    virtual Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) = 0;
++    virtual std::shared_ptr<Annot> *createNativeAnnot(::Page *destPage, DocumentData *doc) = 0;
+
+     /* Inited to 0 (i.e. untied annotation) */
+-    Annot *pdfAnnot;
++    std::shared_ptr<Annot> pdfAnnot;
+     ::Page *pdfPage;
+     DocumentData *parentDoc;
+
+diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc
+index cdf25da..ea86917 100644
+--- a/qt5/src/poppler-annotation.cc
++++ b/qt5/src/poppler-annotation.cc
+@@ -65,6 +65,12 @@
+  * static data set at creation time by findAnnotations
+  */
+
++template<typename T, typename U>
++static std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U> &&in)
++{
++    return std::unique_ptr<T>(static_cast<std::add_pointer_t<T>>(in.release()));
++}
++
+ namespace Poppler {
+
+ // BEGIN AnnotationUtils implementation
+@@ -199,36 +205,25 @@ void getRawDataFromQImage(const QImage &qimg, int bitsPerPixel, QByteArray *data
+ void AnnotationPrivate::addRevision(Annotation *ann, Annotation::RevScope scope, Annotation::RevType type)
+ {
+     /* Since ownership stays with the caller, create an alias of ann */
+-    revisions.append(ann->d_ptr->makeAlias());
++    revisions.push_back(ann->d_ptr->makeAlias());
+
+     /* Set revision properties */
+     revisionScope = scope;
+     revisionType = type;
+ }
+
+-AnnotationPrivate::~AnnotationPrivate()
+-{
+-    // Delete all children revisions
+-    qDeleteAll(revisions);
++AnnotationPrivate::~AnnotationPrivate() = default;
+
+-    // Release Annot object
+-    if (pdfAnnot) {
+-        pdfAnnot->decRefCnt();
+-    }
+-}
+-
+-void AnnotationPrivate::tieToNativeAnnot(Annot *ann, ::Page *page, Poppler::DocumentData *doc)
++void AnnotationPrivate::tieToNativeAnnot(std::shared_ptr<Annot> ann, ::Page *page, Poppler::DocumentData *doc)
+ {
+     if (pdfAnnot) {
+         error(errIO, -1, "Annotation is already tied");
+         return;
+     }
+
+-    pdfAnnot = ann;
++    pdfAnnot = std::move(ann);
+     pdfPage = page;
+     parentDoc = doc;
+-
+-    pdfAnnot->incRefCnt();
+ }
+
+ /* This method is called when a new annotation is created, after pdfAnnot and
+@@ -237,7 +232,7 @@ void AnnotationPrivate::flushBaseAnnotationProperties()
+ {
+     Q_ASSERT(pdfPage);
+
+-    Annotation *q = makeAlias(); // Setters are defined in the public class
++    std::unique_ptr<Annotation> q = makeAlias(); // Setters are defined in the public class
+
+     // Since pdfAnnot has been set, this calls will write in the Annot object
+     q->setAuthor(author);
+@@ -251,12 +246,7 @@ void AnnotationPrivate::flushBaseAnnotationProperties()
+     q->setPopup(popup);
+
+     // Flush revisions
+-    foreach (Annotation *r, revisions) {
+-        // TODO: Flush revision
+-        delete r; // Object is no longer needed
+-    }
+-
+-    delete q;
++    revisions.clear();
+
+     // Clear some members to save memory
+     author.clear();
+@@ -455,14 +445,14 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+
+     // Create Annotation objects and tie to their native Annot
+     QList<Annotation *> res;
+-    for (Annot *ann : annots->getAnnots()) {
++    for (const std::shared_ptr<Annot> &ann : annots->getAnnots()) {
+         if (!ann) {
+             error(errInternal, -1, "Annot is null");
+             continue;
+         }
+
+         // Check parent annotation
+-        AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(ann);
++        AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(ann.get());
+         if (!markupann) {
+             // Assume it's a root annotation, and skip if user didn't request it
+             if (parentID != -1) {
+@@ -536,7 +526,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+                 continue;
+             }
+             // parse Link params
+-            AnnotLink *linkann = static_cast<AnnotLink *>(ann);
++            AnnotLink *linkann = static_cast<AnnotLink *>(ann.get());
+             LinkAnnotation *l = new LinkAnnotation();
+             annotation = l;
+
+@@ -566,7 +556,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+             if (!wantFileAttachmentAnnotations) {
+                 continue;
+             }
+-            AnnotFileAttachment *attachann = static_cast<AnnotFileAttachment *>(ann);
++            AnnotFileAttachment *attachann = static_cast<AnnotFileAttachment *>(ann.get());
+             FileAttachmentAnnotation *f = new FileAttachmentAnnotation();
+             annotation = f;
+             // -> fileIcon
+@@ -581,7 +571,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+             if (!wantSoundAnnotations) {
+                 continue;
+             }
+-            AnnotSound *soundann = static_cast<AnnotSound *>(ann);
++            AnnotSound *soundann = static_cast<AnnotSound *>(ann.get());
+             SoundAnnotation *s = new SoundAnnotation();
+             annotation = s;
+
+@@ -596,7 +586,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+             if (!wantMovieAnnotations) {
+                 continue;
+             }
+-            AnnotMovie *movieann = static_cast<AnnotMovie *>(ann);
++            AnnotMovie *movieann = static_cast<AnnotMovie *>(ann.get());
+             MovieAnnotation *m = new MovieAnnotation();
+             annotation = m;
+
+@@ -614,7 +604,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+             if (!wantScreenAnnotations) {
+                 continue;
+             }
+-            AnnotScreen *screenann = static_cast<AnnotScreen *>(ann);
++            AnnotScreen *screenann = static_cast<AnnotScreen *>(ann.get());
+             // TODO Support other link types than Link::Rendition in ScreenAnnotation
+             if (!screenann->getAction() || screenann->getAction()->getKind() != actionRendition) {
+                 continue;
+@@ -644,7 +634,7 @@ QList<Annotation *> AnnotationPrivate::findAnnotations(::Page *pdfPage, Document
+             annotation = new WidgetAnnotation();
+             break;
+         case Annot::typeRichMedia: {
+-            const AnnotRichMedia *annotRichMedia = static_cast<AnnotRichMedia *>(ann);
++            const AnnotRichMedia *annotRichMedia = static_cast<AnnotRichMedia *>(ann.get());
+
+             RichMediaAnnotation *richMediaAnnotation = new RichMediaAnnotation;
+
+@@ -852,9 +842,9 @@ Link *AnnotationPrivate::additionalAction(Annotation::AdditionalActionType type)
+
+     std::unique_ptr<::LinkAction> linkAction = nullptr;
+     if (pdfAnnot->getType() == Annot::typeScreen) {
+-        linkAction = static_cast<AnnotScreen *>(pdfAnnot)->getAdditionalAction(actionType);
++        linkAction = static_cast<AnnotScreen *>(pdfAnnot.get())->getAdditionalAction(actionType);
+     } else {
+-        linkAction = static_cast<AnnotWidget *>(pdfAnnot)->getAdditionalAction(actionType);
++        linkAction = static_cast<AnnotWidget *>(pdfAnnot.get())->getAdditionalAction(actionType);
+     }
+
+     Link *link = nullptr;
+@@ -875,7 +865,7 @@ void AnnotationPrivate::addAnnotationToPage(::Page *pdfPage, DocumentData *doc,
+
+     // Unimplemented annotations can't be created by the user because their ctor
+     // is private. Therefore, createNativeAnnot will never return 0
+-    Annot *nativeAnnot = ann->d_ptr->createNativeAnnot(pdfPage, doc);
++    std::shared_ptr<Annot> nativeAnnot = ann->d_ptr->createNativeAnnot(pdfPage, doc);
+     Q_ASSERT(nativeAnnot);
+
+     if (ann->d_ptr->annotationAppearance.isStream()) {
+@@ -1400,7 +1390,7 @@ QString Annotation::author() const
+         return d->author;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     return markupann ? UnicodeParsedString(markupann->getLabel()) : QString();
+ }
+
+@@ -1413,7 +1403,7 @@ void Annotation::setAuthor(const QString &author)
+         return;
+     }
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         markupann->setLabel(std::unique_ptr<GooString>(QStringToUnicodeGooString(author)));
+     }
+@@ -1511,7 +1501,7 @@ QDateTime Annotation::creationDate() const
+         return d->creationDate;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+
+     if (markupann && markupann->getDate()) {
+         return convertDate(markupann->getDate()->c_str());
+@@ -1529,7 +1519,7 @@ void Annotation::setCreationDate(const QDateTime &date)
+         return;
+     }
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         if (date.isValid()) {
+             const time_t t = date.toSecsSinceEpoch();
+@@ -1659,7 +1649,7 @@ Annotation::Style Annotation::style() const
+     Style s;
+     s.setColor(convertAnnotColor(d->pdfAnnot->getColor()));
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         s.setOpacity(markupann->getOpacity());
+     }
+@@ -1687,11 +1677,11 @@ Annotation::Style Annotation::style() const
+     AnnotBorderEffect *border_effect;
+     switch (d->pdfAnnot->getType()) {
+     case Annot::typeFreeText:
+-        border_effect = static_cast<AnnotFreeText *>(d->pdfAnnot)->getBorderEffect();
++        border_effect = static_cast<AnnotFreeText *>(d->pdfAnnot.get())->getBorderEffect();
+         break;
+     case Annot::typeSquare:
+     case Annot::typeCircle:
+-        border_effect = static_cast<AnnotGeometry *>(d->pdfAnnot)->getBorderEffect();
++        border_effect = static_cast<AnnotGeometry *>(d->pdfAnnot.get())->getBorderEffect();
+         break;
+     default:
+         border_effect = nullptr;
+@@ -1715,7 +1705,7 @@ void Annotation::setStyle(const Annotation::Style &style)
+
+     d->pdfAnnot->setColor(convertQColor(style.color()));
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         markupann->setOpacity(style.opacity());
+     }
+@@ -1739,9 +1729,9 @@ Annotation::Popup Annotation::popup() const
+     AnnotPopup *popup = nullptr;
+     int flags = -1; // Not initialized
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+-        popup = markupann->getPopup();
++        popup = markupann->getPopup().get();
+         w.setSummary(UnicodeParsedString(markupann->getSubject()));
+     }
+
+@@ -1757,7 +1747,7 @@ Annotation::Popup Annotation::popup() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot);
++        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot.get());
+
+         // Text annotations default to same rect as annotation
+         if (flags == -1) {
+@@ -1813,7 +1803,7 @@ Annotation::RevScope Annotation::revisionScope() const
+         return d->revisionScope;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+
+     if (markupann && markupann->isInReplyTo()) {
+         switch (markupann->getReplyTo()) {
+@@ -1835,7 +1825,7 @@ Annotation::RevType Annotation::revisionType() const
+         return d->revisionType;
+     }
+
+-    const AnnotText *textann = dynamic_cast<const AnnotText *>(d->pdfAnnot);
++    const AnnotText *textann = dynamic_cast<const AnnotText *>(d->pdfAnnot.get());
+
+     if (textann && textann->isInReplyTo()) {
+         switch (textann->getState()) {
+@@ -1866,8 +1856,8 @@ QList<Annotation *> Annotation::revisions() const
+     if (!d->pdfAnnot) {
+         /* Return aliases, whose ownership goes to the caller */
+         QList<Annotation *> res;
+-        foreach (Annotation *rev, d->revisions)
+-            res.append(rev->d_ptr->makeAlias());
++        for (const std::unique_ptr<Annotation> &rev, d->revisions)
++            res.append(rev->d_ptr->makeAlias().release());
+         return res;
+     }
+
+@@ -1884,7 +1874,7 @@ std::unique_ptr<AnnotationAppearance> Annotation::annotationAppearance() const
+ {
+     Q_D(const Annotation);
+
+-    return std::make_unique<AnnotationAppearance>(new AnnotationAppearancePrivate(d->pdfAnnot));
++    return std::make_unique<AnnotationAppearance>(new AnnotationAppearancePrivate(d->pdfAnnot.get()));
+ }
+
+ void Annotation::setAnnotationAppearance(const AnnotationAppearance &annotationAppearance)
+@@ -1909,8 +1899,8 @@ class TextAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     TextAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+     void setDefaultAppearanceToNative();
+     std::unique_ptr<DefaultAppearance> getDefaultAppearanceFromNative() const;
+
+@@ -1926,15 +1916,15 @@ public:
+
+ TextAnnotationPrivate::TextAnnotationPrivate() : AnnotationPrivate(), textType(TextAnnotation::Linked), textIcon(QStringLiteral("Note")), inplaceAlign(0), inplaceIntent(TextAnnotation::Unknown) { }
+
+-Annotation *TextAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> TextAnnotationPrivate::makeAlias()
+ {
+-    return new TextAnnotation(*this);
++    return std::unique_ptr<Annotation>(new TextAnnotation(*this));
+ }
+
+-Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+-    // Setters are defined in the public class
+-    TextAnnotation *q = static_cast<TextAnnotation *>(makeAlias());
++    // Setters are defined in the public clas
++    std::unique_ptr<TextAnnotation> q = static_pointer_cast<TextAnnotation *>(makeAlias());
+
+     // Set page and contents
+     pdfPage = destPage;
+@@ -1943,14 +1933,14 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+     if (textType == TextAnnotation::Linked) {
+-        pdfAnnot = new AnnotText { destPage->getDoc(), &rect };
++        pdfAnnot = std::make_shared<AnnotText>(destPage->getDoc(), &rect);
+     } else {
+         const double pointSize = textFont ? textFont->pointSizeF() : AnnotFreeText::undefinedFontPtSize;
+         if (pointSize < 0) {
+             qWarning() << "TextAnnotationPrivate::createNativeAnnot: font pointSize < 0";
+         }
+         DefaultAppearance da { { objName, "Invalid_font" }, pointSize, convertQColor(textColor) };
+-        pdfAnnot = new AnnotFreeText { destPage->getDoc(), &rect, da };
++        pdfAnnot = std::make_shared<AnnotFreeText>(destPage->getDoc(), &rect, da);
+     }
+
+     // Set properties
+@@ -1960,8 +1950,6 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     q->setCalloutPoints(inplaceCallout);
+     q->setInplaceIntent(inplaceIntent);
+
+-    delete q;
+-
+     inplaceCallout.clear(); // Free up memory
+
+     return pdfAnnot;
+@@ -1970,7 +1958,7 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+ void TextAnnotationPrivate::setDefaultAppearanceToNative()
+ {
+     if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot.get());
+         const double pointSize = textFont ? textFont->pointSizeF() : AnnotFreeText::undefinedFontPtSize;
+         if (pointSize < 0) {
+             qWarning() << "TextAnnotationPrivate::createNativeAnnot: font pointSize < 0";
+@@ -1983,7 +1971,7 @@ void TextAnnotationPrivate::setDefaultAppearanceToNative()
+ std::unique_ptr<DefaultAppearance> TextAnnotationPrivate::getDefaultAppearanceFromNative() const
+ {
+     if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot.get());
+         return ftextann->getDefaultAppearance();
+     } else {
+         return {};
+@@ -2140,7 +2128,7 @@ QString TextAnnotation::textIcon() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot);
++        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot.get());
+         return QString::fromLatin1(textann->getIcon()->c_str());
+     }
+
+@@ -2157,7 +2145,7 @@ void TextAnnotation::setTextIcon(const QString &icon)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        AnnotText *textann = static_cast<AnnotText *>(d->pdfAnnot);
++        AnnotText *textann = static_cast<AnnotText *>(d->pdfAnnot.get());
+         QByteArray encoded = icon.toLatin1();
+         GooString s(encoded.constData());
+         textann->setIcon(&s);
+@@ -2231,7 +2219,7 @@ int TextAnnotation::inplaceAlign() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+         return static_cast<int>(ftextann->getQuadding());
+     }
+
+@@ -2248,7 +2236,7 @@ void TextAnnotation::setInplaceAlign(int align)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+         ftextann->setQuadding((VariableTextQuadding)align);
+     }
+ }
+@@ -2275,7 +2263,7 @@ QVector<QPointF> TextAnnotation::calloutPoints() const
+         return QVector<QPointF>();
+     }
+
+-    const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++    const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+     const AnnotCalloutLine *callout = ftextann->getCalloutLine();
+
+     if (!callout) {
+@@ -2307,7 +2295,7 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+         return;
+     }
+
+-    AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++    AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+     const int count = points.size();
+
+     if (count == 0) {
+@@ -2320,7 +2308,7 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+         return;
+     }
+
+-    AnnotCalloutLine *callout;
++    std::unique_ptr<AnnotCalloutLine> callout;
+     double x1, y1, x2, y2;
+     double MTX[6];
+     d->fillTransformationMTX(MTX);
+@@ -2330,13 +2318,12 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+     if (count == 3) {
+         double x3, y3;
+         XPDFReader::invTransform(MTX, points[2], x3, y3);
+-        callout = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
++        callout = std::make_unique<AnnotCalloutMultiLine>(x1, y1, x2, y2, x3, y3);
+     } else {
+-        callout = new AnnotCalloutLine(x1, y1, x2, y2);
++        callout = std::make_unique<AnnotCalloutLine>(x1, y1, x2, y2);
+     }
+
+-    ftextann->setCalloutLine(callout);
+-    delete callout;
++    ftextann->setCalloutLine(std::move(callout));
+ }
+
+ TextAnnotation::InplaceIntent TextAnnotation::inplaceIntent() const
+@@ -2348,7 +2335,7 @@ TextAnnotation::InplaceIntent TextAnnotation::inplaceIntent() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+         return (TextAnnotation::InplaceIntent)ftextann->getIntent();
+     }
+
+@@ -2365,7 +2352,7 @@ void TextAnnotation::setInplaceIntent(TextAnnotation::InplaceIntent intent)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+         ftextann->setIntent((AnnotFreeText::AnnotFreeTextIntent)intent);
+     }
+ }
+@@ -2375,8 +2362,8 @@ class LineAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     LineAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields (note uses border for rendering style)
+     QLinkedList<QPointF> linePoints;
+@@ -2396,15 +2383,15 @@ LineAnnotationPrivate::LineAnnotationPrivate()
+ {
+ }
+
+-Annotation *LineAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> LineAnnotationPrivate::makeAlias()
+ {
+-    return new LineAnnotation(*this);
++    return std::unique_ptr<LineAnnotation>(new LineAnnotation(*this));
+ }
+
+-Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    LineAnnotation *q = static_cast<LineAnnotation *>(makeAlias());
++    std::unique_ptr<LineAnnotation> q = static_pointer_cast<LineAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2413,9 +2400,9 @@ Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+     if (lineType == LineAnnotation::StraightLine) {
+-        pdfAnnot = new AnnotLine(doc->doc, &rect);
++        pdfAnnot = std::make_shared<AnnotLine>(doc->doc, &rect);
+     } else {
+-        pdfAnnot = new AnnotPolygon(doc->doc, &rect, lineClosed ? Annot::typePolygon : Annot::typePolyLine);
++        pdfAnnot = std::make_shared<AnnotPolygon>(doc->doc, &rect, lineClosed ? Annot::typePolygon : Annot::typePolyLine);
+     }
+
+     // Set properties
+@@ -2429,8 +2416,6 @@ Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     q->setLineShowCaption(lineShowCaption);
+     q->setLineIntent(lineIntent);
+
+-    delete q;
+-
+     linePoints.clear(); // Free up memory
+
+     return pdfAnnot;
+@@ -2596,14 +2581,14 @@ QLinkedList<QPointF> LineAnnotation::linePoints() const
+
+     QLinkedList<QPointF> res;
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         QPointF p;
+         XPDFReader::transform(MTX, lineann->getX1(), lineann->getY1(), p);
+         res.append(p);
+         XPDFReader::transform(MTX, lineann->getX2(), lineann->getY2(), p);
+         res.append(p);
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         const AnnotPath *vertices = polyann->getVertices();
+
+         for (int i = 0; i < vertices->getCoordsLength(); ++i) {
+@@ -2626,7 +2611,7 @@ void LineAnnotation::setLinePoints(const QLinkedList<QPointF> &points)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         if (points.size() != 2) {
+             error(errSyntaxError, -1, "Expected two points for a straight line");
+             return;
+@@ -2638,7 +2623,7 @@ void LineAnnotation::setLinePoints(const QLinkedList<QPointF> &points)
+         XPDFReader::invTransform(MTX, points.last(), x2, y2);
+         lineann->setVertices(x1, y1, x2, y2);
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         AnnotPath *p = d->toAnnotPath(points);
+         polyann->setVertices(p);
+         delete p;
+@@ -2654,10 +2639,10 @@ LineAnnotation::TermStyle LineAnnotation::lineStartStyle() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)lineann->getStartStyle();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)polyann->getStartStyle();
+     }
+ }
+@@ -2672,10 +2657,10 @@ void LineAnnotation::setLineStartStyle(LineAnnotation::TermStyle style)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setStartEndStyle((AnnotLineEndingStyle)style, lineann->getEndStyle());
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setStartEndStyle((AnnotLineEndingStyle)style, polyann->getEndStyle());
+     }
+ }
+@@ -2689,10 +2674,10 @@ LineAnnotation::TermStyle LineAnnotation::lineEndStyle() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)lineann->getEndStyle();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)polyann->getEndStyle();
+     }
+ }
+@@ -2707,10 +2692,10 @@ void LineAnnotation::setLineEndStyle(LineAnnotation::TermStyle style)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setStartEndStyle(lineann->getStartStyle(), (AnnotLineEndingStyle)style);
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setStartEndStyle(polyann->getStartStyle(), (AnnotLineEndingStyle)style);
+     }
+ }
+@@ -2736,7 +2721,7 @@ void LineAnnotation::setLineClosed(bool closed)
+     }
+
+     if (d->pdfAnnot->getType() != Annot::typeLine) {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+
+         // Set new subtype and switch intent if necessary
+         if (closed) {
+@@ -2764,10 +2749,10 @@ QColor LineAnnotation::lineInnerColor() const
+     AnnotColor *c;
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         c = lineann->getInteriorColor();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         c = polyann->getInteriorColor();
+     }
+
+@@ -2786,10 +2771,10 @@ void LineAnnotation::setLineInnerColor(const QColor &color)
+     auto c = convertQColor(color);
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setInteriorColor(std::move(c));
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setInteriorColor(std::move(c));
+     }
+ }
+@@ -2803,7 +2788,7 @@ double LineAnnotation::lineLeadingForwardPoint() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getLeaderLineLength();
+     }
+
+@@ -2820,7 +2805,7 @@ void LineAnnotation::setLineLeadingForwardPoint(double point)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setLeaderLineLength(point);
+     }
+ }
+@@ -2834,7 +2819,7 @@ double LineAnnotation::lineLeadingBackPoint() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getLeaderLineExtension();
+     }
+
+@@ -2851,7 +2836,7 @@ void LineAnnotation::setLineLeadingBackPoint(double point)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setLeaderLineExtension(point);
+     }
+ }
+@@ -2865,7 +2850,7 @@ bool LineAnnotation::lineShowCaption() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getCaption();
+     }
+
+@@ -2882,7 +2867,7 @@ void LineAnnotation::setLineShowCaption(bool show)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setCaption(show);
+     }
+ }
+@@ -2896,10 +2881,10 @@ LineAnnotation::LineIntent LineAnnotation::lineIntent() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::LineIntent)(lineann->getIntent() + 1);
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         if (polyann->getIntent() == AnnotPolygon::polygonCloud) {
+             return LineAnnotation::PolygonCloud;
+         } else { // AnnotPolygon::polylineDimension, AnnotPolygon::polygonDimension
+@@ -2922,10 +2907,10 @@ void LineAnnotation::setLineIntent(LineAnnotation::LineIntent intent)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setIntent((AnnotLine::AnnotLineIntent)(intent - 1));
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         if (intent == LineAnnotation::PolygonCloud) {
+             polyann->setIntent(AnnotPolygon::polygonCloud);
+         } else // LineAnnotation::Dimension
+@@ -2944,8 +2929,8 @@ class GeomAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     GeomAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields (note uses border for rendering style)
+     GeomAnnotation::GeomType geomType;
+@@ -2954,15 +2939,15 @@ public:
+
+ GeomAnnotationPrivate::GeomAnnotationPrivate() : AnnotationPrivate(), geomType(GeomAnnotation::InscribedSquare) { }
+
+-Annotation *GeomAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> GeomAnnotationPrivate::makeAlias()
+ {
+-    return new GeomAnnotation(*this);
++    return std::unique_ptr<GeomAnnotation>(new GeomAnnotation(*this));
+ }
+
+-Annot *GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    GeomAnnotation *q = static_cast<GeomAnnotation *>(makeAlias());
++    std::unique_ptr<GeomAnnotation> q = static_pointer_cast<GeomAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2977,13 +2962,12 @@ Annot *GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotGeometry(destPage->getDoc(), &rect, type);
++    pdfAnnot = std::make_shared<AnnotGeometry>(destPage->getDoc(), &rect, type);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setGeomInnerColor(geomInnerColor);
+
+-    delete q;
+     return pdfAnnot;
+ }
+
+@@ -3064,7 +3048,7 @@ void GeomAnnotation::setGeomType(GeomAnnotation::GeomType type)
+         return;
+     }
+
+-    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot);
++    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot.get());
+     if (type == GeomAnnotation::InscribedSquare) {
+         geomann->setType(Annot::typeSquare);
+     } else { // GeomAnnotation::InscribedCircle
+@@ -3080,7 +3064,7 @@ QColor GeomAnnotation::geomInnerColor() const
+         return d->geomInnerColor;
+     }
+
+-    const AnnotGeometry *geomann = static_cast<const AnnotGeometry *>(d->pdfAnnot);
++    const AnnotGeometry *geomann = static_cast<const AnnotGeometry *>(d->pdfAnnot.get());
+     return convertAnnotColor(geomann->getInteriorColor());
+ }
+
+@@ -3093,7 +3077,7 @@ void GeomAnnotation::setGeomInnerColor(const QColor &color)
+         return;
+     }
+
+-    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot);
++    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot.get());
+     geomann->setInteriorColor(convertQColor(color));
+ }
+
+@@ -3102,8 +3086,8 @@ class HighlightAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     HighlightAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     HighlightAnnotation::HighlightType highlightType;
+@@ -3117,9 +3101,9 @@ public:
+
+ HighlightAnnotationPrivate::HighlightAnnotationPrivate() : AnnotationPrivate(), highlightType(HighlightAnnotation::Highlight) { }
+
+-Annotation *HighlightAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> HighlightAnnotationPrivate::makeAlias()
+ {
+-    return new HighlightAnnotation(*this);
++    return std::unique_ptr<HighlightAnnotation>(new HighlightAnnotation(*this));
+ }
+
+ Annot::AnnotSubtype HighlightAnnotationPrivate::toAnnotSubType(HighlightAnnotation::HighlightType type)
+@@ -3192,10 +3176,10 @@ AnnotQuadrilaterals *HighlightAnnotationPrivate::toQuadrilaterals(const QList<Hi
+     return new AnnotQuadrilaterals(std::move(ac), count);
+ }
+
+-Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    HighlightAnnotation *q = static_cast<HighlightAnnotation *>(makeAlias());
++    std::unique_ptr<HighlightAnnotation q = static_pointer_cast<HighlightAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -3203,7 +3187,7 @@ Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentD
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotTextMarkup(destPage->getDoc(), &rect, toAnnotSubType(highlightType));
++    pdfAnnot = std::make_shared<AnnotTextMarkup>(destPage->getDoc(), &rect, toAnnotSubType(highlightType));
+
+     // Set properties
+     flushBaseAnnotationProperties();
+@@ -3211,8 +3195,6 @@ Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentD
+
+     highlightQuads.clear(); // Free up memory
+
+-    delete q;
+-
+     return pdfAnnot;
+ }
+
+@@ -3345,7 +3327,7 @@ void HighlightAnnotation::setHighlightType(HighlightAnnotation::HighlightType ty
+         return;
+     }
+
+-    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     hlann->setType(HighlightAnnotationPrivate::toAnnotSubType(type));
+ }
+
+@@ -3357,7 +3339,7 @@ QList<HighlightAnnotation::Quad> HighlightAnnotation::highlightQuads() const
+         return d->highlightQuads;
+     }
+
+-    const AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    const AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     return d->fromQuadrilaterals(hlann->getQuadrilaterals());
+ }
+
+@@ -3370,7 +3352,7 @@ void HighlightAnnotation::setHighlightQuads(const QList<HighlightAnnotation::Qua
+         return;
+     }
+
+-    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     AnnotQuadrilaterals *quadrilaterals = d->toQuadrilaterals(quads);
+     hlann->setQuadrilaterals(quadrilaterals);
+     delete quadrilaterals;
+@@ -3381,10 +3363,10 @@ class StampAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     StampAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+-    AnnotStampImageHelper *convertQImageToAnnotStampImageHelper(const QImage &qimg);
++    std::unique_ptr<AnnotStampImageHelper> convertQImageToAnnotStampImageHelper(const QImage &qimg);
+
+     // data fields
+     QString stampIconName;
+@@ -3393,14 +3375,14 @@ public:
+
+ StampAnnotationPrivate::StampAnnotationPrivate() : AnnotationPrivate(), stampIconName(QStringLiteral("Draft")) { }
+
+-Annotation *StampAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> StampAnnotationPrivate::makeAlias()
+ {
+-    return new StampAnnotation(*this);
++    return std::unique_ptr<StampAnnotation>(new StampAnnotation(*this));
+ }
+
+-Annot *StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+-    StampAnnotation *q = static_cast<StampAnnotation *>(makeAlias());
++    std::unique_ptr<StampAnnotation> q = static_pointer_cast<StampAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -3408,21 +3390,19 @@ Annot *StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotStamp(destPage->getDoc(), &rect);
++    pdfAnnot = std::make_shared<AnnotStamp>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setStampIconName(stampIconName);
+     q->setStampCustomImage(stampCustomImage);
+
+-    delete q;
+-
+     stampIconName.clear(); // Free up memory
+
+     return pdfAnnot;
+ }
+
+-AnnotStampImageHelper *StampAnnotationPrivate::convertQImageToAnnotStampImageHelper(const QImage &qimg)
++std::unique_ptr<AnnotStampImageHelper> StampAnnotationPrivate::convertQImageToAnnotStampImageHelper(const QImage &qimg)
+ {
+     QImage convertedQImage = qimg;
+
+@@ -3503,13 +3483,13 @@ AnnotStampImageHelper *StampAnnotationPrivate::convertQImageToAnnotStampImageHel
+
+     getRawDataFromQImage(convertedQImage, convertedQImage.depth(), &data, &sMaskData);
+
+-    AnnotStampImageHelper *annotImg;
++    std::unique_ptr<AnnotStampImageHelper> annotImg;
+
+     if (sMaskData.count() > 0) {
+         AnnotStampImageHelper sMask(parentDoc->doc, width, height, ColorSpace::DeviceGray, 8, sMaskData.data(), sMaskData.count());
+-        annotImg = new AnnotStampImageHelper(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count(), sMask.getRef());
++        annotImg = std::unique_ptr<AnnotStampImageHelper>(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count(), sMask.getRef());
+     } else {
+-        annotImg = new AnnotStampImageHelper(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count());
++        annotImg = std::unique_ptr<AnnotStampImageHelper>(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count());
+     }
+
+     return annotImg;
+@@ -3570,7 +3550,7 @@ QString StampAnnotation::stampIconName() const
+         return d->stampIconName;
+     }
+
+-    const AnnotStamp *stampann = static_cast<const AnnotStamp *>(d->pdfAnnot);
++    const AnnotStamp *stampann = static_cast<const AnnotStamp *>(d->pdfAnnot.get());
+     return QString::fromLatin1(stampann->getIcon()->c_str());
+ }
+
+@@ -3583,7 +3563,7 @@ void StampAnnotation::setStampIconName(const QString &name)
+         return;
+     }
+
+-    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot);
++    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot.get());
+     QByteArray encoded = name.toLatin1();
+     GooString s(encoded.constData());
+     stampann->setIcon(&s);
+@@ -3602,9 +3582,9 @@ void StampAnnotation::setStampCustomImage(const QImage &image)
+         return;
+     }
+
+-    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot);
+-    AnnotStampImageHelper *annotCustomImage = d->convertQImageToAnnotStampImageHelper(image);
+-    stampann->setCustomImage(annotCustomImage);
++    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot.get());
++    std::unique_ptr<AnnotStampImageHelper> annotCustomImage = d->convertQImageToAnnotStampImageHelper(image);
++    stampann->setCustomImage(std::move(annotCustomImage));
+ }
+
+ /** InkAnnotation [Annotation] */
+@@ -3612,8 +3592,8 @@ class InkAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     InkAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QList<QLinkedList<QPointF>> inkPaths;
+@@ -3624,9 +3604,9 @@ public:
+
+ InkAnnotationPrivate::InkAnnotationPrivate() : AnnotationPrivate() { }
+
+-Annotation *InkAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> InkAnnotationPrivate::makeAlias()
+ {
+-    return new InkAnnotation(*this);
++    return std::unique_ptr<InkAnnotation>(new InkAnnotation(*this));
+ }
+
+ // Note: Caller is required to delete array elements and the array itself after use
+@@ -3640,10 +3620,10 @@ AnnotPath **InkAnnotationPrivate::toAnnotPaths(const QList<QLinkedList<QPointF>>
+     return res;
+ }
+
+-Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    InkAnnotation *q = static_cast<InkAnnotation *>(makeAlias());
++    std::unique_ptr<InkAnnotation> q = static_pointer_cast<InkAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -3651,7 +3631,7 @@ Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *d
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotInk(destPage->getDoc(), &rect);
++    pdfAnnot = std::make_shared<AnnotInk>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+@@ -3659,8 +3639,6 @@ Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *d
+
+     inkPaths.clear(); // Free up memory
+
+-    delete q;
+-
+     return pdfAnnot;
+ }
+
+@@ -3762,7 +3740,7 @@ QList<QLinkedList<QPointF>> InkAnnotation::inkPaths() const
+         return d->inkPaths;
+     }
+
+-    const AnnotInk *inkann = static_cast<const AnnotInk *>(d->pdfAnnot);
++    const AnnotInk *inkann = static_cast<const AnnotInk *>(d->pdfAnnot.get());
+
+     const AnnotPath *const *paths = inkann->getInkList();
+     if (!paths || !inkann->getInkListLength()) {
+@@ -3800,7 +3778,7 @@ void InkAnnotation::setInkPaths(const QList<QLinkedList<QPointF>> &paths)
+         return;
+     }
+
+-    AnnotInk *inkann = static_cast<AnnotInk *>(d->pdfAnnot);
++    AnnotInk *inkann = static_cast<AnnotInk *>(d->pdfAnnot.get());
+     AnnotPath **annotpaths = d->toAnnotPaths(paths);
+     const int pathsNumber = paths.size();
+     inkann->setInkList(annotpaths, pathsNumber);
+@@ -3817,8 +3795,8 @@ class LinkAnnotationPrivate : public AnnotationPrivate
+ public:
+     LinkAnnotationPrivate();
+     ~LinkAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot>(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     Link *linkDestination;
+@@ -4119,8 +4097,8 @@ class CaretAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     CaretAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     CaretAnnotation::CaretSymbol symbol;
+@@ -4149,15 +4127,15 @@ static CaretAnnotation::CaretSymbol caretSymbolFromString(const QString &symbol)
+
+ CaretAnnotationPrivate::CaretAnnotationPrivate() : AnnotationPrivate(), symbol(CaretAnnotation::None) { }
+
+-Annotation *CaretAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> CaretAnnotationPrivate::makeAlias()
+ {
+-    return new CaretAnnotation(*this);
++    return std::unique_ptr<CaretAnnotation>(new CaretAnnotation(*this));
+ }
+
+-Annot *CaretAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> CaretAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    CaretAnnotation *q = static_cast<CaretAnnotation *>(makeAlias());
++    std::unique_ptr<CaretAnnotation> q = static_pointer_cast<CaretAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -4165,13 +4143,12 @@ Annot *CaretAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotCaret(destPage->getDoc(), &rect);
++    pdfAnnot = std::make_shared<AnnotCaret>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setCaretSymbol(symbol);
+
+-    delete q;
+     return pdfAnnot;
+ }
+
+@@ -4230,7 +4207,7 @@ CaretAnnotation::CaretSymbol CaretAnnotation::caretSymbol() const
+         return d->symbol;
+     }
+
+-    const AnnotCaret *caretann = static_cast<const AnnotCaret *>(d->pdfAnnot);
++    const AnnotCaret *caretann = static_cast<const AnnotCaret *>(d->pdfAnnot.get());
+     return (CaretAnnotation::CaretSymbol)caretann->getSymbol();
+ }
+
+@@ -4243,7 +4220,7 @@ void CaretAnnotation::setCaretSymbol(CaretAnnotation::CaretSymbol symbol)
+         return;
+     }
+
+-    AnnotCaret *caretann = static_cast<AnnotCaret *>(d->pdfAnnot);
++    AnnotCaret *caretann = static_cast<AnnotCaret *>(d->pdfAnnot.get());
+     caretann->setSymbol((AnnotCaret::AnnotCaretSymbol)symbol);
+ }
+
+@@ -4253,8 +4230,8 @@ class FileAttachmentAnnotationPrivate : public AnnotationPrivate
+ public:
+     FileAttachmentAnnotationPrivate();
+     ~FileAttachmentAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QString icon;
+@@ -4268,12 +4245,12 @@ FileAttachmentAnnotationPrivate::~FileAttachmentAnnotationPrivate()
+     delete embfile;
+ }
+
+-Annotation *FileAttachmentAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> FileAttachmentAnnotationPrivate::makeAlias()
+ {
+-    return new FileAttachmentAnnotation(*this);
++    return std::unique_ptr<FileAttachmentAnnotation>(new FileAttachmentAnnotation(*this));
+ }
+
+-Annot *FileAttachmentAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> FileAttachmentAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -4345,8 +4322,8 @@ class SoundAnnotationPrivate : public AnnotationPrivate
+ public:
+     SoundAnnotationPrivate();
+     ~SoundAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QString icon;
+@@ -4360,12 +4337,12 @@ SoundAnnotationPrivate::~SoundAnnotationPrivate()
+     delete sound;
+ }
+
+-Annotation *SoundAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> SoundAnnotationPrivate::makeAlias()
+ {
+-    return new SoundAnnotation(*this);
++    return std::unique_ptr<SoundAnnotation>(new SoundAnnotation(*this));
+ }
+
+-Annot *SoundAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptrAnnot> SoundAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -4437,8 +4414,8 @@ class MovieAnnotationPrivate : public AnnotationPrivate
+ public:
+     MovieAnnotationPrivate();
+     ~MovieAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     MovieObject *movie;
+@@ -4452,12 +4429,12 @@ MovieAnnotationPrivate::~MovieAnnotationPrivate()
+     delete movie;
+ }
+
+-Annotation *MovieAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> MovieAnnotationPrivate::makeAlias()
+ {
+-    return new MovieAnnotation(*this);
++    return std::unique_ptr<Annotation>(new MovieAnnotation(*this));
+ }
+
+-Annot *MovieAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> MovieAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -4529,8 +4506,8 @@ class ScreenAnnotationPrivate : public AnnotationPrivate
+ public:
+     ScreenAnnotationPrivate();
+     ~ScreenAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     LinkRendition *action;
+@@ -4546,12 +4523,12 @@ ScreenAnnotationPrivate::~ScreenAnnotationPrivate()
+
+ ScreenAnnotation::ScreenAnnotation(ScreenAnnotationPrivate &dd) : Annotation(dd) { }
+
+-Annotation *ScreenAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> ScreenAnnotationPrivate::makeAlias()
+ {
+-    return new ScreenAnnotation(*this);
++    return std::unique_ptr<ScreenAnnotation>(new ScreenAnnotation(*this));
+ }
+
+-Annot *ScreenAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> ScreenAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -4609,16 +4586,16 @@ Link *ScreenAnnotation::additionalAction(AdditionalActionType type) const
+ class WidgetAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+ };
+
+-Annotation *WidgetAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> WidgetAnnotationPrivate::makeAlias()
+ {
+-    return new WidgetAnnotation(*this);
++    return std::unique_ptr<WidgetAnnotation>(new WidgetAnnotation(*this));
+ }
+
+-Annot *WidgetAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> WidgetAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -4942,9 +4919,9 @@ public:
+
+     ~RichMediaAnnotationPrivate() override;
+
+-    Annotation *makeAlias() override { return new RichMediaAnnotation(*this); }
++    std::unique_ptr<Annotation> makeAlias() override { return std::unique_ptr<RichMediaAnnotation>(new RichMediaAnnotation(*this)); }
+
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override
+     {
+         Q_UNUSED(destPage);
+         Q_UNUSED(doc);
+diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
+index 665fb5f..db0a6e8 100644
+--- a/qt5/src/poppler-form.cc
++++ b/qt5/src/poppler-form.cc
+@@ -259,7 +259,7 @@ Link *FormField::additionalAction(AdditionalActionType type) const
+
+ Link *FormField::additionalAction(Annotation::AdditionalActionType type) const
+ {
+-    ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
++    std::shared_ptr<AnnotWidget> w = m_formData->fm->getWidgetAnnotation();
+     if (!w) {
+         return nullptr;
+     }
+@@ -340,7 +340,7 @@ void FormFieldButton::setIcon(const FormFieldIcon &icon)
+
+     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
+     if (fwb->getButtonType() == formButtonPush) {
+-        ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
++        ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation().get();
+         FormFieldIconData *data = FormFieldIconData::getData(icon);
+         if (data->icon != nullptr) {
+             w->setNewAppearance(data->icon->lookup("AP"));
+diff --git a/qt6/src/poppler-annotation-private.h b/qt6/src/poppler-annotation-private.h
+index 35e2676..da1ab71 100644
+--- a/qt6/src/poppler-annotation-private.h
++++ b/qt6/src/poppler-annotation-private.h
+@@ -59,7 +59,7 @@ public:
+
+     /* Returns an Annotation of the right subclass whose d_ptr points to
+      * this AnnotationPrivate */
+-    virtual Annotation *makeAlias() = 0;
++    virtual Astd::unique_ptr<nnotation> makeAlias() = 0;
+
+     /* properties: contents related */
+     QString author;
+@@ -79,18 +79,18 @@ public:
+     /* revisions */
+     Annotation::RevScope revisionScope;
+     Annotation::RevType revisionType;
+-    QList<Annotation *> revisions;
++    std::vector<std::unique_ptr<Annotation>> revisions;
+
+     /* After this call, the Annotation object will behave like a wrapper for
+      * the specified Annot object. All cached values are discarded */
+-    void tieToNativeAnnot(Annot *ann, ::Page *page, DocumentData *doc);
++    void tieToNativeAnnot(std::shared_ptr<Annot> ann, ::Page *page, DocumentData *doc);
+
+     /* Creates a new Annot object on the specified page, flushes current
+      * values to that object and ties this Annotation to that object */
+-    virtual Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) = 0;
++    virtual std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) = 0;
+
+     /* Inited to 0 (i.e. untied annotation) */
+-    Annot *pdfAnnot;
++    std::shared_ptr<Annot> pdfAnnot;
+     ::Page *pdfPage;
+     DocumentData *parentDoc;
+
+diff --git a/qt6/src/poppler-annotation.cc b/qt6/src/poppler-annotation.cc
+index 5770be6..d38aee2 100644
+--- a/qt6/src/poppler-annotation.cc
++++ b/qt6/src/poppler-annotation.cc
+@@ -57,6 +57,12 @@
+ #include <Link.h>
+ #include <DateInfo.h>
+
++template<typename T, typename U>
++static std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U> &&in)
++{
++    return std::unique_ptr<T>(static_cast<std::add_pointer_t<T>>(in.release()));
++}
++
+ /* Almost all getters directly query the underlying poppler annotation, with
+  * the exceptions of link, file attachment, sound, movie and screen annotations,
+  * Whose data retrieval logic has not been moved yet. Their getters return
+@@ -129,36 +135,25 @@ void getRawDataFromQImage(const QImage &qimg, int bitsPerPixel, QByteArray *data
+ void AnnotationPrivate::addRevision(Annotation *ann, Annotation::RevScope scope, Annotation::RevType type)
+ {
+     /* Since ownership stays with the caller, create an alias of ann */
+-    revisions.append(ann->d_ptr->makeAlias());
++    revisions.push_back(ann->d_ptr->makeAlias());
+
+     /* Set revision properties */
+     revisionScope = scope;
+     revisionType = type;
+ }
+
+-AnnotationPrivate::~AnnotationPrivate()
+-{
+-    // Delete all children revisions
+-    qDeleteAll(revisions);
+-
+-    // Release Annot object
+-    if (pdfAnnot) {
+-        pdfAnnot->decRefCnt();
+-    }
+-}
++AnnotationPrivate::~AnnotationPrivate() = default;
+
+-void AnnotationPrivate::tieToNativeAnnot(Annot *ann, ::Page *page, Poppler::DocumentData *doc)
++void AnnotationPrivate::tieToNativeAnnot(std::shared_ptr<Annot> ann, ::Page *page, Poppler::DocumentData *doc)
+ {
+     if (pdfAnnot) {
+         error(errIO, -1, "Annotation is already tied");
+         return;
+     }
+
+-    pdfAnnot = ann;
++    pdfAnnot = std::move(ann);
+     pdfPage = page;
+     parentDoc = doc;
+-
+-    pdfAnnot->incRefCnt();
+ }
+
+ /* This method is called when a new annotation is created, after pdfAnnot and
+@@ -167,7 +162,7 @@ void AnnotationPrivate::flushBaseAnnotationProperties()
+ {
+     Q_ASSERT(pdfPage);
+
+-    Annotation *q = makeAlias(); // Setters are defined in the public class
++    std::unique_ptr<Annotation> q = makeAlias(); // Setters are defined in the public class
+
+     // Since pdfAnnot has been set, this calls will write in the Annot object
+     q->setAuthor(author);
+@@ -180,14 +175,6 @@ void AnnotationPrivate::flushBaseAnnotationProperties()
+     q->setStyle(style);
+     q->setPopup(popup);
+
+-    // Flush revisions
+-    foreach (Annotation *r, revisions) {
+-        // TODO: Flush revision
+-        delete r; // Object is no longer needed
+-    }
+-
+-    delete q;
+-
+     // Clear some members to save memory
+     author.clear();
+     contents.clear();
+@@ -377,14 +364,14 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+
+     // Create Annotation objects and tie to their native Annot
+     std::vector<std::unique_ptr<Annotation>> res;
+-    for (Annot *ann : annots->getAnnots()) {
++    for (const std::shared_ptr<Annot> &ann : annots->getAnnots()) {
+         if (!ann) {
+             error(errInternal, -1, "Annot is null");
+             continue;
+         }
+
+         // Check parent annotation
+-        AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(ann);
++        AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(ann.get());
+         if (!markupann) {
+             // Assume it's a root annotation, and skip if user didn't request it
+             if (parentID != -1) {
+@@ -458,7 +445,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+                 continue;
+             }
+             // parse Link params
+-            AnnotLink *linkann = static_cast<AnnotLink *>(ann);
++            AnnotLink *linkann = static_cast<AnnotLink *>(ann.get());
+             LinkAnnotation *l = new LinkAnnotation();
+
+             // -> hlMode
+@@ -488,7 +475,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+             if (!wantFileAttachmentAnnotations) {
+                 continue;
+             }
+-            AnnotFileAttachment *attachann = static_cast<AnnotFileAttachment *>(ann);
++            AnnotFileAttachment *attachann = static_cast<AnnotFileAttachment *>(ann.get());
+             FileAttachmentAnnotation *f = new FileAttachmentAnnotation();
+             // -> fileIcon
+             f->setFileIconName(QString::fromLatin1(attachann->getName()->c_str()));
+@@ -503,7 +490,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+             if (!wantSoundAnnotations) {
+                 continue;
+             }
+-            AnnotSound *soundann = static_cast<AnnotSound *>(ann);
++            AnnotSound *soundann = static_cast<AnnotSound *>(ann.get());
+             SoundAnnotation *s = new SoundAnnotation();
+
+             // -> soundIcon
+@@ -518,7 +505,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+             if (!wantMovieAnnotations) {
+                 continue;
+             }
+-            AnnotMovie *movieann = static_cast<AnnotMovie *>(ann);
++            AnnotMovie *movieann = static_cast<AnnotMovie *>(ann.get());
+             MovieAnnotation *m = new MovieAnnotation();
+
+             // -> movie
+@@ -536,7 +523,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+             if (!wantScreenAnnotations) {
+                 continue;
+             }
+-            AnnotScreen *screenann = static_cast<AnnotScreen *>(ann);
++            AnnotScreen *screenann = static_cast<AnnotScreen *>(ann.get());
+             // TODO Support other link types than Link::Rendition in ScreenAnnotation
+             if (!screenann->getAction() || screenann->getAction()->getKind() != actionRendition) {
+                 continue;
+@@ -566,7 +553,7 @@ std::vector<std::unique_ptr<Annotation>> AnnotationPrivate::findAnnotations(::Pa
+             annotation.reset(new WidgetAnnotation());
+             break;
+         case Annot::typeRichMedia: {
+-            const AnnotRichMedia *annotRichMedia = static_cast<AnnotRichMedia *>(ann);
++            const AnnotRichMedia *annotRichMedia = static_cast<AnnotRichMedia *>(ann.get());
+
+             RichMediaAnnotation *richMediaAnnotation = new RichMediaAnnotation;
+
+@@ -774,9 +761,9 @@ std::unique_ptr<Link> AnnotationPrivate::additionalAction(Annotation::Additional
+
+     std::unique_ptr<::LinkAction> linkAction;
+     if (pdfAnnot->getType() == Annot::typeScreen) {
+-        linkAction = static_cast<AnnotScreen *>(pdfAnnot)->getAdditionalAction(actionType);
++        linkAction = static_cast<AnnotScreen *>(pdfAnnot.get())->getAdditionalAction(actionType);
+     } else {
+-        linkAction = static_cast<AnnotWidget *>(pdfAnnot)->getAdditionalAction(actionType);
++        linkAction = static_cast<AnnotWidget *>(pdfAnnot.get())->getAdditionalAction(actionType);
+     }
+
+     if (linkAction) {
+@@ -795,7 +782,7 @@ void AnnotationPrivate::addAnnotationToPage(::Page *pdfPage, DocumentData *doc,
+
+     // Unimplemented annotations can't be created by the user because their ctor
+     // is private. Therefore, createNativeAnnot will never return 0
+-    Annot *nativeAnnot = ann->d_ptr->createNativeAnnot(pdfPage, doc);
++    std::shared_ptr<Annot> nativeAnnot = ann->d_ptr->createNativeAnnot(pdfPage, doc);
+     Q_ASSERT(nativeAnnot);
+
+     if (ann->d_ptr->annotationAppearance.isStream()) {
+@@ -1038,7 +1025,7 @@ QString Annotation::author() const
+         return d->author;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     return markupann ? UnicodeParsedString(markupann->getLabel()) : QString();
+ }
+
+@@ -1051,7 +1038,7 @@ void Annotation::setAuthor(const QString &author)
+         return;
+     }
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         markupann->setLabel(std::unique_ptr<GooString>(QStringToUnicodeGooString(author)));
+     }
+@@ -1149,7 +1136,7 @@ QDateTime Annotation::creationDate() const
+         return d->creationDate;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+
+     if (markupann && markupann->getDate()) {
+         return convertDate(markupann->getDate()->c_str());
+@@ -1167,7 +1154,7 @@ void Annotation::setCreationDate(const QDateTime &date)
+         return;
+     }
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         if (date.isValid()) {
+             const time_t t = date.toSecsSinceEpoch();
+@@ -1279,8 +1266,7 @@ void Annotation::setBoundary(const QRectF &boundary)
+     Q_D(Annotation);
+
+     if (!d->pdfAnnot) {
+-        d->boundary = boundary;
+-        return;
++        d->boundary = boundary;        return;
+     }
+
+     PDFRectangle rect = d->boundaryToPdfRectangle(boundary, flags());
+@@ -1298,7 +1284,7 @@ Annotation::Style Annotation::style() const
+     Style s;
+     s.setColor(convertAnnotColor(d->pdfAnnot->getColor()));
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         s.setOpacity(markupann->getOpacity());
+     }
+@@ -1326,11 +1312,11 @@ Annotation::Style Annotation::style() const
+     AnnotBorderEffect *border_effect;
+     switch (d->pdfAnnot->getType()) {
+     case Annot::typeFreeText:
+-        border_effect = static_cast<AnnotFreeText *>(d->pdfAnnot)->getBorderEffect();
++        border_effect = static_cast<AnnotFreeText *>(d->pdfAnnot.get())->getBorderEffect();
+         break;
+     case Annot::typeSquare:
+     case Annot::typeCircle:
+-        border_effect = static_cast<AnnotGeometry *>(d->pdfAnnot)->getBorderEffect();
++        border_effect = static_cast<AnnotGeometry *>(d->pdfAnnot.get())->getBorderEffect();
+         break;
+     default:
+         border_effect = nullptr;
+@@ -1354,7 +1340,7 @@ void Annotation::setStyle(const Annotation::Style &style)
+
+     d->pdfAnnot->setColor(convertQColor(style.color()));
+
+-    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot);
++    AnnotMarkup *markupann = dynamic_cast<AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         markupann->setOpacity(style.opacity());
+     }
+@@ -1375,10 +1361,10 @@ Annotation::Popup Annotation::popup() const
+     }
+
+     Popup w;
+-    AnnotPopup *popup = nullptr;
++    std::shared_ptr<AnnotPopup> popup = nullptr;
+     int flags = -1; // Not initialized
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+     if (markupann) {
+         popup = markupann->getPopup();
+         w.setSummary(UnicodeParsedString(markupann->getSubject()));
+@@ -1396,7 +1382,7 @@ Annotation::Popup Annotation::popup() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot);
++        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot.get());
+
+         // Text annotations default to same rect as annotation
+         if (flags == -1) {
+@@ -1452,7 +1438,7 @@ Annotation::RevScope Annotation::revisionScope() const
+         return d->revisionScope;
+     }
+
+-    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot);
++    const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup *>(d->pdfAnnot.get());
+
+     if (markupann && markupann->isInReplyTo()) {
+         switch (markupann->getReplyTo()) {
+@@ -1505,8 +1491,10 @@ std::vector<std::unique_ptr<Annotation>> Annotation::revisions() const
+     if (!d->pdfAnnot) {
+         /* Return aliases, whose ownership goes to the caller */
+         std::vector<std::unique_ptr<Annotation>> res;
+-        foreach (Annotation *rev, d->revisions)
+-            res.push_back(std::unique_ptr<Annotation>(rev->d_ptr->makeAlias()));
++        res.reserve(d->revisions.size());
++        for (const std::unique_ptr<Annotation> &rev : d->revisions) {
++            res.push_back(rev->d_ptr->makeAlias());
++        }
+         return res;
+     }
+
+@@ -1523,7 +1511,7 @@ std::unique_ptr<AnnotationAppearance> Annotation::annotationAppearance() const
+ {
+     Q_D(const Annotation);
+
+-    return std::make_unique<AnnotationAppearance>(new AnnotationAppearancePrivate(d->pdfAnnot));
++    return std::make_unique<AnnotationAppearance>(new AnnotationAppearancePrivate(d->pdfAnnot.get()));
+ }
+
+ void Annotation::setAnnotationAppearance(const AnnotationAppearance &annotationAppearance)
+@@ -1548,8 +1536,8 @@ class TextAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     TextAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+     void setDefaultAppearanceToNative();
+     std::unique_ptr<DefaultAppearance> getDefaultAppearanceFromNative() const;
+
+@@ -1565,15 +1553,15 @@ public:
+
+ TextAnnotationPrivate::TextAnnotationPrivate() : AnnotationPrivate(), textType(TextAnnotation::Linked), textIcon(QStringLiteral("Note")), inplaceAlign(TextAnnotation::InplaceAlignLeft), inplaceIntent(TextAnnotation::Unknown) { }
+
+-Annotation *TextAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> TextAnnotationPrivate::makeAlias()
+ {
+-    return new TextAnnotation(*this);
++    return std::unique_ptr<Annotation>(new TextAnnotation(*this));
+ }
+
+-Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    TextAnnotation *q = static_cast<TextAnnotation *>(makeAlias());
++    std::unique_ptr<TextAnnotation> q = static_pointer_cast<TextAnnotation *>(makeAlias());
+
+     // Set page and contents
+     pdfPage = destPage;
+@@ -1582,14 +1570,14 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+     if (textType == TextAnnotation::Linked) {
+-        pdfAnnot = new AnnotText { destPage->getDoc(), &rect };
++        pdfAnnot = std::make_shared<AnnotText>(destPage->getDoc(), &rect);
+     } else {
+         const double pointSize = textFont ? textFont->pointSizeF() : AnnotFreeText::undefinedFontPtSize;
+         if (pointSize < 0) {
+             qWarning() << "TextAnnotationPrivate::createNativeAnnot: font pointSize < 0";
+         }
+         DefaultAppearance da { { objName, "Invalid_font" }, pointSize, convertQColor(textColor) };
+-        pdfAnnot = new AnnotFreeText { destPage->getDoc(), &rect, da };
++        pdfAnnot = std::make_shared<AnnotFreeText>(destPage->getDoc(), &rect, da);
+     }
+
+     // Set properties
+@@ -1599,8 +1587,6 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     q->setCalloutPoints(inplaceCallout);
+     q->setInplaceIntent(inplaceIntent);
+
+-    delete q;
+-
+     inplaceCallout.clear(); // Free up memory
+
+     return pdfAnnot;
+@@ -1609,7 +1595,7 @@ Annot *TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+ void TextAnnotationPrivate::setDefaultAppearanceToNative()
+ {
+     if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot.get());
+         const double pointSize = textFont ? textFont->pointSizeF() : AnnotFreeText::undefinedFontPtSize;
+         if (pointSize < 0) {
+             qWarning() << "TextAnnotationPrivate::createNativeAnnot: font pointSize < 0";
+@@ -1622,7 +1608,7 @@ void TextAnnotationPrivate::setDefaultAppearanceToNative()
+ std::unique_ptr<DefaultAppearance> TextAnnotationPrivate::getDefaultAppearanceFromNative() const
+ {
+     if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(pdfAnnot.get());
+         return ftextann->getDefaultAppearance();
+     } else {
+         return {};
+@@ -1676,7 +1662,7 @@ QString TextAnnotation::textIcon() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot);
++        const AnnotText *textann = static_cast<const AnnotText *>(d->pdfAnnot.get());
+         return QString::fromLatin1(textann->getIcon()->c_str());
+     }
+
+@@ -1693,7 +1679,7 @@ void TextAnnotation::setTextIcon(const QString &icon)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeText) {
+-        AnnotText *textann = static_cast<AnnotText *>(d->pdfAnnot);
++        AnnotText *textann = static_cast<AnnotText *>(d->pdfAnnot.get());
+         QByteArray encoded = icon.toLatin1();
+         GooString s(encoded.constData());
+         textann->setIcon(&s);
+@@ -1767,7 +1753,7 @@ TextAnnotation::InplaceAlignPosition TextAnnotation::inplaceAlign() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+         switch (ftextann->getQuadding()) {
+         case VariableTextQuadding::leftJustified:
+             return InplaceAlignLeft;
+@@ -1804,7 +1790,7 @@ void TextAnnotation::setInplaceAlign(InplaceAlignPosition align)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+         ftextann->setQuadding(alignToQuadding(align));
+     }
+ }
+@@ -1831,7 +1817,7 @@ QVector<QPointF> TextAnnotation::calloutPoints() const
+         return QVector<QPointF>();
+     }
+
+-    const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++    const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+     const AnnotCalloutLine *callout = ftextann->getCalloutLine();
+
+     if (!callout) {
+@@ -1863,7 +1849,7 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+         return;
+     }
+
+-    AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++    AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+     const int count = points.size();
+
+     if (count == 0) {
+@@ -1876,7 +1862,7 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+         return;
+     }
+
+-    AnnotCalloutLine *callout;
++    std::unique_ptr<AnnotCalloutLine> callout;
+     double x1, y1, x2, y2;
+     double MTX[6];
+     d->fillTransformationMTX(MTX);
+@@ -1886,13 +1872,12 @@ void TextAnnotation::setCalloutPoints(const QVector<QPointF> &points)
+     if (count == 3) {
+         double x3, y3;
+         XPDFReader::invTransform(MTX, points[2], x3, y3);
+-        callout = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
++        callout = std::unique_ptr<AnnotCalloutMultiLine>(x1, y1, x2, y2, x3, y3);
+     } else {
+-        callout = new AnnotCalloutLine(x1, y1, x2, y2);
++        callout = std::unique_ptr<AnnotCalloutLine>(x1, y1, x2, y2);
+     }
+
+-    ftextann->setCalloutLine(callout);
+-    delete callout;
++    ftextann->setCalloutLine(std::move(callout));
+ }
+
+ TextAnnotation::InplaceIntent TextAnnotation::inplaceIntent() const
+@@ -1904,7 +1889,7 @@ TextAnnotation::InplaceIntent TextAnnotation::inplaceIntent() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot);
++        const AnnotFreeText *ftextann = static_cast<const AnnotFreeText *>(d->pdfAnnot.get());
+         return (TextAnnotation::InplaceIntent)ftextann->getIntent();
+     }
+
+@@ -1921,7 +1906,7 @@ void TextAnnotation::setInplaceIntent(TextAnnotation::InplaceIntent intent)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeFreeText) {
+-        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot);
++        AnnotFreeText *ftextann = static_cast<AnnotFreeText *>(d->pdfAnnot.get());
+         ftextann->setIntent((AnnotFreeText::AnnotFreeTextIntent)intent);
+     }
+ }
+@@ -1931,8 +1916,8 @@ class LineAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     LineAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields (note uses border for rendering style)
+     QVector<QPointF> linePoints;
+@@ -1952,15 +1937,15 @@ LineAnnotationPrivate::LineAnnotationPrivate()
+ {
+ }
+
+-Annotation *LineAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> LineAnnotationPrivate::makeAlias()
+ {
+-    return new LineAnnotation(*this);
++    return std::unique_ptr<Annotation>(new LineAnnotation(*this));
+ }
+
+-Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    LineAnnotation *q = static_cast<LineAnnotation *>(makeAlias());
++    std::unique_ptr<LineAnnotation> q = static_pointer_cast<LineAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -1969,9 +1954,9 @@ Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+     if (lineType == LineAnnotation::StraightLine) {
+-        pdfAnnot = new AnnotLine(doc->doc, &rect);
++        pdfAnnot = std::shared_ptr<AnnotLine>(doc->doc, &rect);
+     } else {
+-        pdfAnnot = new AnnotPolygon(doc->doc, &rect, lineClosed ? Annot::typePolygon : Annot::typePolyLine);
++        pdfAnnot = std::shared_ptr<AnnotPolygon>(doc->doc, &rect, lineClosed ? Annot::typePolygon : Annot::typePolyLine);
+     }
+
+     // Set properties
+@@ -1985,8 +1970,6 @@ Annot *LineAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+     q->setLineShowCaption(lineShowCaption);
+     q->setLineIntent(lineIntent);
+
+-    delete q;
+-
+     linePoints.clear(); // Free up memory
+
+     return pdfAnnot;
+@@ -2043,14 +2026,14 @@ QVector<QPointF> LineAnnotation::linePoints() const
+
+     QVector<QPointF> res;
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         QPointF p;
+         XPDFReader::transform(MTX, lineann->getX1(), lineann->getY1(), p);
+         res.append(p);
+         XPDFReader::transform(MTX, lineann->getX2(), lineann->getY2(), p);
+         res.append(p);
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         const AnnotPath *vertices = polyann->getVertices();
+
+         for (int i = 0; i < vertices->getCoordsLength(); ++i) {
+@@ -2073,7 +2056,7 @@ void LineAnnotation::setLinePoints(const QVector<QPointF> &points)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         if (points.size() != 2) {
+             error(errSyntaxError, -1, "Expected two points for a straight line");
+             return;
+@@ -2085,7 +2068,7 @@ void LineAnnotation::setLinePoints(const QVector<QPointF> &points)
+         XPDFReader::invTransform(MTX, points.last(), x2, y2);
+         lineann->setVertices(x1, y1, x2, y2);
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         AnnotPath *p = d->toAnnotPath(points);
+         polyann->setVertices(p);
+         delete p;
+@@ -2101,10 +2084,10 @@ LineAnnotation::TermStyle LineAnnotation::lineStartStyle() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)lineann->getStartStyle();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)polyann->getStartStyle();
+     }
+ }
+@@ -2119,10 +2102,10 @@ void LineAnnotation::setLineStartStyle(LineAnnotation::TermStyle style)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setStartEndStyle((AnnotLineEndingStyle)style, lineann->getEndStyle());
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setStartEndStyle((AnnotLineEndingStyle)style, polyann->getEndStyle());
+     }
+ }
+@@ -2136,10 +2119,10 @@ LineAnnotation::TermStyle LineAnnotation::lineEndStyle() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)lineann->getEndStyle();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         return (LineAnnotation::TermStyle)polyann->getEndStyle();
+     }
+ }
+@@ -2154,10 +2137,10 @@ void LineAnnotation::setLineEndStyle(LineAnnotation::TermStyle style)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setStartEndStyle(lineann->getStartStyle(), (AnnotLineEndingStyle)style);
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setStartEndStyle(polyann->getStartStyle(), (AnnotLineEndingStyle)style);
+     }
+ }
+@@ -2183,7 +2166,7 @@ void LineAnnotation::setLineClosed(bool closed)
+     }
+
+     if (d->pdfAnnot->getType() != Annot::typeLine) {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+
+         // Set new subtype and switch intent if necessary
+         if (closed) {
+@@ -2211,10 +2194,10 @@ QColor LineAnnotation::lineInnerColor() const
+     AnnotColor *c;
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         c = lineann->getInteriorColor();
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         c = polyann->getInteriorColor();
+     }
+
+@@ -2233,10 +2216,10 @@ void LineAnnotation::setLineInnerColor(const QColor &color)
+     auto c = convertQColor(color);
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setInteriorColor(std::move(c));
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         polyann->setInteriorColor(std::move(c));
+     }
+ }
+@@ -2250,7 +2233,7 @@ double LineAnnotation::lineLeadingForwardPoint() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getLeaderLineLength();
+     }
+
+@@ -2267,7 +2250,7 @@ void LineAnnotation::setLineLeadingForwardPoint(double point)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setLeaderLineLength(point);
+     }
+ }
+@@ -2281,7 +2264,7 @@ double LineAnnotation::lineLeadingBackPoint() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getLeaderLineExtension();
+     }
+
+@@ -2298,7 +2281,7 @@ void LineAnnotation::setLineLeadingBackPoint(double point)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setLeaderLineExtension(point);
+     }
+ }
+@@ -2312,7 +2295,7 @@ bool LineAnnotation::lineShowCaption() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return lineann->getCaption();
+     }
+
+@@ -2329,7 +2312,7 @@ void LineAnnotation::setLineShowCaption(bool show)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setCaption(show);
+     }
+ }
+@@ -2343,10 +2326,10 @@ LineAnnotation::LineIntent LineAnnotation::lineIntent() const
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot);
++        const AnnotLine *lineann = static_cast<const AnnotLine *>(d->pdfAnnot.get());
+         return (LineAnnotation::LineIntent)(lineann->getIntent() + 1);
+     } else {
+-        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot);
++        const AnnotPolygon *polyann = static_cast<const AnnotPolygon *>(d->pdfAnnot.get());
+         if (polyann->getIntent() == AnnotPolygon::polygonCloud) {
+             return LineAnnotation::PolygonCloud;
+         } else { // AnnotPolygon::polylineDimension, AnnotPolygon::polygonDimension
+@@ -2369,10 +2352,10 @@ void LineAnnotation::setLineIntent(LineAnnotation::LineIntent intent)
+     }
+
+     if (d->pdfAnnot->getType() == Annot::typeLine) {
+-        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot);
++        AnnotLine *lineann = static_cast<AnnotLine *>(d->pdfAnnot.get());
+         lineann->setIntent((AnnotLine::AnnotLineIntent)(intent - 1));
+     } else {
+-        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot);
++        AnnotPolygon *polyann = static_cast<AnnotPolygon *>(d->pdfAnnot.get());
+         if (intent == LineAnnotation::PolygonCloud) {
+             polyann->setIntent(AnnotPolygon::polygonCloud);
+         } else // LineAnnotation::Dimension
+@@ -2391,8 +2374,8 @@ class GeomAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     GeomAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields (note uses border for rendering style)
+     GeomAnnotation::GeomType geomType;
+@@ -2401,15 +2384,15 @@ public:
+
+ GeomAnnotationPrivate::GeomAnnotationPrivate() : AnnotationPrivate(), geomType(GeomAnnotation::InscribedSquare) { }
+
+-Annotation *GeomAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> GeomAnnotationPrivate::makeAlias()
+ {
+-    return new GeomAnnotation(*this);
++    return std::unique_ptr<Annotation>(new GeomAnnotation(*this));
+ }
+
+-Annot *GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    GeomAnnotation *q = static_cast<GeomAnnotation *>(makeAlias());
++    std::unique_ptr<GeomAnnotation> q = static_pointer_cast<GeomAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2424,13 +2407,12 @@ Annot *GeomAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotGeometry(destPage->getDoc(), &rect, type);
++    pdfAnnot = std::make_shared<AnnotGeometry>(destPage->getDoc(), &rect, type);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setGeomInnerColor(geomInnerColor);
+
+-    delete q;
+     return pdfAnnot;
+ }
+
+@@ -2469,7 +2451,7 @@ void GeomAnnotation::setGeomType(GeomAnnotation::GeomType type)
+         return;
+     }
+
+-    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot);
++    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot.get());
+     if (type == GeomAnnotation::InscribedSquare) {
+         geomann->setType(Annot::typeSquare);
+     } else { // GeomAnnotation::InscribedCircle
+@@ -2485,7 +2467,7 @@ QColor GeomAnnotation::geomInnerColor() const
+         return d->geomInnerColor;
+     }
+
+-    const AnnotGeometry *geomann = static_cast<const AnnotGeometry *>(d->pdfAnnot);
++    const AnnotGeometry *geomann = static_cast<const AnnotGeometry *>(d->pdfAnnot.get());
+     return convertAnnotColor(geomann->getInteriorColor());
+ }
+
+@@ -2498,7 +2480,7 @@ void GeomAnnotation::setGeomInnerColor(const QColor &color)
+         return;
+     }
+
+-    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot);
++    AnnotGeometry *geomann = static_cast<AnnotGeometry *>(d->pdfAnnot.get());
+     geomann->setInteriorColor(convertQColor(color));
+ }
+
+@@ -2507,8 +2489,8 @@ class HighlightAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     HighlightAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     HighlightAnnotation::HighlightType highlightType;
+@@ -2522,9 +2504,9 @@ public:
+
+ HighlightAnnotationPrivate::HighlightAnnotationPrivate() : AnnotationPrivate(), highlightType(HighlightAnnotation::Highlight) { }
+
+-Annotation *HighlightAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> HighlightAnnotationPrivate::makeAlias()
+ {
+-    return new HighlightAnnotation(*this);
++    return std::unique_ptr<Annotation>(new HighlightAnnotation(*this));
+ }
+
+ Annot::AnnotSubtype HighlightAnnotationPrivate::toAnnotSubType(HighlightAnnotation::HighlightType type)
+@@ -2597,10 +2579,10 @@ AnnotQuadrilaterals *HighlightAnnotationPrivate::toQuadrilaterals(const QList<Hi
+     return new AnnotQuadrilaterals(std::move(ac), count);
+ }
+
+-Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    HighlightAnnotation *q = static_cast<HighlightAnnotation *>(makeAlias());
++    std::unique_ptr<HighlightAnnotation> q = static_pointer_cast<HighlightAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2608,7 +2590,7 @@ Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentD
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotTextMarkup(destPage->getDoc(), &rect, toAnnotSubType(highlightType));
++    pdfAnnot = std::shared_ptr<AnnotTextMarkup>(destPage->getDoc(), &rect, toAnnotSubType(highlightType));
+
+     // Set properties
+     flushBaseAnnotationProperties();
+@@ -2616,8 +2598,6 @@ Annot *HighlightAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentD
+
+     highlightQuads.clear(); // Free up memory
+
+-    delete q;
+-
+     return pdfAnnot;
+ }
+
+@@ -2662,7 +2642,7 @@ void HighlightAnnotation::setHighlightType(HighlightAnnotation::HighlightType ty
+         return;
+     }
+
+-    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     hlann->setType(HighlightAnnotationPrivate::toAnnotSubType(type));
+ }
+
+@@ -2674,7 +2654,7 @@ QList<HighlightAnnotation::Quad> HighlightAnnotation::highlightQuads() const
+         return d->highlightQuads;
+     }
+
+-    const AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    const AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     return d->fromQuadrilaterals(hlann->getQuadrilaterals());
+ }
+
+@@ -2687,7 +2667,7 @@ void HighlightAnnotation::setHighlightQuads(const QList<HighlightAnnotation::Qua
+         return;
+     }
+
+-    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot);
++    AnnotTextMarkup *hlann = static_cast<AnnotTextMarkup *>(d->pdfAnnot.get());
+     AnnotQuadrilaterals *quadrilaterals = d->toQuadrilaterals(quads);
+     hlann->setQuadrilaterals(quadrilaterals);
+     delete quadrilaterals;
+@@ -2698,10 +2678,10 @@ class StampAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     StampAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+-    AnnotStampImageHelper *convertQImageToAnnotStampImageHelper(const QImage &qimg);
++    std::unique_ptr<AnnotStampImageHelper> convertQImageToAnnotStampImageHelper(const QImage &qimg);
+
+     // data fields
+     QString stampIconName;
+@@ -2710,14 +2690,14 @@ public:
+
+ StampAnnotationPrivate::StampAnnotationPrivate() : AnnotationPrivate(), stampIconName(QStringLiteral("Draft")) { }
+
+-Annotation *StampAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> StampAnnotationPrivate::makeAlias()
+ {
+-    return new StampAnnotation(*this);
++    return std::unique_ptr<Annotation>(new StampAnnotation(*this));
+ }
+
+-Annot *StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+-    StampAnnotation *q = static_cast<StampAnnotation *>(makeAlias());
++    std::unique_ptr<StampAnnotation> q = static_pointer_cast<StampAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2725,21 +2705,19 @@ Annot *StampAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotStamp(destPage->getDoc(), &rect);
++    pdfAnnot = std::make_shared<AnnotStamp>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setStampIconName(stampIconName);
+     q->setStampCustomImage(stampCustomImage);
+
+-    delete q;
+-
+     stampIconName.clear(); // Free up memory
+
+     return pdfAnnot;
+ }
+
+-AnnotStampImageHelper *StampAnnotationPrivate::convertQImageToAnnotStampImageHelper(const QImage &qimg)
++std::unique_ptr<AnnotStampImageHelper> StampAnnotationPrivate::convertQImageToAnnotStampImageHelper(const QImage &qimg)
+ {
+     QImage convertedQImage = qimg;
+
+@@ -2818,13 +2796,13 @@ AnnotStampImageHelper *StampAnnotationPrivate::convertQImageToAnnotStampImageHel
+
+     getRawDataFromQImage(convertedQImage, convertedQImage.depth(), &data, &sMaskData);
+
+-    AnnotStampImageHelper *annotImg;
++    std::unique_ptr<AnnotStampImageHelper> annotImg;
+
+     if (sMaskData.count() > 0) {
+         AnnotStampImageHelper sMask(parentDoc->doc, width, height, ColorSpace::DeviceGray, 8, sMaskData.data(), sMaskData.count());
+-        annotImg = new AnnotStampImageHelper(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count(), sMask.getRef());
++        annotImg = std::unique_ptr<AnnotStampImageHelper>(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count(), sMask.getRef());
+     } else {
+-        annotImg = new AnnotStampImageHelper(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count());
++        annotImg = std::unique_ptr<AnnotStampImageHelper>(parentDoc->doc, width, height, colorSpace, bitsPerComponent, data.data(), data.count());
+     }
+
+     return annotImg;
+@@ -2849,7 +2827,7 @@ QString StampAnnotation::stampIconName() const
+         return d->stampIconName;
+     }
+
+-    const AnnotStamp *stampann = static_cast<const AnnotStamp *>(d->pdfAnnot);
++    const AnnotStamp *stampann = static_cast<const AnnotStamp *>(d->pdfAnnot.get());
+     return QString::fromLatin1(stampann->getIcon()->c_str());
+ }
+
+@@ -2862,7 +2840,7 @@ void StampAnnotation::setStampIconName(const QString &name)
+         return;
+     }
+
+-    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot);
++    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot.get());
+     QByteArray encoded = name.toLatin1();
+     GooString s(encoded.constData());
+     stampann->setIcon(&s);
+@@ -2881,9 +2859,9 @@ void StampAnnotation::setStampCustomImage(const QImage &image)
+         return;
+     }
+
+-    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot);
+-    AnnotStampImageHelper *annotCustomImage = d->convertQImageToAnnotStampImageHelper(image);
+-    stampann->setCustomImage(annotCustomImage);
++    AnnotStamp *stampann = static_cast<AnnotStamp *>(d->pdfAnnot.get());
++    std::unique_ptr<AnnotStampImageHelper> annotCustomImage = d->convertQImageToAnnotStampImageHelper(image);
++    stampann->setCustomImage(std::move(annotCustomImage));
+ }
+
+ /** InkAnnotation [Annotation] */
+@@ -2891,8 +2869,8 @@ class InkAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     InkAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QList<QVector<QPointF>> inkPaths;
+@@ -2903,9 +2881,9 @@ public:
+
+ InkAnnotationPrivate::InkAnnotationPrivate() : AnnotationPrivate() { }
+
+-Annotation *InkAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> InkAnnotationPrivate::makeAlias()
+ {
+-    return new InkAnnotation(*this);
++    return std::unique_ptr<Annotation>(new InkAnnotation(*this));
+ }
+
+ // Note: Caller is required to delete array elements and the array itself after use
+@@ -2919,10 +2897,10 @@ AnnotPath **InkAnnotationPrivate::toAnnotPaths(const QList<QVector<QPointF>> &pa
+     return res;
+ }
+
+-Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    InkAnnotation *q = static_cast<InkAnnotation *>(makeAlias());
++    std::unique_ptr<InkAnnotation> q = static_pointer_cast<InkAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -2930,7 +2908,7 @@ Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *d
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotInk(destPage->getDoc(), &rect);
++    pdfAnnot = std::make_shared<AnnotInk>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+@@ -2938,8 +2916,6 @@ Annot *InkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *d
+
+     inkPaths.clear(); // Free up memory
+
+-    delete q;
+-
+     return pdfAnnot;
+ }
+
+@@ -2962,7 +2938,7 @@ QList<QVector<QPointF>> InkAnnotation::inkPaths() const
+         return d->inkPaths;
+     }
+
+-    const AnnotInk *inkann = static_cast<const AnnotInk *>(d->pdfAnnot);
++    const AnnotInk *inkann = static_cast<const AnnotInk *>(d->pdfAnnot.get());
+
+     const AnnotPath *const *paths = inkann->getInkList();
+     if (!paths || !inkann->getInkListLength()) {
+@@ -3000,7 +2976,7 @@ void InkAnnotation::setInkPaths(const QList<QVector<QPointF>> &paths)
+         return;
+     }
+
+-    AnnotInk *inkann = static_cast<AnnotInk *>(d->pdfAnnot);
++    AnnotInk *inkann = static_cast<AnnotInk *>(d->pdfAnnot.get());
+     AnnotPath **annotpaths = d->toAnnotPaths(paths);
+     const int pathsNumber = paths.size();
+     inkann->setInkList(annotpaths, pathsNumber);
+@@ -3017,8 +2993,8 @@ class LinkAnnotationPrivate : public AnnotationPrivate
+ public:
+     LinkAnnotationPrivate();
+     ~LinkAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     std::unique_ptr<Link> linkDestination;
+@@ -3030,12 +3006,12 @@ LinkAnnotationPrivate::LinkAnnotationPrivate() : AnnotationPrivate(), linkHLMode
+
+ LinkAnnotationPrivate::~LinkAnnotationPrivate() { }
+
+-Annotation *LinkAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> LinkAnnotationPrivate::makeAlias()
+ {
+-    return new LinkAnnotation(*this);
++    return std::unique_ptr<Annotation>(new LinkAnnotation(*this));
+ }
+
+-Annot *LinkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> LinkAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3100,8 +3076,8 @@ class CaretAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+     CaretAnnotationPrivate();
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     CaretAnnotation::CaretSymbol symbol;
+@@ -3109,15 +3085,15 @@ public:
+
+ CaretAnnotationPrivate::CaretAnnotationPrivate() : AnnotationPrivate(), symbol(CaretAnnotation::None) { }
+
+-Annotation *CaretAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> CaretAnnotationPrivate::makeAlias()
+ {
+-    return new CaretAnnotation(*this);
++    return std::unique_ptr<Annotation>(new CaretAnnotation(*this));
+ }
+
+-Annot *CaretAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> CaetAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     // Setters are defined in the public class
+-    CaretAnnotation *q = static_cast<CaretAnnotation *>(makeAlias());
++    std::unique_ptr<CaretAnnotation> q = static_pointer_cast<CaretAnnotation *>(makeAlias());
+
+     // Set page and document
+     pdfPage = destPage;
+@@ -3125,13 +3101,12 @@ Annot *CaretAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData
+
+     // Set pdfAnnot
+     PDFRectangle rect = boundaryToPdfRectangle(boundary, flags);
+-    pdfAnnot = new AnnotCaret(destPage->getDoc(), &rect);
++    pdfAnnot = std::shared_ptr<AnnotCaret>(destPage->getDoc(), &rect);
+
+     // Set properties
+     flushBaseAnnotationProperties();
+     q->setCaretSymbol(symbol);
+
+-    delete q;
+     return pdfAnnot;
+ }
+
+@@ -3154,7 +3129,7 @@ CaretAnnotation::CaretSymbol CaretAnnotation::caretSymbol() const
+         return d->symbol;
+     }
+
+-    const AnnotCaret *caretann = static_cast<const AnnotCaret *>(d->pdfAnnot);
++    const AnnotCaret *caretann = static_cast<const AnnotCaret *>(d->pdfAnnot.get());
+     return (CaretAnnotation::CaretSymbol)caretann->getSymbol();
+ }
+
+@@ -3167,7 +3142,7 @@ void CaretAnnotation::setCaretSymbol(CaretAnnotation::CaretSymbol symbol)
+         return;
+     }
+
+-    AnnotCaret *caretann = static_cast<AnnotCaret *>(d->pdfAnnot);
++    AnnotCaret *caretann = static_cast<AnnotCaret *>(d->pdfAnnot.get());
+     caretann->setSymbol((AnnotCaret::AnnotCaretSymbol)symbol);
+ }
+
+@@ -3177,8 +3152,8 @@ class FileAttachmentAnnotationPrivate : public AnnotationPrivate
+ public:
+     FileAttachmentAnnotationPrivate();
+     ~FileAttachmentAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QString icon;
+@@ -3192,12 +3167,12 @@ FileAttachmentAnnotationPrivate::~FileAttachmentAnnotationPrivate()
+     delete embfile;
+ }
+
+-Annotation *FileAttachmentAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> FileAttachmentAnnotationPrivate::makeAlias()
+ {
+-    return new FileAttachmentAnnotation(*this);
++    return std::unique_ptr<Annotation>(new FileAttachmentAnnotation(*this));
+ }
+
+-Annot *FileAttachmentAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> FileAttachmentAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3243,8 +3218,8 @@ class SoundAnnotationPrivate : public AnnotationPrivate
+ public:
+     SoundAnnotationPrivate();
+     ~SoundAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     QString icon;
+@@ -3258,12 +3233,12 @@ SoundAnnotationPrivate::~SoundAnnotationPrivate()
+     delete sound;
+ }
+
+-Annotation *SoundAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> SoundAnnotationPrivate::makeAlias()
+ {
+-    return new SoundAnnotation(*this);
++    return std::unique_ptr<Annotation>(new SoundAnnotation(*this));
+ }
+
+-Annot *SoundAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> SoundAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3309,8 +3284,8 @@ class MovieAnnotationPrivate : public AnnotationPrivate
+ public:
+     MovieAnnotationPrivate();
+     ~MovieAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     MovieObject *movie;
+@@ -3324,12 +3299,12 @@ MovieAnnotationPrivate::~MovieAnnotationPrivate()
+     delete movie;
+ }
+
+-Annotation *MovieAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> MovieAnnotationPrivate::makeAlias()
+ {
+-    return new MovieAnnotation(*this);
++    return std::unique_ptr<Annotation>(new MovieAnnotation(*this));
+ }
+
+-Annot *MovieAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> MovieAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3375,8 +3350,8 @@ class ScreenAnnotationPrivate : public AnnotationPrivate
+ public:
+     ScreenAnnotationPrivate();
+     ~ScreenAnnotationPrivate() override;
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+
+     // data fields
+     LinkRendition *action;
+@@ -3392,12 +3367,12 @@ ScreenAnnotationPrivate::~ScreenAnnotationPrivate()
+
+ ScreenAnnotation::ScreenAnnotation(ScreenAnnotationPrivate &dd) : Annotation(dd) { }
+
+-Annotation *ScreenAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> ScreenAnnotationPrivate::makeAlias()
+ {
+-    return new ScreenAnnotation(*this);
++    return std::unique_ptr<Annotation>(new ScreenAnnotation(*this));
+ }
+
+-Annot *ScreenAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> ScreenAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3445,16 +3420,16 @@ std::unique_ptr<Link> ScreenAnnotation::additionalAction(AdditionalActionType ty
+ class WidgetAnnotationPrivate : public AnnotationPrivate
+ {
+ public:
+-    Annotation *makeAlias() override;
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override;
++    std::unique_ptr<Annotation> makeAlias() override;
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override;
+ };
+
+-Annotation *WidgetAnnotationPrivate::makeAlias()
++std::unique_ptr<Annotation> WidgetAnnotationPrivate::makeAlias()
+ {
+-    return new WidgetAnnotation(*this);
++    return std::unique_ptr<Annotation>(new WidgetAnnotation(*this));
+ }
+
+-Annot *WidgetAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
++std::shared_ptr<Annot> WidgetAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc)
+ {
+     return nullptr; // Not implemented
+ }
+@@ -3768,9 +3743,9 @@ public:
+
+     ~RichMediaAnnotationPrivate() override;
+
+-    Annotation *makeAlias() override { return new RichMediaAnnotation(*this); }
++    std::unique_ptr<Annotation> makeAlias() override { return std::unique_ptr<Annotation>(new RichMediaAnnotation(*this)); }
+
+-    Annot *createNativeAnnot(::Page *destPage, DocumentData *doc) override
++    std::shared_ptr<Annot> createNativeAnnot(::Page *destPage, DocumentData *doc) override
+     {
+         Q_UNUSED(destPage);
+         Q_UNUSED(doc);
+diff --git a/qt6/src/poppler-form.cc b/qt6/src/poppler-form.cc
+index 7e963f0..93b80b6 100644
+--- a/qt6/src/poppler-form.cc
++++ b/qt6/src/poppler-form.cc
+@@ -259,7 +259,7 @@ std::unique_ptr<Link> FormField::additionalAction(AdditionalActionType type) con
+
+ std::unique_ptr<Link> FormField::additionalAction(Annotation::AdditionalActionType type) const
+ {
+-    ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
++    ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation().get();
+     if (!w) {
+         return {};
+     }
+@@ -340,7 +340,7 @@ void FormFieldButton::setIcon(const FormFieldIcon &icon)
+
+     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
+     if (fwb->getButtonType() == formButtonPush) {
+-        ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
++        std::shared_ptr<::AnnotWidget> w = m_formData->fm->getWidgetAnnotation();
+         FormFieldIconData *data = FormFieldIconData::getData(icon);
+         if (data->icon != nullptr) {
+             w->setNewAppearance(data->icon->lookup("AP"));
+diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
+index 2056188..cc41b2f 100644
+--- a/utils/HtmlOutputDev.cc
++++ b/utils/HtmlOutputDev.cc
+@@ -1247,8 +1247,8 @@ void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref)
+ void HtmlOutputDev::endPage()
+ {
+     std::unique_ptr<Links> linksList = docPage->getLinks();
+-    for (AnnotLink *link : linksList->getLinks()) {
+-        doProcessLink(link);
++    for (const std::shared_ptr<AnnotLink> &link : linksList->getLinks()) {
++        doProcessLink(link.get());
+     }
+
+     pages->conv();
+diff --git a/utils/pdfdetach.cc b/utils/pdfdetach.cc
+index 247c2c1..cbb4f30 100644
+--- a/utils/pdfdetach.cc
++++ b/utils/pdfdetach.cc
+@@ -150,11 +150,11 @@ int main(int argc, char *argv[])
+             break;
+         }
+
+-        for (Annot *annot : annots->getAnnots()) {
++        for (const std::shared_ptr<Annot> &annot : annots->getAnnots()) {
+             if (annot->getType() != Annot::typeFileAttachment) {
+                 continue;
+             }
+-            embeddedFiles.push_back(std::make_unique<FileSpec>(static_cast<AnnotFileAttachment *>(annot)->getFile()));
++            embeddedFiles.push_back(std::make_unique<FileSpec>(static_cast<AnnotFileAttachment *>(annot.get())->getFile()));
+         }
+     }
+
+diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
+index 5f96b41..7b3896e 100644
+--- a/utils/pdfinfo.cc
++++ b/utils/pdfinfo.cc
+@@ -415,7 +415,7 @@ static void printUrlList(PDFDoc *doc)
+         Page *page = doc->getPage(pg);
+         if (page) {
+             std::unique_ptr<Links> links = page->getLinks();
+-            for (AnnotLink *annot : links->getLinks()) {
++            for (const std::shared_ptr<AnnotLink> &annot : links->getLinks()) {
+                 LinkAction *action = annot->getAction();
+                 if (action->getKind() == actionURI) {
+                     LinkURI *linkUri = dynamic_cast<LinkURI *>(action);
+--
+2.40.0
diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0004.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0004.patch
new file mode 100644
index 0000000000..680d3004be
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2025-52886-0004.patch
@@ -0,0 +1,58 @@ 
+From ac36affcc8486de38e8905a8d6547a3464ff46e5 Mon Sep 17 00:00:00 2001
+From: Sune Vuorela <sune@vuorela.dk>
+Date: Tue, 3 Jun 2025 00:35:19 +0200
+Subject: [PATCH] Limit ammount of annots per document/page
+
+CVE: CVE-2025-52886
+Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/ac36affcc8486de38e8905a8d6547a3464ff46e5]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ poppler/Annot.cc |  4 ++++
+ poppler/Page.cc  | 16 ++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/poppler/Annot.cc b/poppler/Annot.cc
+index 19ec824..9b5145c 100644
+--- a/poppler/Annot.cc
++++ b/poppler/Annot.cc
+@@ -7253,6 +7253,10 @@ Annots::Annots(PDFDoc *docA, int page, Object *annotsObj)
+                 const Object &obj2 = annotsObj->arrayGetNF(i);
+                 std::shared_ptr<Annot> annot = createAnnot(std::move(obj1), &obj2);
+                 if (annot) {
++                    if (annot.use_count() > 100000) {
++                        error(errSyntaxError, -1, "Annotations likely malformed. Too many references. Stopping processing annots on page {0:d}", page);
++                        break;
++                    }
+                     if (annot->isOk()) {
+                         annot->setPage(page, false); // Don't change /P
+                         appendAnnot(annot);
+diff --git a/poppler/Page.cc b/poppler/Page.cc
+index b27c90d..8b5da2f 100644
+--- a/poppler/Page.cc
++++ b/poppler/Page.cc
+@@ -289,6 +289,22 @@ Page::Page(PDFDoc *docA, int numA, Object &&pageDict, Ref pageRefA, PageAttrs *a
+         goto err2;
+     }
+
++    if (annotsObj.isArray() && annotsObj.arrayGetLength() > 10000) {
++        error(errSyntaxError, -1, "Page annotations object (page {0:d}) is likely malformed. Too big: ({1:d})", num, annotsObj.arrayGetLength());
++        goto err2;
++    }
++    if (annotsObj.isRef()) {
++        auto resolvedObj = getAnnotsObject();
++        if (resolvedObj.isArray() && resolvedObj.arrayGetLength() > 10000) {
++            error(errSyntaxError, -1, "Page annotations object (page {0:d}) is likely malformed. Too big: ({1:d})", num, resolvedObj.arrayGetLength());
++            goto err2;
++        }
++        if (!resolvedObj.isArray() && !resolvedObj.isNull()) {
++            error(errSyntaxError, -1, "Page annotations object (page {0:d}) is wrong type ({1:s})", num, resolvedObj.getTypeName());
++            goto err2;
++        }
++    }
++
+     // contents
+     contents = pageObj.dictLookupNF("Contents").copy();
+     if (!(contents.isRef() || contents.isArray() || contents.isNull())) {
+--
+2.40.0
diff --git a/meta-oe/recipes-support/poppler/poppler_22.04.0.bb b/meta-oe/recipes-support/poppler/poppler_22.04.0.bb
index bb6e64d657..87f240616f 100644
--- a/meta-oe/recipes-support/poppler/poppler_22.04.0.bb
+++ b/meta-oe/recipes-support/poppler/poppler_22.04.0.bb
@@ -14,6 +14,10 @@  SRC_URI = "http://poppler.freedesktop.org/${BP}.tar.xz \
            file://CVE-2025-32364.patch \
            file://CVE-2025-32365.patch \
            file://CVE-2025-43903.patch \
+           file://CVE-2025-52886-0001.patch \
+           file://CVE-2025-52886-0002.patch \
+           file://CVE-2025-52886-0003.patch \
+           file://CVE-2025-52886-0004.patch \
            "
 SRC_URI[sha256sum] = "813fb4b90e7bda63df53205c548602bae728887a60f4048aae4dbd9b1927deff"