summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYogita Urade <yogita.urade@windriver.com>2025-01-09 12:25:26 +0000
committerArmin Kuster <akuster808@gmail.com>2025-01-22 19:16:45 -0500
commite9e496dc64ed0abf602ea103ee10e6d3ffd918b9 (patch)
tree65019c949efb0c760184013f608f27bb6803827a
parent9d2f35c8ce8c65434f8c91c3bec927f38334b76c (diff)
downloadmeta-openembedded-e9e496dc64ed0abf602ea103ee10e6d3ffd918b9.tar.gz
poppler: fix CVE-2024-6239
A flaw was found in the Poppler's Pdfinfo utility. This issue occurs when using -dests parameter with pdfinfo utility. By using certain malformed input files, an attacker could cause the utility to crash, leading to a denial of service. CVE-2024-6239-0001 is the dependent commit and CVE-2024-6239-0002 is the actual CVE fix. fix indent issue in poppler_22.04.0.bb file. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-6239 Upstream patches: https://gitlab.freedesktop.org/poppler/poppler/-/commit/0554731052d1a97745cb179ab0d45620589dd9c4 https://gitlab.freedesktop.org/poppler/poppler/-/commit/fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc Signed-off-by: Yogita Urade <yogita.urade@windriver.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch1255
-rw-r--r--meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch112
-rw-r--r--meta-oe/recipes-support/poppler/poppler_22.04.0.bb4
3 files changed, 1370 insertions, 1 deletions
diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch
new file mode 100644
index 0000000000..0f0ec1b2c0
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch
@@ -0,0 +1,1255 @@
1From fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc Mon Sep 17 00:00:00 2001
2From: Sune Vuorela <sune@vuorela.dk>
3Date: Thu, 1 Feb 2024 19:11:03 +0000
4Subject: [PATCH] More unicode vectors; fewer raw pointers
5
6Conflicts:-qt5/tests/check_utf8document.cpp and qt6/tests/check_utf8document.cpp
7 files are not presented in this code version. We ignore them.
8 -In file utils/pdfsig.cc TextStringToUTF8 API don't exist
9 in this code version. We ignore them.
10
11CVE: CVE-2024-6239
12Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc]
13
14Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
15---
16 cpp/poppler-toc.cpp | 5 +-
17 glib/poppler-document.cc | 3 +-
18 poppler/CharCodeToUnicode.cc | 113 +++++++++------------------
19 poppler/CharCodeToUnicode.h | 12 ++-
20 poppler/DateInfo.cc | 10 +--
21 poppler/JSInfo.cc | 9 +--
22 poppler/Outline.cc | 12 +--
23 poppler/Outline.h | 7 +-
24 poppler/TextOutputDev.cc | 8 +-
25 poppler/UTF.cc | 78 ++++++++----------
26 poppler/UTF.h | 11 ++-
27 qt5/src/poppler-outline.cc | 2 +-
28 qt5/src/poppler-private.cc | 13 ++-
29 qt5/src/poppler-private.h | 1 +
30 qt5/tests/check_internal_outline.cpp | 6 +-
31 qt5/tests/check_utf_conversion.cpp | 24 +++---
32 qt6/src/poppler-outline.cc | 2 +-
33 qt6/src/poppler-private.cc | 5 ++
34 qt6/src/poppler-private.h | 1 +
35 qt6/tests/check_internal_outline.cpp | 6 +-
36 qt6/tests/check_utf_conversion.cpp | 24 +++---
37 utils/HtmlFonts.cc | 4 +-
38 utils/HtmlFonts.h | 2 +-
39 utils/HtmlOutputDev.cc | 38 ++++-----
40 utils/HtmlOutputDev.h | 2 +-
41 utils/pdfinfo.cc | 8 +-
42 utils/pdftohtml.cc | 25 +++---
43 27 files changed, 180 insertions(+), 251 deletions(-)
44
45diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
46index c79abde..ed3a983 100644
47--- a/cpp/poppler-toc.cpp
48+++ b/cpp/poppler-toc.cpp
49@@ -61,9 +61,8 @@ toc_item_private::~toc_item_private()
50
51 void toc_item_private::load(const OutlineItem *item)
52 {
53- const Unicode *title_unicode = item->getTitle();
54- const int title_length = item->getTitleLength();
55- title = detail::unicode_to_ustring(title_unicode, title_length);
56+ const std::vector<Unicode> &title_unicode = item->getTitle();
57+ title = detail::unicode_to_ustring(title_unicode.data(), title_unicode.size());
58 is_open = item->isOpen();
59 }
60
61diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
62index 7796f5a..be8cea1 100644
63--- a/glib/poppler-document.cc
64+++ b/glib/poppler-document.cc
65@@ -2773,7 +2773,8 @@ PopplerAction *poppler_index_iter_get_action(PopplerIndexIter *iter)
66 item = (*iter->items)[iter->index];
67 link_action = item->getAction();
68
69- title = unicode_to_char(item->getTitle(), item->getTitleLength());
70+ const std::vector<Unicode> &itemTitle = item->getTitle();
71+ title = unicode_to_char(itemTitle.data(), itemTitle.size());
72
73 action = _poppler_action_new(iter->document, link_action, title);
74 g_free(title);
75diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc
76index cd00937..d9ef019 100644
77--- a/poppler/CharCodeToUnicode.cc
78+++ b/poppler/CharCodeToUnicode.cc
79@@ -38,6 +38,7 @@
80
81 #include <cstdio>
82 #include <cstring>
83+#include <functional>
84 #include "goo/glibc.h"
85 #include "goo/gmem.h"
86 #include "goo/gfile.h"
87@@ -51,13 +52,6 @@
88
89 //------------------------------------------------------------------------
90
91-struct CharCodeToUnicodeString
92-{
93- CharCode c;
94- Unicode *u;
95- int len;
96-};
97-
98 //------------------------------------------------------------------------
99
100 static int getCharFromString(void *data)
101@@ -162,7 +156,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(const char *fileName, co
102 }
103 fclose(f);
104
105- ctu = new CharCodeToUnicode(collection->toStr(), mapA, mapLenA, true, nullptr, 0, 0);
106+ ctu = new CharCodeToUnicode(collection->toStr(), mapA, mapLenA, true, {});
107 gfree(mapA);
108 return ctu;
109 }
110@@ -171,8 +165,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil
111 {
112 FILE *f;
113 Unicode *mapA;
114- CharCodeToUnicodeString *sMapA;
115- CharCode size, oldSize, len, sMapSizeA, sMapLenA;
116+ CharCode size, oldSize, len;
117 char buf[256];
118 char *tok;
119 Unicode u0;
120@@ -192,8 +185,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil
121 mapA = (Unicode *)gmallocn(size, sizeof(Unicode));
122 memset(mapA, 0, size * sizeof(Unicode));
123 len = 0;
124- sMapA = nullptr;
125- sMapSizeA = sMapLenA = 0;
126+ std::vector<CharCodeToUnicodeString> sMapA;
127
128 line = 0;
129 while (getLine(buf, sizeof(buf), f)) {
130@@ -230,17 +222,12 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil
131 mapA[u0] = uBuf[0];
132 } else {
133 mapA[u0] = 0;
134- if (sMapLenA == sMapSizeA) {
135- sMapSizeA += 16;
136- sMapA = (CharCodeToUnicodeString *)greallocn(sMapA, sMapSizeA, sizeof(CharCodeToUnicodeString));
137- }
138- sMapA[sMapLenA].c = u0;
139- sMapA[sMapLenA].u = (Unicode *)gmallocn(n, sizeof(Unicode));
140+ std::vector<Unicode> u;
141+ u.reserve(n);
142 for (i = 0; i < n; ++i) {
143- sMapA[sMapLenA].u[i] = uBuf[i];
144+ u.push_back(uBuf[i]);
145 }
146- sMapA[sMapLenA].len = n;
147- ++sMapLenA;
148+ sMapA.push_back({ u0, std::move(u) });
149 }
150 if (u0 >= len) {
151 len = u0 + 1;
152@@ -248,7 +235,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil
153 }
154 fclose(f);
155
156- ctu = new CharCodeToUnicode(fileName->toStr(), mapA, len, true, sMapA, sMapLenA, sMapSizeA);
157+ ctu = new CharCodeToUnicode(fileName->toStr(), mapA, len, true, std::move(sMapA));
158 gfree(mapA);
159 gfree(uBuf);
160 return ctu;
161@@ -256,7 +243,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil
162
163 CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode)
164 {
165- return new CharCodeToUnicode({}, toUnicode, 256, true, nullptr, 0, 0);
166+ return new CharCodeToUnicode({}, toUnicode, 256, true, {});
167 }
168
169 CharCodeToUnicode *CharCodeToUnicode::parseCMap(const GooString *buf, int nBits)
170@@ -512,25 +499,18 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, int offset)
171 map[code] = 0xfffd;
172 }
173 } else {
174- if (sMapLen >= sMapSize) {
175- sMapSize = sMapSize + 16;
176- sMap = (CharCodeToUnicodeString *)greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
177- }
178 map[code] = 0;
179- sMap[sMapLen].c = code;
180 int utf16Len = n / 4;
181- Unicode *utf16 = (Unicode *)gmallocn(utf16Len, sizeof(Unicode));
182+ std::vector<Unicode> utf16(utf16Len);
183+ utf16.resize(utf16Len);
184 for (j = 0; j < utf16Len; ++j) {
185 if (!parseHex(uStr + j * 4, 4, &utf16[j])) {
186- gfree(utf16);
187 error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap");
188 return;
189 }
190 }
191 utf16[utf16Len - 1] += offset;
192- sMap[sMapLen].len = UTF16toUCS4(utf16, utf16Len, &sMap[sMapLen].u);
193- gfree(utf16);
194- ++sMapLen;
195+ sMap.push_back({ code, UTF16toUCS4(utf16.data(), utf16.size()) });
196 }
197 }
198
199@@ -561,8 +541,6 @@ CharCodeToUnicode::CharCodeToUnicode()
200 {
201 map = nullptr;
202 mapLen = 0;
203- sMap = nullptr;
204- sMapLen = sMapSize = 0;
205 refCnt = 1;
206 isIdentity = false;
207 }
208@@ -576,13 +554,11 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional<std::string> &tagA) : t
209 for (i = 0; i < mapLen; ++i) {
210 map[i] = 0;
211 }
212- sMap = nullptr;
213- sMapLen = sMapSize = 0;
214 refCnt = 1;
215 isIdentity = false;
216 }
217
218-CharCodeToUnicode::CharCodeToUnicode(const std::optional<std::string> &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, CharCodeToUnicodeString *sMapA, int sMapLenA, int sMapSizeA) : tag(tagA)
219+CharCodeToUnicode::CharCodeToUnicode(const std::optional<std::string> &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, std::vector<CharCodeToUnicodeString> &&sMapA) : tag(tagA)
220 {
221 mapLen = mapLenA;
222 if (copyMap) {
223@@ -591,9 +567,7 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional<std::string> &tagA, Uni
224 } else {
225 map = mapA;
226 }
227- sMap = sMapA;
228- sMapLen = sMapLenA;
229- sMapSize = sMapSizeA;
230+ sMap = std::move(sMapA);
231 refCnt = 1;
232 isIdentity = false;
233 }
234@@ -601,12 +575,6 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional<std::string> &tagA, Uni
235 CharCodeToUnicode::~CharCodeToUnicode()
236 {
237 gfree(map);
238- if (sMap) {
239- for (int i = 0; i < sMapLen; ++i) {
240- gfree(sMap[i].u);
241- }
242- gfree(sMap);
243- }
244 }
245
246 void CharCodeToUnicode::incRefCnt()
247@@ -628,7 +596,8 @@ bool CharCodeToUnicode::match(const GooString *tagA)
248
249 void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len)
250 {
251- int i, j;
252+ size_t i;
253+ int j;
254
255 if (!map || isIdentity) {
256 return;
257@@ -636,28 +605,26 @@ void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len)
258 if (len == 1) {
259 map[c] = u[0];
260 } else {
261- for (i = 0; i < sMapLen; ++i) {
262+ std::optional<std::reference_wrapper<CharCodeToUnicodeString>> element;
263+ for (i = 0; i < sMap.size(); ++i) {
264 if (sMap[i].c == c) {
265- gfree(sMap[i].u);
266+ sMap[i].u.clear();
267+ element = std::ref(sMap[i]);
268 break;
269 }
270 }
271- if (i == sMapLen) {
272- if (sMapLen == sMapSize) {
273- sMapSize += 8;
274- sMap = (CharCodeToUnicodeString *)greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
275- }
276- ++sMapLen;
277+ if (!element) {
278+ sMap.emplace_back(CharCodeToUnicodeString { c, {} });
279+ element = std::ref(sMap.back());
280 }
281 map[c] = 0;
282- sMap[i].c = c;
283- sMap[i].len = len;
284- sMap[i].u = (Unicode *)gmallocn(len, sizeof(Unicode));
285+ element->get().c = c;
286+ element->get().u.reserve(len);
287 for (j = 0; j < len; ++j) {
288 if (UnicodeIsValid(u[j])) {
289- sMap[i].u[j] = u[j];
290+ element->get().u.push_back(u[j]);
291 } else {
292- sMap[i].u[j] = 0xfffd;
293+ element->get().u.push_back(0xfffd);
294 }
295 }
296 }
297@@ -665,8 +632,6 @@ void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len)
298
299 int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode const **u) const
300 {
301- int i;
302-
303 if (isIdentity) {
304 map[0] = (Unicode)c;
305 *u = map;
306@@ -679,10 +644,10 @@ int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode const **u) const
307 *u = &map[c];
308 return 1;
309 }
310- for (i = sMapLen - 1; i >= 0; --i) { // in reverse so CMap takes precedence
311- if (sMap[i].c == c) {
312- *u = sMap[i].u;
313- return sMap[i].len;
314+ for (auto i = sMap.size(); i > 0; --i) { // in reverse so CMap takes precedence
315+ if (sMap[i - 1].c == c) {
316+ *u = sMap[i - 1].u.data();
317+ return sMap[i - 1].u.size();
318 }
319 }
320 return 0;
321@@ -704,24 +669,24 @@ int CharCodeToUnicode::mapToCharCode(const Unicode *u, CharCode *c, int usize) c
322 }
323 *c = 'x';
324 } else {
325- int i, j;
326+ size_t j;
327 // for each entry in the sMap
328- for (i = 0; i < sMapLen; i++) {
329+ for (const auto &element : sMap) {
330 // if the entry's unicode length isn't the same are usize, the strings
331 // are obviously different
332- if (sMap[i].len != usize) {
333+ if (element.u.size() != size_t(usize)) {
334 continue;
335 }
336 // compare the string char by char
337- for (j = 0; j < sMap[i].len; j++) {
338- if (sMap[i].u[j] != u[j]) {
339+ for (j = 0; j < element.u.size(); j++) {
340+ if (element.u[j] != u[j]) {
341 break;
342 }
343 }
344
345 // we have the same strings
346- if (j == sMap[i].len) {
347- *c = sMap[i].c;
348+ if (j == element.u.size()) {
349+ *c = element.c;
350 return 1;
351 }
352 }
353diff --git a/poppler/CharCodeToUnicode.h b/poppler/CharCodeToUnicode.h
354index 596d44d..9aa2571 100644
355--- a/poppler/CharCodeToUnicode.h
356+++ b/poppler/CharCodeToUnicode.h
357@@ -33,11 +33,11 @@
358
359 #include <atomic>
360 #include <optional>
361+#include <vector>
362
363 #include "poppler-config.h"
364 #include "CharTypes.h"
365
366-struct CharCodeToUnicodeString;
367 class GooString;
368
369 //------------------------------------------------------------------------
370@@ -100,18 +100,22 @@ public:
371 CharCode getLength() const { return mapLen; }
372
373 private:
374+ struct CharCodeToUnicodeString
375+ {
376+ CharCode c;
377+ std::vector<Unicode> u;
378+ };
379 bool parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
380 void addMapping(CharCode code, char *uStr, int n, int offset);
381 void addMappingInt(CharCode code, Unicode u);
382 CharCodeToUnicode();
383 explicit CharCodeToUnicode(const std::optional<std::string> &tagA);
384- CharCodeToUnicode(const std::optional<std::string> &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, CharCodeToUnicodeString *sMapA, int sMapLenA, int sMapSizeA);
385+ CharCodeToUnicode(const std::optional<std::string> &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, std::vector<CharCodeToUnicodeString> &&sMapA);
386
387 const std::optional<std::string> tag;
388 Unicode *map;
389 CharCode mapLen;
390- CharCodeToUnicodeString *sMap;
391- int sMapLen, sMapSize;
392+ std::vector<CharCodeToUnicodeString> sMap;
393 std::atomic_int refCnt;
394 bool isIdentity;
395 };
396diff --git a/poppler/DateInfo.cc b/poppler/DateInfo.cc
397index 36e9804..d62cc78 100644
398--- a/poppler/DateInfo.cc
399+++ b/poppler/DateInfo.cc
400@@ -36,16 +36,14 @@
401 /* See PDF Reference 1.3, Section 3.8.2 for PDF Date representation */
402 bool parseDateString(const GooString *date, int *year, int *month, int *day, int *hour, int *minute, int *second, char *tz, int *tzHour, int *tzMinute)
403 {
404- Unicode *u;
405- int len = TextStringToUCS4(date->toStr(), &u);
406+ std::vector<Unicode> u = TextStringToUCS4(date->toStr());
407 GooString s;
408- for (int i = 0; i < len; i++) {
409+ for (auto &c : u) {
410 // Ignore any non ASCII characters
411- if (u[i] < 128) {
412- s.append(u[i]);
413+ if (c < 128) {
414+ s.append(c);
415 }
416 }
417- gfree(u);
418 const char *dateString = s.c_str();
419
420 if (strlen(dateString) < 2) {
421diff --git a/poppler/JSInfo.cc b/poppler/JSInfo.cc
422index bc6992c..6607085 100644
423--- a/poppler/JSInfo.cc
424+++ b/poppler/JSInfo.cc
425@@ -38,20 +38,17 @@ JSInfo::~JSInfo() { }
426
427 void JSInfo::printJS(const GooString *js)
428 {
429- Unicode *u = nullptr;
430 char buf[8];
431- int i, n, len;
432
433 if (!js || !js->c_str()) {
434 return;
435 }
436
437- len = TextStringToUCS4(js->toStr(), &u);
438- for (i = 0; i < len; i++) {
439- n = uniMap->mapUnicode(u[i], buf, sizeof(buf));
440+ std::vector<Unicode> u = TextStringToUCS4(js->toStr());
441+ for (auto &c : u) {
442+ int n = uniMap->mapUnicode(c, buf, sizeof(buf));
443 fwrite(buf, 1, n, file);
444 }
445- gfree(u);
446 }
447
448 void JSInfo::scanLinkAction(LinkAction *link, const char *action)
449diff --git a/poppler/Outline.cc b/poppler/Outline.cc
450index 4c68be9..086c104 100644
451--- a/poppler/Outline.cc
452+++ b/poppler/Outline.cc
453@@ -407,15 +407,12 @@ OutlineItem::OutlineItem(const Dict *dict, Ref refA, OutlineItem *parentA, XRef
454 parent = parentA;
455 xref = xrefA;
456 doc = docA;
457- title = nullptr;
458 kids = nullptr;
459
460 obj1 = dict->lookup("Title");
461 if (obj1.isString()) {
462 const GooString *s = obj1.getString();
463- titleLen = TextStringToUCS4(s->toStr(), &title);
464- } else {
465- titleLen = 0;
466+ title = TextStringToUCS4(s->toStr());
467 }
468
469 obj1 = dict->lookup("Dest");
470@@ -446,9 +443,6 @@ OutlineItem::~OutlineItem()
471 delete kids;
472 kids = nullptr;
473 }
474- if (title) {
475- gfree(title);
476- }
477 }
478
479 std::vector<OutlineItem *> *OutlineItem::readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA, PDFDoc *docA)
480@@ -494,11 +488,9 @@ void OutlineItem::open()
481
482 void OutlineItem::setTitle(const std::string &titleA)
483 {
484- gfree(title);
485-
486 Object dict = xref->fetch(ref);
487 GooString *g = new GooString(titleA);
488- titleLen = TextStringToUCS4(g->toStr(), &title);
489+ title = TextStringToUCS4(g->toStr());
490 dict.dictSet("Title", Object(g));
491 xref->setModifiedObject(&dict, ref);
492 }
493diff --git a/poppler/Outline.h b/poppler/Outline.h
494index a301604..af431f6 100644
495--- a/poppler/Outline.h
496+++ b/poppler/Outline.h
497@@ -27,6 +27,7 @@
498 #define OUTLINE_H
499
500 #include <memory>
501+#include <vector>
502 #include "Object.h"
503 #include "CharTypes.h"
504 #include "poppler_private_export.h"
505@@ -91,9 +92,8 @@ public:
506 OutlineItem(const OutlineItem &) = delete;
507 OutlineItem &operator=(const OutlineItem &) = delete;
508 static std::vector<OutlineItem *> *readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA, PDFDoc *docA);
509- const Unicode *getTitle() const { return title; }
510+ const std::vector<Unicode> &getTitle() const { return title; }
511 void setTitle(const std::string &titleA);
512- int getTitleLength() const { return titleLen; }
513 bool setPageDest(int i);
514 // OutlineItem keeps the ownership of the action
515 const LinkAction *getAction() const { return action.get(); }
516@@ -112,8 +112,7 @@ private:
517 OutlineItem *parent;
518 PDFDoc *doc;
519 XRef *xref;
520- Unicode *title;
521- int titleLen;
522+ std::vector<Unicode> title;
523 std::unique_ptr<LinkAction> action;
524 bool startsOpen;
525 std::vector<OutlineItem *> *kids; // nullptr if this item is closed or has no kids
526diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
527index 439143c..5d75900 100644
528--- a/poppler/TextOutputDev.cc
529+++ b/poppler/TextOutputDev.cc
530@@ -5661,15 +5661,11 @@ void ActualText::end(const GfxState *state)
531 // extents of all the glyphs inside the span
532
533 if (actualTextNBytes) {
534- Unicode *uni = nullptr;
535- int length;
536-
537 // now that we have the position info for all of the text inside
538 // the marked content span, we feed the "ActualText" back through
539 // text->addChar()
540- length = TextStringToUCS4(actualText->toStr(), &uni);
541- text->addChar(state, actualTextX0, actualTextY0, actualTextX1 - actualTextX0, actualTextY1 - actualTextY0, 0, actualTextNBytes, uni, length);
542- gfree(uni);
543+ std::vector<Unicode> uni = TextStringToUCS4(actualText->toStr());
544+ text->addChar(state, actualTextX0, actualTextY0, actualTextX1 - actualTextX0, actualTextY1 - actualTextY0, 0, actualTextNBytes, uni.data(), uni.size());
545 }
546
547 delete actualText;
548diff --git a/poppler/UTF.cc b/poppler/UTF.cc
549index 9b1bf95..eb542eb 100644
550--- a/poppler/UTF.cc
551+++ b/poppler/UTF.cc
552@@ -42,65 +42,52 @@ bool UnicodeIsValid(Unicode ucs4)
553 return (ucs4 < 0x110000) && ((ucs4 & 0xfffff800) != 0xd800) && (ucs4 < 0xfdd0 || ucs4 > 0xfdef) && ((ucs4 & 0xfffe) != 0xfffe);
554 }
555
556-int UTF16toUCS4(const Unicode *utf16, int utf16Len, Unicode **ucs4_out)
557+std::vector<Unicode> UTF16toUCS4(const Unicode *utf16, int utf16Len)
558 {
559- int i, n, len;
560- Unicode *u;
561-
562 // count characters
563- len = 0;
564- for (i = 0; i < utf16Len; i++) {
565+ int len = 0;
566+ for (int i = 0; i < utf16Len; i++) {
567 if (utf16[i] >= 0xd800 && utf16[i] < 0xdc00 && i + 1 < utf16Len && utf16[i + 1] >= 0xdc00 && utf16[i + 1] < 0xe000) {
568 i++; /* surrogate pair */
569 }
570 len++;
571 }
572- if (ucs4_out == nullptr) {
573- return len;
574- }
575-
576- u = (Unicode *)gmallocn(len, sizeof(Unicode));
577- n = 0;
578+ std::vector<Unicode> u;
579+ u.reserve(len);
580 // convert string
581- for (i = 0; i < utf16Len; i++) {
582+ for (int i = 0; i < utf16Len; i++) {
583 if (utf16[i] >= 0xd800 && utf16[i] < 0xdc00) { /* surrogate pair */
584 if (i + 1 < utf16Len && utf16[i + 1] >= 0xdc00 && utf16[i + 1] < 0xe000) {
585 /* next code is a low surrogate */
586- u[n] = (((utf16[i] & 0x3ff) << 10) | (utf16[i + 1] & 0x3ff)) + 0x10000;
587+ u.push_back((((utf16[i] & 0x3ff) << 10) | (utf16[i + 1] & 0x3ff)) + 0x10000);
588 ++i;
589 } else {
590 /* missing low surrogate
591 replace it with REPLACEMENT CHARACTER (U+FFFD) */
592- u[n] = 0xfffd;
593+ u.push_back(0xfffd);
594 }
595 } else if (utf16[i] >= 0xdc00 && utf16[i] < 0xe000) {
596 /* invalid low surrogate
597 replace it with REPLACEMENT CHARACTER (U+FFFD) */
598- u[n] = 0xfffd;
599+ u.push_back(0xfffd);
600 } else {
601- u[n] = utf16[i];
602+ u.push_back(utf16[i]);
603 }
604- if (!UnicodeIsValid(u[n])) {
605- u[n] = 0xfffd;
606+ if (!UnicodeIsValid(u.back())) {
607+ u.back() = 0xfffd;
608 }
609- n++;
610 }
611- *ucs4_out = u;
612- return len;
613+ return u;
614 }
615
616-int TextStringToUCS4(const std::string &textStr, Unicode **ucs4)
617+std::vector<Unicode> TextStringToUCS4(const std::string &textStr)
618 {
619- int i, len;
620- const char *s;
621- Unicode *u;
622 bool isUnicode, isUnicodeLE;
623
624- len = textStr.size();
625- s = textStr.c_str();
626+ int len = textStr.size();
627+ const std::string &s = textStr;
628 if (len == 0) {
629- *ucs4 = nullptr;
630- return 0;
631+ return {};
632 }
633
634 if (GooString::hasUnicodeMarker(textStr)) {
635@@ -115,30 +102,30 @@ int TextStringToUCS4(const std::string &textStr, Unicode **ucs4)
636 }
637
638 if (isUnicode || isUnicodeLE) {
639- Unicode *utf16;
640 len = len / 2 - 1;
641 if (len > 0) {
642- utf16 = new Unicode[len];
643- for (i = 0; i < len; i++) {
644+ std::vector<Unicode> utf16;
645+ utf16.reserve(len);
646+ for (int i = 0; i < len; i++) {
647 if (isUnicode) {
648- utf16[i] = (s[2 + i * 2] & 0xff) << 8 | (s[3 + i * 2] & 0xff);
649+ utf16.push_back((s[2 + i * 2] & 0xff) << 8 | (s[3 + i * 2] & 0xff));
650 } else { // UnicodeLE
651- utf16[i] = (s[3 + i * 2] & 0xff) << 8 | (s[2 + i * 2] & 0xff);
652+ utf16.push_back((s[3 + i * 2] & 0xff) << 8 | (s[2 + i * 2] & 0xff));
653 }
654 }
655- len = UTF16toUCS4(utf16, len, &u);
656- delete[] utf16;
657+ return UTF16toUCS4(utf16.data(), utf16.size());
658+
659 } else {
660- u = nullptr;
661+ return {};
662 }
663 } else {
664- u = (Unicode *)gmallocn(len, sizeof(Unicode));
665- for (i = 0; i < len; i++) {
666- u[i] = pdfDocEncoding[s[i] & 0xff];
667+ std::vector<Unicode> u;
668+ u.reserve(len);
669+ for (int i = 0; i < len; i++) {
670+ u.push_back(pdfDocEncoding[s[i] & 0xff]);
671 }
672+ return u;
673 }
674- *ucs4 = u;
675- return len;
676 }
677
678 bool UnicodeIsWhitespace(Unicode ucs4)
679@@ -549,7 +536,10 @@ void unicodeToAscii7(const Unicode *in, int len, Unicode **ucs4_out, int *out_le
680 }
681 }
682
683- *out_len = TextStringToUCS4(str, ucs4_out);
684+ std::vector<Unicode> ucs4 = TextStringToUCS4(str);
685+ *out_len = ucs4.size();
686+ *ucs4_out = (Unicode *)gmallocn(ucs4.size(), sizeof(Unicode));
687+ memcpy(*ucs4_out, ucs4.data(), ucs4.size() * sizeof(Unicode));
688
689 if (indices) {
690 idx[k] = in_idx[len];
691diff --git a/poppler/UTF.h b/poppler/UTF.h
692index 626c686..bfc5f65 100644
693--- a/poppler/UTF.h
694+++ b/poppler/UTF.h
695@@ -19,6 +19,7 @@
696 #include <cstdint>
697 #include <climits>
698 #include <memory>
699+#include <vector>
700
701 #include "goo/GooString.h"
702 #include "CharTypes.h"
703@@ -27,16 +28,14 @@
704 // Convert a UTF-16 string to a UCS-4
705 // utf16 - utf16 bytes
706 // utf16_len - number of UTF-16 characters
707-// ucs4_out - if not NULL, allocates and returns UCS-4 string. Free with gfree.
708 // returns number of UCS-4 characters
709-int UTF16toUCS4(const Unicode *utf16, int utf16Len, Unicode **ucs4_out);
710+std::vector<Unicode> UTF16toUCS4(const Unicode *utf16, int utf16Len);
711
712 // Convert a PDF Text String to UCS-4
713 // s - PDF text string
714-// ucs4 - if the number of UCS-4 characters is > 0, allocates and
715-// returns UCS-4 string. Free with gfree.
716-// returns number of UCS-4 characters
717-int POPPLER_PRIVATE_EXPORT TextStringToUCS4(const std::string &textStr, Unicode **ucs4);
718+// returns UCS-4 characters
719+// Convert a PDF text string to UCS-4
720+std::vector<Unicode> POPPLER_PRIVATE_EXPORT TextStringToUCS4(const std::string &textStr);
721
722 // check if UCS-4 character is valid
723 bool UnicodeIsValid(Unicode ucs4);
724diff --git a/qt5/src/poppler-outline.cc b/qt5/src/poppler-outline.cc
725index 5ff7e37..2f6ef2d 100644
726--- a/qt5/src/poppler-outline.cc
727+++ b/qt5/src/poppler-outline.cc
728@@ -78,7 +78,7 @@ QString OutlineItem::name() const
729
730 if (name.isEmpty()) {
731 if (const ::OutlineItem *data = m_data->data) {
732- name = unicodeToQString(data->getTitle(), data->getTitleLength());
733+ name = unicodeToQString(data->getTitle());
734 }
735 }
736
737diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc
738index 228d8e8..54df79f 100644
739--- a/qt5/src/poppler-private.cc
740+++ b/qt5/src/poppler-private.cc
741@@ -94,6 +94,11 @@ QString unicodeToQString(const Unicode *u, int len)
742 return QString::fromUtf8(convertedStr.c_str(), convertedStr.getLength());
743 }
744
745+QString unicodeToQString(const std::vector<Unicode> &u)
746+{
747+ return unicodeToQString(u.data(), u.size());
748+}
749+
750 QString UnicodeParsedString(const GooString *s1)
751 {
752 return (s1) ? UnicodeParsedString(s1->toStr()) : QString();
753@@ -266,13 +271,7 @@ void DocumentData::addTocChildren(QDomDocument *docSyn, QDomNode *parent, const
754 // iterate over every object in 'items'
755
756 // 1. create element using outlineItem's title as tagName
757- QString name;
758- const Unicode *uniChar = outlineItem->getTitle();
759- int titleLength = outlineItem->getTitleLength();
760- name = unicodeToQString(uniChar, titleLength);
761- if (name.isEmpty()) {
762- continue;
763- }
764+ QString name = unicodeToQString(outlineItem->getTitle());
765
766 QDomElement item = docSyn->createElement(name);
767 parent->appendChild(item);
768diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h
769index 39dfb6b..bba5bd7 100644
770--- a/qt5/src/poppler-private.h
771+++ b/qt5/src/poppler-private.h
772@@ -73,6 +73,7 @@ namespace Poppler {
773
774 /* borrowed from kpdf */
775 POPPLER_QT5_EXPORT QString unicodeToQString(const Unicode *u, int len);
776+POPPLER_QT5_EXPORT QString unicodeToQString(const std::vector<Unicode> &u);
777
778 POPPLER_QT5_EXPORT QString UnicodeParsedString(const GooString *s1);
779
780diff --git a/qt5/tests/check_internal_outline.cpp b/qt5/tests/check_internal_outline.cpp
781index c12b604..5db6bf4 100644
782--- a/qt5/tests/check_internal_outline.cpp
783+++ b/qt5/tests/check_internal_outline.cpp
784@@ -56,10 +56,10 @@ void TestInternalOutline::testCreateOutline()
785
786 static std::string getTitle(const OutlineItem *item)
787 {
788- const Unicode *u = item->getTitle();
789+ std::vector<Unicode> u = item->getTitle();
790 std::string s;
791- for (int i = 0; i < item->getTitleLength(); i++) {
792- s.append(1, (char)u[i]);
793+ for (auto &c : u) {
794+ s.append(1, (char)(c));
795 }
796 return s;
797 }
798diff --git a/qt5/tests/check_utf_conversion.cpp b/qt5/tests/check_utf_conversion.cpp
799index 73c684e..b00f080 100644
800--- a/qt5/tests/check_utf_conversion.cpp
801+++ b/qt5/tests/check_utf_conversion.cpp
802@@ -133,16 +133,13 @@ void TestUTFConversion::testUnicodeToAscii7()
803 // malloc() always returns 8-byte aligned memory addresses.
804 GooString *goo = Poppler::QStringToUnicodeGooString(QString::fromUtf8("®©©©©©©©©©©©©©©©©©©©©")); // clazy:exclude=qstring-allocations
805
806- Unicode *in;
807- const int in_len = TextStringToUCS4(goo->toStr(), &in);
808+ const std::vector<Unicode> in = TextStringToUCS4(goo->toStr());
809
810 delete goo;
811
812 int in_norm_len;
813 int *in_norm_idx;
814- Unicode *in_norm = unicodeNormalizeNFKC(in, in_len, &in_norm_len, &in_norm_idx, true);
815-
816- free(in);
817+ Unicode *in_norm = unicodeNormalizeNFKC(in.data(), in.size(), &in_norm_len, &in_norm_idx, true);
818
819 Unicode *out;
820 int out_len;
821@@ -174,25 +171,24 @@ void TestUTFConversion::testUnicodeLittleEndian()
822 // Let's assert both GooString's are different
823 QVERIFY(GooUTF16LE != GooUTF16BE);
824
825- Unicode *UCS4fromLE, *UCS4fromBE;
826- const int len1 = TextStringToUCS4(GooUTF16LE, &UCS4fromLE);
827- const int len2 = TextStringToUCS4(GooUTF16BE, &UCS4fromBE);
828+ const std::vector<Unicode> UCS4fromLE = TextStringToUCS4(GooUTF16LE);
829+ const std::vector<Unicode> UCS4fromBE = TextStringToUCS4(GooUTF16BE);
830
831 // len is 4 because TextStringToUCS4() removes the two leading Byte Order Mark (BOM) code points
832- QCOMPARE(len1, len2);
833- QCOMPARE(len1, 4);
834+ QCOMPARE(UCS4fromLE.size(), UCS4fromBE.size());
835+ QCOMPARE(UCS4fromLE.size(), 4);
836
837 // Check that now after conversion, UCS4fromLE and UCS4fromBE are now the same
838- for (int i = 0; i < len1; i++) {
839+ for (size_t i = 0; i < UCS4fromLE.size(); i++) {
840 QCOMPARE(UCS4fromLE[i], UCS4fromBE[i]);
841 }
842
843 const QString expected = QString::fromUtf8("HI!☑"); // clazy:exclude=qstring-allocations
844
845 // Do some final verifications, checking the strings to be "HI!"
846- QVERIFY(*UCS4fromLE == *UCS4fromBE);
847- QVERIFY(compare(UCS4fromLE, expected.utf16(), len1));
848- QVERIFY(compare(UCS4fromBE, expected.utf16(), len1));
849+ QVERIFY(UCS4fromLE == UCS4fromBE);
850+ QVERIFY(compare(UCS4fromLE.data(), expected.utf16(), UCS4fromLE.size()));
851+ QVERIFY(compare(UCS4fromBE.data(), expected.utf16(), UCS4fromLE.size()));
852 }
853
854 QTEST_GUILESS_MAIN(TestUTFConversion)
855diff --git a/qt6/src/poppler-outline.cc b/qt6/src/poppler-outline.cc
856index f5ba2a9..2bc0d30 100644
857--- a/qt6/src/poppler-outline.cc
858+++ b/qt6/src/poppler-outline.cc
859@@ -78,7 +78,7 @@ QString OutlineItem::name() const
860
861 if (name.isEmpty()) {
862 if (const ::OutlineItem *data = m_data->data) {
863- name = unicodeToQString(data->getTitle(), data->getTitleLength());
864+ name = unicodeToQString(data->getTitle());
865 }
866 }
867
868diff --git a/qt6/src/poppler-private.cc b/qt6/src/poppler-private.cc
869index 91d1725..2cb2396 100644
870--- a/qt6/src/poppler-private.cc
871+++ b/qt6/src/poppler-private.cc
872@@ -94,6 +94,11 @@ QString unicodeToQString(const Unicode *u, int len)
873 return QString::fromUtf8(convertedStr.c_str(), convertedStr.getLength());
874 }
875
876+QString unicodeToQString(const std::vector<Unicode> &u)
877+{
878+ return unicodeToQString(u.data(), u.size());
879+}
880+
881 QString UnicodeParsedString(const GooString *s1)
882 {
883 return (s1) ? UnicodeParsedString(s1->toStr()) : QString();
884diff --git a/qt6/src/poppler-private.h b/qt6/src/poppler-private.h
885index d1f7335..a3117a6 100644
886--- a/qt6/src/poppler-private.h
887+++ b/qt6/src/poppler-private.h
888@@ -72,6 +72,7 @@ namespace Poppler {
889
890 /* borrowed from kpdf */
891 POPPLER_QT6_EXPORT QString unicodeToQString(const Unicode *u, int len);
892+POPPLER_QT6_EXPORT QString unicodeToQString(const std::vector<Unicode> &u);
893
894 POPPLER_QT6_EXPORT QString UnicodeParsedString(const GooString *s1);
895
896diff --git a/qt6/tests/check_internal_outline.cpp b/qt6/tests/check_internal_outline.cpp
897index c12b604..d23e773 100644
898--- a/qt6/tests/check_internal_outline.cpp
899+++ b/qt6/tests/check_internal_outline.cpp
900@@ -56,10 +56,10 @@ void TestInternalOutline::testCreateOutline()
901
902 static std::string getTitle(const OutlineItem *item)
903 {
904- const Unicode *u = item->getTitle();
905+ const std::vector<Unicode> &u = item->getTitle();
906 std::string s;
907- for (int i = 0; i < item->getTitleLength(); i++) {
908- s.append(1, (char)u[i]);
909+ for (const auto &c : u) {
910+ s.append(1, (char)(c));
911 }
912 return s;
913 }
914diff --git a/qt6/tests/check_utf_conversion.cpp b/qt6/tests/check_utf_conversion.cpp
915index 2cac758..e7f35ea 100644
916--- a/qt6/tests/check_utf_conversion.cpp
917+++ b/qt6/tests/check_utf_conversion.cpp
918@@ -131,16 +131,13 @@ void TestUTFConversion::testUnicodeToAscii7()
919 // malloc() always returns 8-byte aligned memory addresses.
920 GooString *goo = Poppler::QStringToUnicodeGooString(QString::fromUtf8("®©©©©©©©©©©©©©©©©©©©©")); // clazy:exclude=qstring-allocations
921
922- Unicode *in;
923- const int in_len = TextStringToUCS4(goo->toStr(), &in);
924+ const std::vector<Unicode> in = TextStringToUCS4(goo->toStr());
925
926 delete goo;
927
928 int in_norm_len;
929 int *in_norm_idx;
930- Unicode *in_norm = unicodeNormalizeNFKC(in, in_len, &in_norm_len, &in_norm_idx, true);
931-
932- free(in);
933+ Unicode *in_norm = unicodeNormalizeNFKC(in.data(), in.size(), &in_norm_len, &in_norm_idx, true);
934
935 Unicode *out;
936 int out_len;
937@@ -172,25 +169,24 @@ void TestUTFConversion::testUnicodeLittleEndian()
938 // Let's assert both GooString's are different
939 QVERIFY(GooUTF16LE != GooUTF16BE);
940
941- Unicode *UCS4fromLE, *UCS4fromBE;
942- const int len1 = TextStringToUCS4(GooUTF16LE, &UCS4fromLE);
943- const int len2 = TextStringToUCS4(GooUTF16BE, &UCS4fromBE);
944+ const std::vector<Unicode> UCS4fromLE = TextStringToUCS4(GooUTF16LE);
945+ const std::vector<Unicode> UCS4fromBE = TextStringToUCS4(GooUTF16BE);
946
947 // len is 4 because TextStringToUCS4() removes the two leading Byte Order Mark (BOM) code points
948- QCOMPARE(len1, len2);
949- QCOMPARE(len1, 4);
950+ QCOMPARE(UCS4fromLE.size(), UCS4fromBE.size());
951+ QCOMPARE(UCS4fromLE.size(), 4);
952
953 // Check that now after conversion, UCS4fromLE and UCS4fromBE are now the same
954- for (int i = 0; i < len1; i++) {
955+ for (size_t i = 0; i < UCS4fromLE.size(); i++) {
956 QCOMPARE(UCS4fromLE[i], UCS4fromBE[i]);
957 }
958
959 const QString expected = QStringLiteral("HI!☑");
960
961 // Do some final verifications, checking the strings to be "HI!"
962- QVERIFY(*UCS4fromLE == *UCS4fromBE);
963- QVERIFY(compare(UCS4fromLE, expected.utf16(), len1));
964- QVERIFY(compare(UCS4fromBE, expected.utf16(), len1));
965+ QVERIFY(UCS4fromLE == UCS4fromBE);
966+ QVERIFY(compare(UCS4fromLE.data(), expected.utf16(), UCS4fromLE.size()));
967+ QVERIFY(compare(UCS4fromBE.data(), expected.utf16(), UCS4fromBE.size()));
968 }
969
970 QTEST_GUILESS_MAIN(TestUTFConversion)
971diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc
972index ca7d4a4..9f25621 100644
973--- a/utils/HtmlFonts.cc
974+++ b/utils/HtmlFonts.cc
975@@ -230,9 +230,9 @@ GooString *HtmlFont::getFullName()
976 }
977
978 // this method if plain wrong todo
979-GooString *HtmlFont::HtmlFilter(const Unicode *u, int uLen)
980+std::unique_ptr<GooString> HtmlFont::HtmlFilter(const Unicode *u, int uLen)
981 {
982- GooString *tmp = new GooString();
983+ auto tmp = std::make_unique<GooString>();
984 const UnicodeMap *uMap;
985 char buf[8];
986 int n;
987diff --git a/utils/HtmlFonts.h b/utils/HtmlFonts.h
988index ca4ae54..74cdca0 100644
989--- a/utils/HtmlFonts.h
990+++ b/utils/HtmlFonts.h
991@@ -104,7 +104,7 @@ public:
992 }
993 const double *getRotMat() const { return rotSkewMat; }
994 GooString *getFontName();
995- static GooString *HtmlFilter(const Unicode *u, int uLen); // char* s);
996+ static std::unique_ptr<GooString> HtmlFilter(const Unicode *u, int uLen); // char* s);
997 bool isEqual(const HtmlFont &x) const;
998 bool isEqualIgnoreBold(const HtmlFont &x) const;
999 void print() const { printf("font: %s (%s) %d %s%s\n", FontName->c_str(), familyName.c_str(), size, bold ? "bold " : "", italic ? "italic " : ""); };
1000diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
1001index 8a16e00..71fe672 100644
1002--- a/utils/HtmlOutputDev.cc
1003+++ b/utils/HtmlOutputDev.cc
1004@@ -127,11 +127,11 @@ static bool debug = false;
1005
1006 #if 0
1007 static GooString* Dirname(GooString* str){
1008-
1009+
1010 char *p=str->c_str();
1011 int len=str->getLength();
1012 for (int i=len-1;i>=0;i--)
1013- if (*(p+i)==SLASH)
1014+ if (*(p+i)==SLASH)
1015 return new GooString(p,i+1);
1016 return new GooString();
1017 }
1018@@ -222,14 +222,13 @@ HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu *_fonts) :
1019 len = size = 0;
1020 yxNext = nullptr;
1021 xyNext = nullptr;
1022- htext = new GooString();
1023+ htext = std::make_unique<GooString>();
1024 dir = textDirUnknown;
1025 }
1026
1027 HtmlString::~HtmlString()
1028 {
1029 gfree(text);
1030- delete htext;
1031 gfree(xRight);
1032 }
1033
1034@@ -340,7 +339,6 @@ void HtmlPage::beginString(GfxState *state, const GooString *s)
1035 void HtmlPage::conv()
1036 {
1037 for (HtmlString *tmp = yxStrings; tmp; tmp = tmp->yxNext) {
1038- delete tmp->htext;
1039 tmp->htext = HtmlFont::HtmlFilter(tmp->text, tmp->len);
1040
1041 int linkIndex = 0;
1042@@ -636,7 +634,7 @@ void HtmlPage::coalesce()
1043 bool finish_a = switch_links && hlink1 != nullptr;
1044 bool finish_italic = hfont1->isItalic() && (!hfont2->isItalic() || finish_a);
1045 bool finish_bold = hfont1->isBold() && (!hfont2->isBold() || finish_a || finish_italic);
1046- CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
1047+ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold);
1048 if (switch_links && hlink2 != nullptr) {
1049 GooString *ls = hlink2->getLinkStart();
1050 str1->htext->append(ls);
1051@@ -649,7 +647,7 @@ void HtmlPage::coalesce()
1052 str1->htext->append("<b>", 3);
1053 }
1054
1055- str1->htext->append(str2->htext);
1056+ str1->htext->append(str2->htext.get());
1057 // str1 now contains href for link of str2 (if it is defined)
1058 str1->link = str2->link;
1059 hfont1 = hfont2;
1060@@ -666,7 +664,7 @@ void HtmlPage::coalesce()
1061 bool finish_a = str1->getLink() != nullptr;
1062 bool finish_bold = hfont1->isBold();
1063 bool finish_italic = hfont1->isItalic();
1064- CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
1065+ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold);
1066
1067 str1->xMin = curX;
1068 str1->yMin = curY;
1069@@ -693,14 +691,14 @@ void HtmlPage::coalesce()
1070 bool finish_bold = hfont1->isBold();
1071 bool finish_italic = hfont1->isItalic();
1072 bool finish_a = str1->getLink() != nullptr;
1073- CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
1074+ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold);
1075
1076 #if 0 //~ for debugging
1077 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
1078 printf("x=%3d..%3d y=%3d..%3d size=%2d ",
1079 (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax,
1080 (int)(str1->yMax - str1->yMin));
1081- printf("'%s'\n", str1->htext->c_str());
1082+ printf("'%s'\n", str1->htext->c_str());
1083 }
1084 printf("\n------------------------------------------------------------\n\n");
1085 #endif
1086@@ -1220,10 +1218,10 @@ void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref)
1087 exit(1);
1088 }
1089 delete fname;
1090- // if(state->getRotation()!=0)
1091+ // if(state->getRotation()!=0)
1092 // fprintf(tin,"ROTATE=%d rotate %d neg %d neg translate\n",state->getRotation(),state->getX1(),-state->getY1());
1093- // else
1094- fprintf(tin,"ROTATE=%d neg %d neg translate\n",state->getX1(),state->getY1());
1095+ // else
1096+ fprintf(tin,"ROTATE=%d neg %d neg translate\n",state->getX1(),state->getY1());
1097 }
1098 }
1099 #endif
1100@@ -1718,10 +1716,11 @@ bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector<OutlineI
1101 fputs("<ul>\n", output);
1102
1103 for (OutlineItem *item : *outlines) {
1104- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength());
1105+ const auto &title = item->getTitle();
1106+ std::unique_ptr<GooString> titleStr = HtmlFont::HtmlFilter(title.data(), title.size());
1107
1108 GooString *linkName = nullptr;
1109- ;
1110+
1111 const int itemPage = getOutlinePageNum(item);
1112 if (itemPage > 0) {
1113 /* complex simple
1114@@ -1748,12 +1747,13 @@ bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector<OutlineI
1115 if (linkName) {
1116 fprintf(output, "<a href=\"%s\">", linkName->c_str());
1117 }
1118- fputs(titleStr->c_str(), output);
1119+ if (titleStr) {
1120+ fputs(titleStr->c_str(), output);
1121+ }
1122 if (linkName) {
1123 fputs("</a>", output);
1124 delete linkName;
1125 }
1126- delete titleStr;
1127 atLeastOne = true;
1128
1129 item->open();
1130@@ -1773,14 +1773,14 @@ void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const std::vector<OutlineIt
1131 fputs("<outline>\n", output);
1132
1133 for (OutlineItem *item : *outlines) {
1134- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength());
1135+ const std::vector<Unicode> &title = item->getTitle();
1136+ auto titleStr = HtmlFont::HtmlFilter(title.data(), title.size());
1137 const int itemPage = getOutlinePageNum(item);
1138 if (itemPage > 0) {
1139 fprintf(output, "<item page=\"%d\">%s</item>\n", itemPage, titleStr->c_str());
1140 } else {
1141 fprintf(output, "<item>%s</item>\n", titleStr->c_str());
1142 }
1143- delete titleStr;
1144
1145 item->open();
1146 if (item->hasKids() && item->getKids()) {
1147diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h
1148index c7b08d1..e490eff 100644
1149--- a/utils/HtmlOutputDev.h
1150+++ b/utils/HtmlOutputDev.h
1151@@ -95,7 +95,7 @@ private:
1152 HtmlString *yxNext; // next string in y-major order
1153 HtmlString *xyNext; // next string in x-major order
1154 int fontpos;
1155- GooString *htext;
1156+ std::unique_ptr<GooString> htext;
1157 int len; // length of text and xRight
1158 int size; // size of text and xRight arrays
1159 UnicodeTextDirection dir; // direction (left to right/right to left)
1160diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
1161index 7a7fc78..a446c3c 100644
1162--- a/utils/pdfinfo.cc
1163+++ b/utils/pdfinfo.cc
1164@@ -114,14 +114,12 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to
1165
1166 static void printTextString(const GooString *s, const UnicodeMap *uMap)
1167 {
1168- Unicode *u;
1169 char buf[8];
1170- int len = TextStringToUCS4(s->toStr(), &u);
1171- for (int i = 0; i < len; i++) {
1172- int n = uMap->mapUnicode(u[i], buf, sizeof(buf));
1173+ std::vector<Unicode> u = TextStringToUCS4(s->toStr());
1174+ for (const auto &c : u) {
1175+ int n = uMap->mapUnicode(c, buf, sizeof(buf));
1176 fwrite(buf, 1, n, stdout);
1177 }
1178- gfree(u);
1179 }
1180
1181 static void printUCS4String(const Unicode *u, int len, const UnicodeMap *uMap)
1182diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc
1183index 97b141a..d7c0889 100644
1184--- a/utils/pdftohtml.cc
1185+++ b/utils/pdftohtml.cc
1186@@ -99,7 +99,7 @@ static char ownerPassword[33] = "";
1187 static char userPassword[33] = "";
1188 static bool printVersion = false;
1189
1190-static GooString *getInfoString(Dict *infoDict, const char *key);
1191+static std::unique_ptr<GooString> getInfoString(Dict *infoDict, const char *key);
1192 static GooString *getInfoDate(Dict *infoDict, const char *key);
1193
1194 static char textEncName[128] = "";
1195@@ -158,8 +158,11 @@ int main(int argc, char *argv[])
1196 {
1197 std::unique_ptr<PDFDoc> doc;
1198 GooString *fileName = nullptr;
1199- GooString *docTitle = nullptr;
1200- GooString *author = nullptr, *keywords = nullptr, *subject = nullptr, *date = nullptr;
1201+ std::unique_ptr<GooString> docTitle;
1202+ std::unique_ptr<GooString> author;
1203+ std::unique_ptr<GooString> keywords;
1204+ std::unique_ptr<GooString> subject;
1205+ GooString *date = nullptr;
1206 GooString *htmlFileName = nullptr;
1207 HtmlOutputDev *htmlOut = nullptr;
1208 SplashOutputDev *splashOut = nullptr;
1209@@ -317,7 +320,7 @@ int main(int argc, char *argv[])
1210 }
1211 }
1212 if (!docTitle) {
1213- docTitle = new GooString(htmlFileName);
1214+ docTitle = std::make_unique<GooString>(htmlFileName);
1215 }
1216
1217 if (!singleHtml) {
1218@@ -330,16 +333,6 @@ int main(int argc, char *argv[])
1219 // write text file
1220 htmlOut = new HtmlOutputDev(doc->getCatalog(), htmlFileName->c_str(), docTitle->c_str(), author ? author->c_str() : nullptr, keywords ? keywords->c_str() : nullptr, subject ? subject->c_str() : nullptr, date ? date->c_str() : nullptr,
1221 rawOrder, firstPage, doOutline);
1222- delete docTitle;
1223- if (author) {
1224- delete author;
1225- }
1226- if (keywords) {
1227- delete keywords;
1228- }
1229- if (subject) {
1230- delete subject;
1231- }
1232 if (date) {
1233 delete date;
1234 }
1235@@ -397,7 +390,7 @@ error:
1236 return exit_status;
1237 }
1238
1239-static GooString *getInfoString(Dict *infoDict, const char *key)
1240+static std::unique_ptr<GooString> getInfoString(Dict *infoDict, const char *key)
1241 {
1242 Object obj;
1243 // Raw value as read from PDF (may be in pdfDocEncoding or UCS2)
1244@@ -406,7 +399,7 @@ static GooString *getInfoString(Dict *infoDict, const char *key)
1245 Unicode *unicodeString;
1246 int unicodeLength;
1247 // Value HTML escaped and converted to desired encoding
1248- GooString *encodedString = nullptr;
1249+ std::unique_ptr<GooString> encodedString;
1250 // Is rawString UCS2 (as opposed to pdfDocEncoding)
1251 bool isUnicode;
1252
1253--
12542.40.0
1255
diff --git a/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch
new file mode 100644
index 0000000000..dc632c2707
--- /dev/null
+++ b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch
@@ -0,0 +1,112 @@
1From 0554731052d1a97745cb179ab0d45620589dd9c4 Mon Sep 17 00:00:00 2001
2From: Albert Astals Cid <aacid@kde.org>
3Date: Fri, 7 Jun 2024 00:54:55 +0200
4Subject: [PATCH] pdfinfo: Fix crash in broken documents when using -dests
5
6CVE: CVE-2024-6239
7Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/0554731052d1a97745cb179ab0d45620589dd9c4]
8
9Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
10---
11 utils/pdfinfo.cc | 35 +++++++++++++++--------------------
12 1 file changed, 15 insertions(+), 20 deletions(-)
13
14diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
15index a446c3c..4b9166f 100644
16--- a/utils/pdfinfo.cc
17+++ b/utils/pdfinfo.cc
18@@ -15,7 +15,7 @@
19 // under GPL version 2 or later
20 //
21 // Copyright (C) 2006 Dom Lachowicz <cinamod@hotmail.com>
22-// Copyright (C) 2007-2010, 2012, 2016-2022 Albert Astals Cid <aacid@kde.org>
23+// Copyright (C) 2007-2010, 2012, 2016-2022, 2024 Albert Astals Cid <aacid@kde.org>
24 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
25 // Copyright (C) 2011 Vittal Aithal <vittal.aithal@cognidox.com>
26 // Copyright (C) 2012, 2013, 2016-2018, 2021 Adrian Johnson <ajohnson@redneon.com>
27@@ -112,16 +112,21 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to
28 { "-?", argFlag, &printHelp, 0, "print usage information" },
29 {} };
30
31-static void printTextString(const GooString *s, const UnicodeMap *uMap)
32+static void printStdTextString(const std::string &s, const UnicodeMap *uMap)
33 {
34 char buf[8];
35- std::vector<Unicode> u = TextStringToUCS4(s->toStr());
36+ const std::vector<Unicode> u = TextStringToUCS4(s);
37 for (const auto &c : u) {
38 int n = uMap->mapUnicode(c, buf, sizeof(buf));
39 fwrite(buf, 1, n, stdout);
40 }
41 }
42
43+static void printTextString(const GooString *s, const UnicodeMap *uMap)
44+{
45+ printStdTextString(s->toStr(), uMap);
46+}
47+
48 static void printUCS4String(const Unicode *u, int len, const UnicodeMap *uMap)
49 {
50 char buf[8];
51@@ -293,11 +298,6 @@ static void printStruct(const StructElement *element, unsigned indent)
52 }
53 }
54
55-struct GooStringCompare
56-{
57- bool operator()(GooString *lhs, GooString *rhs) const { return lhs->cmp(const_cast<GooString *>(rhs)) < 0; }
58-};
59-
60 static void printLinkDest(const std::unique_ptr<LinkDest> &dest)
61 {
62 GooString s;
63@@ -368,29 +368,25 @@ static void printLinkDest(const std::unique_ptr<LinkDest> &dest)
64
65 static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap)
66 {
67- std::map<Ref, std::map<GooString *, std::unique_ptr<LinkDest>, GooStringCompare>> map;
68+ std::map<Ref, std::map<std::string, std::unique_ptr<LinkDest>>> map;
69
70 int numDests = doc->getCatalog()->numDestNameTree();
71 for (int i = 0; i < numDests; i++) {
72- GooString *name = new GooString(doc->getCatalog()->getDestNameTreeName(i));
73+ const GooString *name = doc->getCatalog()->getDestNameTreeName(i);
74 std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestNameTreeDest(i);
75- if (dest && dest->isPageRef()) {
76+ if (name && dest && dest->isPageRef()) {
77 Ref pageRef = dest->getPageRef();
78- map[pageRef].insert(std::make_pair(name, std::move(dest)));
79- } else {
80- delete name;
81+ map[pageRef].insert(std::make_pair(name->toStr(), std::move(dest)));
82 }
83 }
84
85 numDests = doc->getCatalog()->numDests();
86 for (int i = 0; i < numDests; i++) {
87- GooString *name = new GooString(doc->getCatalog()->getDestsName(i));
88+ const char *name = doc->getCatalog()->getDestsName(i);
89 std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestsDest(i);
90- if (dest && dest->isPageRef()) {
91+ if (name && dest && dest->isPageRef()) {
92 Ref pageRef = dest->getPageRef();
93 map[pageRef].insert(std::make_pair(name, std::move(dest)));
94- } else {
95- delete name;
96 }
97 }
98
99@@ -404,9 +400,8 @@ static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap)
100 printf("%4d ", i);
101 printLinkDest(it.second);
102 printf(" \"");
103- printTextString(it.first, uMap);
104+ printStdTextString(it.first, uMap);
105 printf("\"\n");
106- delete it.first;
107 }
108 }
109 }
110--
1112.40.0
112
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 04106f11aa..f49571caa9 100644
--- a/meta-oe/recipes-support/poppler/poppler_22.04.0.bb
+++ b/meta-oe/recipes-support/poppler/poppler_22.04.0.bb
@@ -7,7 +7,9 @@ SRC_URI = "http://poppler.freedesktop.org/${BP}.tar.xz \
7 file://0001-Do-not-overwrite-all-our-build-flags.patch \ 7 file://0001-Do-not-overwrite-all-our-build-flags.patch \
8 file://basename-include.patch \ 8 file://basename-include.patch \
9 file://0001-JBIG2Stream-Fix-crash-on-broken-file.patch \ 9 file://0001-JBIG2Stream-Fix-crash-on-broken-file.patch \
10 file://CVE-2023-34872.patch \ 10 file://CVE-2023-34872.patch \
11 file://CVE-2024-6239-0001.patch \
12 file://CVE-2024-6239-0002.patch \
11 " 13 "
12SRC_URI[sha256sum] = "813fb4b90e7bda63df53205c548602bae728887a60f4048aae4dbd9b1927deff" 14SRC_URI[sha256sum] = "813fb4b90e7bda63df53205c548602bae728887a60f4048aae4dbd9b1927deff"
13 15