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
