From 0554731052d1a97745cb179ab0d45620589dd9c4 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Fri, 7 Jun 2024 00:54:55 +0200
Subject: [PATCH] pdfinfo: Fix crash in broken documents when using -dests

Reference:https://gitlab.freedesktop.org/poppler/poppler/-/commit/0554731052d1a97745cb179ab0d45620589dd9c4
Conflict:add StdTextStringToUCS4() to avoid header interface change;remove unnecessary changes in version 0.90.0
---
 utils/pdfinfo.cc | 62 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
index 2b5eb02..009298e 100644
--- a/utils/pdfinfo.cc
+++ b/utils/pdfinfo.cc
@@ -59,6 +59,7 @@
 #include "Page.h"
 #include "PDFDoc.h"
 #include "PDFDocFactory.h"
+#include "PDFDocEncoding.h"
 #include "CharTypes.h"
 #include "UnicodeMap.h"
 #include "UTF.h"
@@ -297,12 +298,6 @@ static void printStruct(const StructElement *element, unsigned indent) {
   }
 }
 
-struct GooStringCompare {
-  bool operator() (GooString* lhs, GooString* rhs) const {
-    return lhs->cmp(const_cast<GooString*>(rhs)) < 0;
-  }
-};
-
 static void printLinkDest(const std::unique_ptr<LinkDest>& dest) {
   GooString s;
 
@@ -374,30 +369,62 @@ static void printLinkDest(const std::unique_ptr<LinkDest>& dest) {
   printf("%s", s.c_str());
 }
 
+static int StdTextStringToUCS4(const std::string &textStr, Unicode **ucs4)
+{
+  int i, len;
+  const char *s;
+  Unicode *u;
+
+  len = textStr.size();
+  s = textStr.c_str();
+  if (len == 0) {
+    *ucs4 = nullptr;
+    return 0;
+  }
+
+  if (GooString::hasUnicodeMarker(textStr)) {
+    Unicode *utf16;
+    len = len/2 - 1;
+    if (len > 0) {
+      utf16 = new Unicode[len];
+      for (i = 0 ; i < len; i++) {
+        utf16[i] = (s[2 + i*2] & 0xff) << 8 | (s[3 + i*2] & 0xff);
+      }
+      len = UTF16toUCS4(utf16, len, &u);
+      delete[] utf16;
+    } else {
+      u = nullptr;
+    }
+  } else {
+    u = (Unicode*)gmallocn(len, sizeof(Unicode));
+    for (i = 0 ; i < len; i++) {
+      u[i] = pdfDocEncoding[s[i] & 0xff];
+    }
+  }
+  *ucs4 = u;
+  return len;
+}
+
 static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap) {
-  std::map<Ref,std::map<GooString*,std::unique_ptr<LinkDest>,GooStringCompare> > map;
+  std::map<Ref, std::map<std::string, std::unique_ptr<LinkDest>>> map;
 
   int numDests = doc->getCatalog()->numDestNameTree();
   for (int i = 0; i < numDests; i++) {
-    GooString *name = new GooString(doc->getCatalog()->getDestNameTreeName(i));
+    const GooString *name = doc->getCatalog()->getDestNameTreeName(i);
     std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestNameTreeDest(i);
-    if (dest && dest->isPageRef()) {
+    if (name && dest && dest->isPageRef()) {
       Ref pageRef = dest->getPageRef();
-      map[pageRef].insert(std::make_pair(name, std::move(dest)));
-    } else {
-      delete name;
+      map[pageRef].insert(std::make_pair(name->toStr(), std::move(dest)));
     }
   }
 
   numDests = doc->getCatalog()->numDests();
   for (int i = 0; i < numDests; i++) {
-    GooString *name = new GooString(doc->getCatalog()->getDestsName(i));
+    const char *name = doc->getCatalog()->getDestsName(i);
     std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestsDest(i);
-    if (dest && dest->isPageRef()) {
+    if (name && dest && dest->isPageRef()) {
       Ref pageRef = dest->getPageRef();
       map[pageRef].insert(std::make_pair(name, std::move(dest)));
-    } else {
-      delete name;
     }
   }
 
@@ -413,14 +440,13 @@ static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap) {
 	  printf(" \"");
 	  Unicode *u;
 	  char buf[8];
-	  const int len = TextStringToUCS4(it.first, &u);
+	  const int len = StdTextStringToUCS4(it.first, &u);
 	  for (int j = 0; j < len; j++) {
 	    const int n = uMap->mapUnicode(u[j], buf, sizeof(buf));
 	    fwrite(buf, 1, n, stdout);
 	  }
 	  gfree(u);
 	  printf("\"\n");
-	  delete it.first;
 	}
       }
     }
-- 
GitLab

