From 0554731052d1a97745cb179ab0d45620589dd9c4 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid 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(rhs)) < 0; - } -}; - static void printLinkDest(const std::unique_ptr& dest) { GooString s; @@ -374,30 +369,62 @@ static void printLinkDest(const std::unique_ptr& 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,GooStringCompare> > map; + std::map>> 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 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 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