From patchwork Wed Aug 21 09:05:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: yurade X-Patchwork-Id: 48031 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4515C52D7C for ; Wed, 21 Aug 2024 09:06:02 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.web11.15784.1724231157683880965 for ; Wed, 21 Aug 2024 02:05:57 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=8963eb4839=yogita.urade@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 47L4OTPh001709 for ; Wed, 21 Aug 2024 09:05:57 GMT Received: from ala-exchng01.corp.ad.wrs.com (ala-exchng01.wrs.com [147.11.82.252]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 412ju6uxca-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 21 Aug 2024 09:05:56 +0000 (GMT) Received: from blr-linux-engg1.wrs.com (147.11.136.210) by ala-exchng01.corp.ad.wrs.com (147.11.82.252) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 21 Aug 2024 02:05:53 -0700 From: yurade To: Subject: [oe][meta-oe][scarthgap][PATCH 1/1] poppler: CVE-2024-6239 Date: Wed, 21 Aug 2024 09:05:35 +0000 Message-ID: <20240821090535.1702393-1-yogita.urade@windriver.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 X-Originating-IP: [147.11.136.210] X-ClientProxiedBy: ala-exchng01.corp.ad.wrs.com (147.11.82.252) To ala-exchng01.corp.ad.wrs.com (147.11.82.252) X-Proofpoint-ORIG-GUID: _y9M0F4So4FsxOXcOz0lmp1i3vru6n3x X-Authority-Analysis: v=2.4 cv=VdWlP0p9 c=1 sm=1 tr=0 ts=66c5adf4 cx=c_pps a=/ZJR302f846pc/tyiSlYyQ==:117 a=/ZJR302f846pc/tyiSlYyQ==:17 a=HCiNrPZc1L8A:10 a=IkcTkHD0fZMA:10 a=yoJbH4e0A30A:10 a=t7CeM3EgAAAA:8 a=PYnjg3YJAAAA:8 a=e5mUnYsNAAAA:8 a=3fyaaF4VAAAA:8 a=69EAbJreAAAA:8 a=1Xalw8JdAAAA:8 a=c5qZ5hseAAAA:8 a=adCLzVSxAAAA:8 a=DTMSSxG-jYXJ2uFPd_AA:9 a=UUvlH2NyNM_xwBqZ:21 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 a=96-UuAdfYG6OSYlHWuPe:22 a=Vxmtnl_E_bksehYqCbjh:22 a=jOuFdahVONy5WApiBME_:22 a=SFmCVs0O3PHrPH4T2K5Z:22 a=xPetBifu163DGidV9dIZ:22 a=DQGzAmq_EYDXIBPpOZAu:22 X-Proofpoint-GUID: _y9M0F4So4FsxOXcOz0lmp1i3vru6n3x X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-21_07,2024-08-19_03,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 spamscore=0 malwarescore=0 impostorscore=0 mlxscore=0 suspectscore=0 mlxlogscore=999 lowpriorityscore=0 bulkscore=0 priorityscore=1501 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.21.0-2407110000 definitions=main-2408210065 X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-0064b401.pphosted.com id 47L4OTPh001709 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 21 Aug 2024 09:06:02 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/111882 From: Yogita Urade 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-0002 is the CVE fix and CVE-2024-6239-0001 is dependent commit to fix the CVE. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-6239 Upstream patch: https://gitlab.freedesktop.org/poppler/poppler/-/commit/0554731052d1a97745cb179ab0d45620589dd9c4 https://gitlab.freedesktop.org/poppler/poppler/-/commit/fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc Signed-off-by: Yogita Urade --- .../poppler/poppler/CVE-2024-6239-0001.patch | 1275 +++++++++++++++++ .../poppler/poppler/CVE-2024-6239-0002.patch | 111 ++ .../poppler/poppler_23.04.0.bb | 2 + 3 files changed, 1388 insertions(+) create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch create mode 100644 meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch 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 000000000..9994ce785 --- /dev/null +++ b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0001.patch @@ -0,0 +1,1275 @@ +From fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc Mon Sep 17 00:00:00 2001 +From: Sune Vuorela +Date: Thu, 1 Feb 2024 19:11:03 +0000 +Subject: [PATCH] More unicode vectors; fewer raw pointers + +CVE: CVE-2024-6239 +Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/fc1c711cb5f769546c6b31cc688bf0ee7f0c1dbc] + +Signed-off-by: Yogita Urade +--- + cpp/poppler-toc.cpp | 5 +- + glib/poppler-document.cc | 3 +- + poppler/CharCodeToUnicode.cc | 113 +++++++++------------------ + poppler/CharCodeToUnicode.h | 12 ++- + poppler/DateInfo.cc | 10 +-- + poppler/JSInfo.cc | 9 +-- + poppler/Outline.cc | 12 +-- + poppler/Outline.h | 7 +- + poppler/TextOutputDev.cc | 8 +- + poppler/UTF.cc | 78 ++++++++---------- + poppler/UTF.h | 11 ++- + qt5/src/poppler-outline.cc | 2 +- + qt5/src/poppler-private.cc | 13 ++- + qt5/src/poppler-private.h | 1 + + qt5/tests/check_internal_outline.cpp | 6 +- + qt5/tests/check_utf_conversion.cpp | 24 +++--- + qt6/src/poppler-outline.cc | 2 +- + qt6/src/poppler-private.cc | 5 ++ + qt6/src/poppler-private.h | 1 + + qt6/tests/check_internal_outline.cpp | 6 +- + qt6/tests/check_utf_conversion.cpp | 24 +++--- + utils/HtmlFonts.cc | 4 +- + utils/HtmlFonts.h | 2 +- + utils/HtmlOutputDev.cc | 38 ++++----- + utils/HtmlOutputDev.h | 2 +- + utils/pdfinfo.cc | 8 +- + utils/pdfsig.cc | 8 +- + utils/pdftohtml.cc | 25 +++--- + 28 files changed, 183 insertions(+), 256 deletions(-) + +diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp +index c79abde..ed3a983 100644 +--- a/cpp/poppler-toc.cpp ++++ b/cpp/poppler-toc.cpp +@@ -61,9 +61,8 @@ toc_item_private::~toc_item_private() + + void toc_item_private::load(const OutlineItem *item) + { +- const Unicode *title_unicode = item->getTitle(); +- const int title_length = item->getTitleLength(); +- title = detail::unicode_to_ustring(title_unicode, title_length); ++ const std::vector &title_unicode = item->getTitle(); ++ title = detail::unicode_to_ustring(title_unicode.data(), title_unicode.size()); + is_open = item->isOpen(); + } + +diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc +index 7505a6f..fdfefdc 100644 +--- a/glib/poppler-document.cc ++++ b/glib/poppler-document.cc +@@ -2772,7 +2772,8 @@ PopplerAction *poppler_index_iter_get_action(PopplerIndexIter *iter) + item = (*iter->items)[iter->index]; + link_action = item->getAction(); + +- title = unicode_to_char(item->getTitle(), item->getTitleLength()); ++ const std::vector &itemTitle = item->getTitle(); ++ title = unicode_to_char(itemTitle.data(), itemTitle.size()); + + action = _poppler_action_new(iter->document, link_action, title); + g_free(title); +diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc +index cd00937..d9ef019 100644 +--- a/poppler/CharCodeToUnicode.cc ++++ b/poppler/CharCodeToUnicode.cc +@@ -38,6 +38,7 @@ + + #include + #include ++#include + #include "goo/glibc.h" + #include "goo/gmem.h" + #include "goo/gfile.h" +@@ -51,13 +52,6 @@ + + //------------------------------------------------------------------------ + +-struct CharCodeToUnicodeString +-{ +- CharCode c; +- Unicode *u; +- int len; +-}; +- + //------------------------------------------------------------------------ + + static int getCharFromString(void *data) +@@ -162,7 +156,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(const char *fileName, co + } + fclose(f); + +- ctu = new CharCodeToUnicode(collection->toStr(), mapA, mapLenA, true, nullptr, 0, 0); ++ ctu = new CharCodeToUnicode(collection->toStr(), mapA, mapLenA, true, {}); + gfree(mapA); + return ctu; + } +@@ -171,8 +165,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil + { + FILE *f; + Unicode *mapA; +- CharCodeToUnicodeString *sMapA; +- CharCode size, oldSize, len, sMapSizeA, sMapLenA; ++ CharCode size, oldSize, len; + char buf[256]; + char *tok; + Unicode u0; +@@ -192,8 +185,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil + mapA = (Unicode *)gmallocn(size, sizeof(Unicode)); + memset(mapA, 0, size * sizeof(Unicode)); + len = 0; +- sMapA = nullptr; +- sMapSizeA = sMapLenA = 0; ++ std::vector sMapA; + + line = 0; + while (getLine(buf, sizeof(buf), f)) { +@@ -230,17 +222,12 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil + mapA[u0] = uBuf[0]; + } else { + mapA[u0] = 0; +- if (sMapLenA == sMapSizeA) { +- sMapSizeA += 16; +- sMapA = (CharCodeToUnicodeString *)greallocn(sMapA, sMapSizeA, sizeof(CharCodeToUnicodeString)); +- } +- sMapA[sMapLenA].c = u0; +- sMapA[sMapLenA].u = (Unicode *)gmallocn(n, sizeof(Unicode)); ++ std::vector u; ++ u.reserve(n); + for (i = 0; i < n; ++i) { +- sMapA[sMapLenA].u[i] = uBuf[i]; ++ u.push_back(uBuf[i]); + } +- sMapA[sMapLenA].len = n; +- ++sMapLenA; ++ sMapA.push_back({ u0, std::move(u) }); + } + if (u0 >= len) { + len = u0 + 1; +@@ -248,7 +235,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil + } + fclose(f); + +- ctu = new CharCodeToUnicode(fileName->toStr(), mapA, len, true, sMapA, sMapLenA, sMapSizeA); ++ ctu = new CharCodeToUnicode(fileName->toStr(), mapA, len, true, std::move(sMapA)); + gfree(mapA); + gfree(uBuf); + return ctu; +@@ -256,7 +243,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(const GooString *fil + + CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) + { +- return new CharCodeToUnicode({}, toUnicode, 256, true, nullptr, 0, 0); ++ return new CharCodeToUnicode({}, toUnicode, 256, true, {}); + } + + CharCodeToUnicode *CharCodeToUnicode::parseCMap(const GooString *buf, int nBits) +@@ -512,25 +499,18 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, int offset) + map[code] = 0xfffd; + } + } else { +- if (sMapLen >= sMapSize) { +- sMapSize = sMapSize + 16; +- sMap = (CharCodeToUnicodeString *)greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString)); +- } + map[code] = 0; +- sMap[sMapLen].c = code; + int utf16Len = n / 4; +- Unicode *utf16 = (Unicode *)gmallocn(utf16Len, sizeof(Unicode)); ++ std::vector utf16(utf16Len); ++ utf16.resize(utf16Len); + for (j = 0; j < utf16Len; ++j) { + if (!parseHex(uStr + j * 4, 4, &utf16[j])) { +- gfree(utf16); + error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap"); + return; + } + } + utf16[utf16Len - 1] += offset; +- sMap[sMapLen].len = UTF16toUCS4(utf16, utf16Len, &sMap[sMapLen].u); +- gfree(utf16); +- ++sMapLen; ++ sMap.push_back({ code, UTF16toUCS4(utf16.data(), utf16.size()) }); + } + } + +@@ -561,8 +541,6 @@ CharCodeToUnicode::CharCodeToUnicode() + { + map = nullptr; + mapLen = 0; +- sMap = nullptr; +- sMapLen = sMapSize = 0; + refCnt = 1; + isIdentity = false; + } +@@ -576,13 +554,11 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional &tagA) : t + for (i = 0; i < mapLen; ++i) { + map[i] = 0; + } +- sMap = nullptr; +- sMapLen = sMapSize = 0; + refCnt = 1; + isIdentity = false; + } + +-CharCodeToUnicode::CharCodeToUnicode(const std::optional &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, CharCodeToUnicodeString *sMapA, int sMapLenA, int sMapSizeA) : tag(tagA) ++CharCodeToUnicode::CharCodeToUnicode(const std::optional &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, std::vector &&sMapA) : tag(tagA) + { + mapLen = mapLenA; + if (copyMap) { +@@ -591,9 +567,7 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional &tagA, Uni + } else { + map = mapA; + } +- sMap = sMapA; +- sMapLen = sMapLenA; +- sMapSize = sMapSizeA; ++ sMap = std::move(sMapA); + refCnt = 1; + isIdentity = false; + } +@@ -601,12 +575,6 @@ CharCodeToUnicode::CharCodeToUnicode(const std::optional &tagA, Uni + CharCodeToUnicode::~CharCodeToUnicode() + { + gfree(map); +- if (sMap) { +- for (int i = 0; i < sMapLen; ++i) { +- gfree(sMap[i].u); +- } +- gfree(sMap); +- } + } + + void CharCodeToUnicode::incRefCnt() +@@ -628,7 +596,8 @@ bool CharCodeToUnicode::match(const GooString *tagA) + + void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) + { +- int i, j; ++ size_t i; ++ int j; + + if (!map || isIdentity) { + return; +@@ -636,28 +605,26 @@ void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) + if (len == 1) { + map[c] = u[0]; + } else { +- for (i = 0; i < sMapLen; ++i) { ++ std::optional> element; ++ for (i = 0; i < sMap.size(); ++i) { + if (sMap[i].c == c) { +- gfree(sMap[i].u); ++ sMap[i].u.clear(); ++ element = std::ref(sMap[i]); + break; + } + } +- if (i == sMapLen) { +- if (sMapLen == sMapSize) { +- sMapSize += 8; +- sMap = (CharCodeToUnicodeString *)greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString)); +- } +- ++sMapLen; ++ if (!element) { ++ sMap.emplace_back(CharCodeToUnicodeString { c, {} }); ++ element = std::ref(sMap.back()); + } + map[c] = 0; +- sMap[i].c = c; +- sMap[i].len = len; +- sMap[i].u = (Unicode *)gmallocn(len, sizeof(Unicode)); ++ element->get().c = c; ++ element->get().u.reserve(len); + for (j = 0; j < len; ++j) { + if (UnicodeIsValid(u[j])) { +- sMap[i].u[j] = u[j]; ++ element->get().u.push_back(u[j]); + } else { +- sMap[i].u[j] = 0xfffd; ++ element->get().u.push_back(0xfffd); + } + } + } +@@ -665,8 +632,6 @@ void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) + + int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode const **u) const + { +- int i; +- + if (isIdentity) { + map[0] = (Unicode)c; + *u = map; +@@ -679,10 +644,10 @@ int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode const **u) const + *u = &map[c]; + return 1; + } +- for (i = sMapLen - 1; i >= 0; --i) { // in reverse so CMap takes precedence +- if (sMap[i].c == c) { +- *u = sMap[i].u; +- return sMap[i].len; ++ for (auto i = sMap.size(); i > 0; --i) { // in reverse so CMap takes precedence ++ if (sMap[i - 1].c == c) { ++ *u = sMap[i - 1].u.data(); ++ return sMap[i - 1].u.size(); + } + } + return 0; +@@ -704,24 +669,24 @@ int CharCodeToUnicode::mapToCharCode(const Unicode *u, CharCode *c, int usize) c + } + *c = 'x'; + } else { +- int i, j; ++ size_t j; + // for each entry in the sMap +- for (i = 0; i < sMapLen; i++) { ++ for (const auto &element : sMap) { + // if the entry's unicode length isn't the same are usize, the strings + // are obviously different +- if (sMap[i].len != usize) { ++ if (element.u.size() != size_t(usize)) { + continue; + } + // compare the string char by char +- for (j = 0; j < sMap[i].len; j++) { +- if (sMap[i].u[j] != u[j]) { ++ for (j = 0; j < element.u.size(); j++) { ++ if (element.u[j] != u[j]) { + break; + } + } + + // we have the same strings +- if (j == sMap[i].len) { +- *c = sMap[i].c; ++ if (j == element.u.size()) { ++ *c = element.c; + return 1; + } + } +diff --git a/poppler/CharCodeToUnicode.h b/poppler/CharCodeToUnicode.h +index 596d44d..9aa2571 100644 +--- a/poppler/CharCodeToUnicode.h ++++ b/poppler/CharCodeToUnicode.h +@@ -33,11 +33,11 @@ + + #include + #include ++#include + + #include "poppler-config.h" + #include "CharTypes.h" + +-struct CharCodeToUnicodeString; + class GooString; + + //------------------------------------------------------------------------ +@@ -100,18 +100,22 @@ public: + CharCode getLength() const { return mapLen; } + + private: ++ struct CharCodeToUnicodeString ++ { ++ CharCode c; ++ std::vector u; ++ }; + bool parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); + void addMapping(CharCode code, char *uStr, int n, int offset); + void addMappingInt(CharCode code, Unicode u); + CharCodeToUnicode(); + explicit CharCodeToUnicode(const std::optional &tagA); +- CharCodeToUnicode(const std::optional &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, CharCodeToUnicodeString *sMapA, int sMapLenA, int sMapSizeA); ++ CharCodeToUnicode(const std::optional &tagA, Unicode *mapA, CharCode mapLenA, bool copyMap, std::vector &&sMapA); + + const std::optional tag; + Unicode *map; + CharCode mapLen; +- CharCodeToUnicodeString *sMap; +- int sMapLen, sMapSize; ++ std::vector sMap; + std::atomic_int refCnt; + bool isIdentity; + }; +diff --git a/poppler/DateInfo.cc b/poppler/DateInfo.cc +index cdba4ab..28474de 100644 +--- a/poppler/DateInfo.cc ++++ b/poppler/DateInfo.cc +@@ -36,16 +36,14 @@ + /* See PDF Reference 1.3, Section 3.8.2 for PDF Date representation */ + bool parseDateString(const GooString *date, int *year, int *month, int *day, int *hour, int *minute, int *second, char *tz, int *tzHour, int *tzMinute) + { +- Unicode *u; +- int len = TextStringToUCS4(date->toStr(), &u); ++ std::vector u = TextStringToUCS4(date->toStr()); + GooString s; +- for (int i = 0; i < len; i++) { ++ for (auto &c : u) { + // Ignore any non ASCII characters +- if (u[i] < 128) { +- s.append(u[i]); ++ if (c < 128) { ++ s.append(c); + } + } +- gfree(u); + const char *dateString = s.c_str(); + + if (strlen(dateString) < 2) { +diff --git a/poppler/JSInfo.cc b/poppler/JSInfo.cc +index 29fa707..eaef33e 100644 +--- a/poppler/JSInfo.cc ++++ b/poppler/JSInfo.cc +@@ -38,20 +38,17 @@ JSInfo::~JSInfo() { } + + void JSInfo::printJS(const GooString *js) + { +- Unicode *u = nullptr; + char buf[8]; +- int i, n, len; + + if (!js || !js->c_str()) { + return; + } + +- len = TextStringToUCS4(js->toStr(), &u); +- for (i = 0; i < len; i++) { +- n = uniMap->mapUnicode(u[i], buf, sizeof(buf)); ++ std::vector u = TextStringToUCS4(js->toStr()); ++ for (auto &c : u) { ++ int n = uniMap->mapUnicode(c, buf, sizeof(buf)); + fwrite(buf, 1, n, file); + } +- gfree(u); + } + + void JSInfo::scanLinkAction(LinkAction *link, const char *action) +diff --git a/poppler/Outline.cc b/poppler/Outline.cc +index 4c68be9..086c104 100644 +--- a/poppler/Outline.cc ++++ b/poppler/Outline.cc +@@ -407,15 +407,12 @@ OutlineItem::OutlineItem(const Dict *dict, Ref refA, OutlineItem *parentA, XRef + parent = parentA; + xref = xrefA; + doc = docA; +- title = nullptr; + kids = nullptr; + + obj1 = dict->lookup("Title"); + if (obj1.isString()) { + const GooString *s = obj1.getString(); +- titleLen = TextStringToUCS4(s->toStr(), &title); +- } else { +- titleLen = 0; ++ title = TextStringToUCS4(s->toStr()); + } + + obj1 = dict->lookup("Dest"); +@@ -446,9 +443,6 @@ OutlineItem::~OutlineItem() + delete kids; + kids = nullptr; + } +- if (title) { +- gfree(title); +- } + } + + std::vector *OutlineItem::readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA, PDFDoc *docA) +@@ -494,11 +488,9 @@ void OutlineItem::open() + + void OutlineItem::setTitle(const std::string &titleA) + { +- gfree(title); +- + Object dict = xref->fetch(ref); + GooString *g = new GooString(titleA); +- titleLen = TextStringToUCS4(g->toStr(), &title); ++ title = TextStringToUCS4(g->toStr()); + dict.dictSet("Title", Object(g)); + xref->setModifiedObject(&dict, ref); + } +diff --git a/poppler/Outline.h b/poppler/Outline.h +index a301604..af431f6 100644 +--- a/poppler/Outline.h ++++ b/poppler/Outline.h +@@ -27,6 +27,7 @@ + #define OUTLINE_H + + #include ++#include + #include "Object.h" + #include "CharTypes.h" + #include "poppler_private_export.h" +@@ -91,9 +92,8 @@ public: + OutlineItem(const OutlineItem &) = delete; + OutlineItem &operator=(const OutlineItem &) = delete; + static std::vector *readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA, PDFDoc *docA); +- const Unicode *getTitle() const { return title; } ++ const std::vector &getTitle() const { return title; } + void setTitle(const std::string &titleA); +- int getTitleLength() const { return titleLen; } + bool setPageDest(int i); + // OutlineItem keeps the ownership of the action + const LinkAction *getAction() const { return action.get(); } +@@ -112,8 +112,7 @@ private: + OutlineItem *parent; + PDFDoc *doc; + XRef *xref; +- Unicode *title; +- int titleLen; ++ std::vector title; + std::unique_ptr action; + bool startsOpen; + std::vector *kids; // nullptr if this item is closed or has no kids +diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc +index 06fc307..ee11fcb 100644 +--- a/poppler/TextOutputDev.cc ++++ b/poppler/TextOutputDev.cc +@@ -5668,15 +5668,11 @@ void ActualText::end(const GfxState *state) + // extents of all the glyphs inside the span + + if (actualTextNBytes) { +- Unicode *uni = nullptr; +- int length; +- + // now that we have the position info for all of the text inside + // the marked content span, we feed the "ActualText" back through + // text->addChar() +- length = TextStringToUCS4(actualText->toStr(), &uni); +- text->addChar(state, actualTextX0, actualTextY0, actualTextX1 - actualTextX0, actualTextY1 - actualTextY0, 0, actualTextNBytes, uni, length); +- gfree(uni); ++ std::vector uni = TextStringToUCS4(actualText->toStr()); ++ text->addChar(state, actualTextX0, actualTextY0, actualTextX1 - actualTextX0, actualTextY1 - actualTextY0, 0, actualTextNBytes, uni.data(), uni.size()); + } + + delete actualText; +diff --git a/poppler/UTF.cc b/poppler/UTF.cc +index 9b1bf95..eb542eb 100644 +--- a/poppler/UTF.cc ++++ b/poppler/UTF.cc +@@ -42,65 +42,52 @@ bool UnicodeIsValid(Unicode ucs4) + return (ucs4 < 0x110000) && ((ucs4 & 0xfffff800) != 0xd800) && (ucs4 < 0xfdd0 || ucs4 > 0xfdef) && ((ucs4 & 0xfffe) != 0xfffe); + } + +-int UTF16toUCS4(const Unicode *utf16, int utf16Len, Unicode **ucs4_out) ++std::vector UTF16toUCS4(const Unicode *utf16, int utf16Len) + { +- int i, n, len; +- Unicode *u; +- + // count characters +- len = 0; +- for (i = 0; i < utf16Len; i++) { ++ int len = 0; ++ for (int i = 0; i < utf16Len; i++) { + if (utf16[i] >= 0xd800 && utf16[i] < 0xdc00 && i + 1 < utf16Len && utf16[i + 1] >= 0xdc00 && utf16[i + 1] < 0xe000) { + i++; /* surrogate pair */ + } + len++; + } +- if (ucs4_out == nullptr) { +- return len; +- } +- +- u = (Unicode *)gmallocn(len, sizeof(Unicode)); +- n = 0; ++ std::vector u; ++ u.reserve(len); + // convert string +- for (i = 0; i < utf16Len; i++) { ++ for (int i = 0; i < utf16Len; i++) { + if (utf16[i] >= 0xd800 && utf16[i] < 0xdc00) { /* surrogate pair */ + if (i + 1 < utf16Len && utf16[i + 1] >= 0xdc00 && utf16[i + 1] < 0xe000) { + /* next code is a low surrogate */ +- u[n] = (((utf16[i] & 0x3ff) << 10) | (utf16[i + 1] & 0x3ff)) + 0x10000; ++ u.push_back((((utf16[i] & 0x3ff) << 10) | (utf16[i + 1] & 0x3ff)) + 0x10000); + ++i; + } else { + /* missing low surrogate + replace it with REPLACEMENT CHARACTER (U+FFFD) */ +- u[n] = 0xfffd; ++ u.push_back(0xfffd); + } + } else if (utf16[i] >= 0xdc00 && utf16[i] < 0xe000) { + /* invalid low surrogate + replace it with REPLACEMENT CHARACTER (U+FFFD) */ +- u[n] = 0xfffd; ++ u.push_back(0xfffd); + } else { +- u[n] = utf16[i]; ++ u.push_back(utf16[i]); + } +- if (!UnicodeIsValid(u[n])) { +- u[n] = 0xfffd; ++ if (!UnicodeIsValid(u.back())) { ++ u.back() = 0xfffd; + } +- n++; + } +- *ucs4_out = u; +- return len; ++ return u; + } + +-int TextStringToUCS4(const std::string &textStr, Unicode **ucs4) ++std::vector TextStringToUCS4(const std::string &textStr) + { +- int i, len; +- const char *s; +- Unicode *u; + bool isUnicode, isUnicodeLE; + +- len = textStr.size(); +- s = textStr.c_str(); ++ int len = textStr.size(); ++ const std::string &s = textStr; + if (len == 0) { +- *ucs4 = nullptr; +- return 0; ++ return {}; + } + + if (GooString::hasUnicodeMarker(textStr)) { +@@ -115,30 +102,30 @@ int TextStringToUCS4(const std::string &textStr, Unicode **ucs4) + } + + if (isUnicode || isUnicodeLE) { +- Unicode *utf16; + len = len / 2 - 1; + if (len > 0) { +- utf16 = new Unicode[len]; +- for (i = 0; i < len; i++) { ++ std::vector utf16; ++ utf16.reserve(len); ++ for (int i = 0; i < len; i++) { + if (isUnicode) { +- utf16[i] = (s[2 + i * 2] & 0xff) << 8 | (s[3 + i * 2] & 0xff); ++ utf16.push_back((s[2 + i * 2] & 0xff) << 8 | (s[3 + i * 2] & 0xff)); + } else { // UnicodeLE +- utf16[i] = (s[3 + i * 2] & 0xff) << 8 | (s[2 + i * 2] & 0xff); ++ utf16.push_back((s[3 + i * 2] & 0xff) << 8 | (s[2 + i * 2] & 0xff)); + } + } +- len = UTF16toUCS4(utf16, len, &u); +- delete[] utf16; ++ return UTF16toUCS4(utf16.data(), utf16.size()); ++ + } else { +- u = nullptr; ++ return {}; + } + } else { +- u = (Unicode *)gmallocn(len, sizeof(Unicode)); +- for (i = 0; i < len; i++) { +- u[i] = pdfDocEncoding[s[i] & 0xff]; ++ std::vector u; ++ u.reserve(len); ++ for (int i = 0; i < len; i++) { ++ u.push_back(pdfDocEncoding[s[i] & 0xff]); + } ++ return u; + } +- *ucs4 = u; +- return len; + } + + bool UnicodeIsWhitespace(Unicode ucs4) +@@ -549,7 +536,10 @@ void unicodeToAscii7(const Unicode *in, int len, Unicode **ucs4_out, int *out_le + } + } + +- *out_len = TextStringToUCS4(str, ucs4_out); ++ std::vector ucs4 = TextStringToUCS4(str); ++ *out_len = ucs4.size(); ++ *ucs4_out = (Unicode *)gmallocn(ucs4.size(), sizeof(Unicode)); ++ memcpy(*ucs4_out, ucs4.data(), ucs4.size() * sizeof(Unicode)); + + if (indices) { + idx[k] = in_idx[len]; +diff --git a/poppler/UTF.h b/poppler/UTF.h +index 626c686..bfc5f65 100644 +--- a/poppler/UTF.h ++++ b/poppler/UTF.h +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include "goo/GooString.h" + #include "CharTypes.h" +@@ -27,16 +28,14 @@ + // Convert a UTF-16 string to a UCS-4 + // utf16 - utf16 bytes + // utf16_len - number of UTF-16 characters +-// ucs4_out - if not NULL, allocates and returns UCS-4 string. Free with gfree. + // returns number of UCS-4 characters +-int UTF16toUCS4(const Unicode *utf16, int utf16Len, Unicode **ucs4_out); ++std::vector UTF16toUCS4(const Unicode *utf16, int utf16Len); + + // Convert a PDF Text String to UCS-4 + // s - PDF text string +-// ucs4 - if the number of UCS-4 characters is > 0, allocates and +-// returns UCS-4 string. Free with gfree. +-// returns number of UCS-4 characters +-int POPPLER_PRIVATE_EXPORT TextStringToUCS4(const std::string &textStr, Unicode **ucs4); ++// returns UCS-4 characters ++// Convert a PDF text string to UCS-4 ++std::vector POPPLER_PRIVATE_EXPORT TextStringToUCS4(const std::string &textStr); + + // check if UCS-4 character is valid + bool UnicodeIsValid(Unicode ucs4); +diff --git a/qt5/src/poppler-outline.cc b/qt5/src/poppler-outline.cc +index 5ff7e37..2f6ef2d 100644 +--- a/qt5/src/poppler-outline.cc ++++ b/qt5/src/poppler-outline.cc +@@ -78,7 +78,7 @@ QString OutlineItem::name() const + + if (name.isEmpty()) { + if (const ::OutlineItem *data = m_data->data) { +- name = unicodeToQString(data->getTitle(), data->getTitleLength()); ++ name = unicodeToQString(data->getTitle()); + } + } + +diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc +index 228d8e8..54df79f 100644 +--- a/qt5/src/poppler-private.cc ++++ b/qt5/src/poppler-private.cc +@@ -94,6 +94,11 @@ QString unicodeToQString(const Unicode *u, int len) + return QString::fromUtf8(convertedStr.c_str(), convertedStr.getLength()); + } + ++QString unicodeToQString(const std::vector &u) ++{ ++ return unicodeToQString(u.data(), u.size()); ++} ++ + QString UnicodeParsedString(const GooString *s1) + { + return (s1) ? UnicodeParsedString(s1->toStr()) : QString(); +@@ -266,13 +271,7 @@ void DocumentData::addTocChildren(QDomDocument *docSyn, QDomNode *parent, const + // iterate over every object in 'items' + + // 1. create element using outlineItem's title as tagName +- QString name; +- const Unicode *uniChar = outlineItem->getTitle(); +- int titleLength = outlineItem->getTitleLength(); +- name = unicodeToQString(uniChar, titleLength); +- if (name.isEmpty()) { +- continue; +- } ++ QString name = unicodeToQString(outlineItem->getTitle()); + + QDomElement item = docSyn->createElement(name); + parent->appendChild(item); +diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h +index 39dfb6b..bba5bd7 100644 +--- a/qt5/src/poppler-private.h ++++ b/qt5/src/poppler-private.h +@@ -73,6 +73,7 @@ namespace Poppler { + + /* borrowed from kpdf */ + POPPLER_QT5_EXPORT QString unicodeToQString(const Unicode *u, int len); ++POPPLER_QT5_EXPORT QString unicodeToQString(const std::vector &u); + + POPPLER_QT5_EXPORT QString UnicodeParsedString(const GooString *s1); + +diff --git a/qt5/tests/check_internal_outline.cpp b/qt5/tests/check_internal_outline.cpp +index c12b604..5db6bf4 100644 +--- a/qt5/tests/check_internal_outline.cpp ++++ b/qt5/tests/check_internal_outline.cpp +@@ -56,10 +56,10 @@ void TestInternalOutline::testCreateOutline() + + static std::string getTitle(const OutlineItem *item) + { +- const Unicode *u = item->getTitle(); ++ std::vector u = item->getTitle(); + std::string s; +- for (int i = 0; i < item->getTitleLength(); i++) { +- s.append(1, (char)u[i]); ++ for (auto &c : u) { ++ s.append(1, (char)(c)); + } + return s; + } +diff --git a/qt5/tests/check_utf_conversion.cpp b/qt5/tests/check_utf_conversion.cpp +index 73c684e..b00f080 100644 +--- a/qt5/tests/check_utf_conversion.cpp ++++ b/qt5/tests/check_utf_conversion.cpp +@@ -133,16 +133,13 @@ void TestUTFConversion::testUnicodeToAscii7() + // malloc() always returns 8-byte aligned memory addresses. + GooString *goo = Poppler::QStringToUnicodeGooString(QString::fromUtf8("®©©©©©©©©©©©©©©©©©©©©")); // clazy:exclude=qstring-allocations + +- Unicode *in; +- const int in_len = TextStringToUCS4(goo->toStr(), &in); ++ const std::vector in = TextStringToUCS4(goo->toStr()); + + delete goo; + + int in_norm_len; + int *in_norm_idx; +- Unicode *in_norm = unicodeNormalizeNFKC(in, in_len, &in_norm_len, &in_norm_idx, true); +- +- free(in); ++ Unicode *in_norm = unicodeNormalizeNFKC(in.data(), in.size(), &in_norm_len, &in_norm_idx, true); + + Unicode *out; + int out_len; +@@ -174,25 +171,24 @@ void TestUTFConversion::testUnicodeLittleEndian() + // Let's assert both GooString's are different + QVERIFY(GooUTF16LE != GooUTF16BE); + +- Unicode *UCS4fromLE, *UCS4fromBE; +- const int len1 = TextStringToUCS4(GooUTF16LE, &UCS4fromLE); +- const int len2 = TextStringToUCS4(GooUTF16BE, &UCS4fromBE); ++ const std::vector UCS4fromLE = TextStringToUCS4(GooUTF16LE); ++ const std::vector UCS4fromBE = TextStringToUCS4(GooUTF16BE); + + // len is 4 because TextStringToUCS4() removes the two leading Byte Order Mark (BOM) code points +- QCOMPARE(len1, len2); +- QCOMPARE(len1, 4); ++ QCOMPARE(UCS4fromLE.size(), UCS4fromBE.size()); ++ QCOMPARE(UCS4fromLE.size(), 4); + + // Check that now after conversion, UCS4fromLE and UCS4fromBE are now the same +- for (int i = 0; i < len1; i++) { ++ for (size_t i = 0; i < UCS4fromLE.size(); i++) { + QCOMPARE(UCS4fromLE[i], UCS4fromBE[i]); + } + + const QString expected = QString::fromUtf8("HI!☑"); // clazy:exclude=qstring-allocations + + // Do some final verifications, checking the strings to be "HI!" +- QVERIFY(*UCS4fromLE == *UCS4fromBE); +- QVERIFY(compare(UCS4fromLE, expected.utf16(), len1)); +- QVERIFY(compare(UCS4fromBE, expected.utf16(), len1)); ++ QVERIFY(UCS4fromLE == UCS4fromBE); ++ QVERIFY(compare(UCS4fromLE.data(), expected.utf16(), UCS4fromLE.size())); ++ QVERIFY(compare(UCS4fromBE.data(), expected.utf16(), UCS4fromLE.size())); + } + + QTEST_GUILESS_MAIN(TestUTFConversion) +diff --git a/qt6/src/poppler-outline.cc b/qt6/src/poppler-outline.cc +index f5ba2a9..2bc0d30 100644 +--- a/qt6/src/poppler-outline.cc ++++ b/qt6/src/poppler-outline.cc +@@ -78,7 +78,7 @@ QString OutlineItem::name() const + + if (name.isEmpty()) { + if (const ::OutlineItem *data = m_data->data) { +- name = unicodeToQString(data->getTitle(), data->getTitleLength()); ++ name = unicodeToQString(data->getTitle()); + } + } + +diff --git a/qt6/src/poppler-private.cc b/qt6/src/poppler-private.cc +index 91d1725..2cb2396 100644 +--- a/qt6/src/poppler-private.cc ++++ b/qt6/src/poppler-private.cc +@@ -94,6 +94,11 @@ QString unicodeToQString(const Unicode *u, int len) + return QString::fromUtf8(convertedStr.c_str(), convertedStr.getLength()); + } + ++QString unicodeToQString(const std::vector &u) ++{ ++ return unicodeToQString(u.data(), u.size()); ++} ++ + QString UnicodeParsedString(const GooString *s1) + { + return (s1) ? UnicodeParsedString(s1->toStr()) : QString(); +diff --git a/qt6/src/poppler-private.h b/qt6/src/poppler-private.h +index d1f7335..a3117a6 100644 +--- a/qt6/src/poppler-private.h ++++ b/qt6/src/poppler-private.h +@@ -72,6 +72,7 @@ namespace Poppler { + + /* borrowed from kpdf */ + POPPLER_QT6_EXPORT QString unicodeToQString(const Unicode *u, int len); ++POPPLER_QT6_EXPORT QString unicodeToQString(const std::vector &u); + + POPPLER_QT6_EXPORT QString UnicodeParsedString(const GooString *s1); + +diff --git a/qt6/tests/check_internal_outline.cpp b/qt6/tests/check_internal_outline.cpp +index c12b604..d23e773 100644 +--- a/qt6/tests/check_internal_outline.cpp ++++ b/qt6/tests/check_internal_outline.cpp +@@ -56,10 +56,10 @@ void TestInternalOutline::testCreateOutline() + + static std::string getTitle(const OutlineItem *item) + { +- const Unicode *u = item->getTitle(); ++ const std::vector &u = item->getTitle(); + std::string s; +- for (int i = 0; i < item->getTitleLength(); i++) { +- s.append(1, (char)u[i]); ++ for (const auto &c : u) { ++ s.append(1, (char)(c)); + } + return s; + } +diff --git a/qt6/tests/check_utf_conversion.cpp b/qt6/tests/check_utf_conversion.cpp +index 2cac758..e7f35ea 100644 +--- a/qt6/tests/check_utf_conversion.cpp ++++ b/qt6/tests/check_utf_conversion.cpp +@@ -131,16 +131,13 @@ void TestUTFConversion::testUnicodeToAscii7() + // malloc() always returns 8-byte aligned memory addresses. + GooString *goo = Poppler::QStringToUnicodeGooString(QString::fromUtf8("®©©©©©©©©©©©©©©©©©©©©")); // clazy:exclude=qstring-allocations + +- Unicode *in; +- const int in_len = TextStringToUCS4(goo->toStr(), &in); ++ const std::vector in = TextStringToUCS4(goo->toStr()); + + delete goo; + + int in_norm_len; + int *in_norm_idx; +- Unicode *in_norm = unicodeNormalizeNFKC(in, in_len, &in_norm_len, &in_norm_idx, true); +- +- free(in); ++ Unicode *in_norm = unicodeNormalizeNFKC(in.data(), in.size(), &in_norm_len, &in_norm_idx, true); + + Unicode *out; + int out_len; +@@ -172,25 +169,24 @@ void TestUTFConversion::testUnicodeLittleEndian() + // Let's assert both GooString's are different + QVERIFY(GooUTF16LE != GooUTF16BE); + +- Unicode *UCS4fromLE, *UCS4fromBE; +- const int len1 = TextStringToUCS4(GooUTF16LE, &UCS4fromLE); +- const int len2 = TextStringToUCS4(GooUTF16BE, &UCS4fromBE); ++ const std::vector UCS4fromLE = TextStringToUCS4(GooUTF16LE); ++ const std::vector UCS4fromBE = TextStringToUCS4(GooUTF16BE); + + // len is 4 because TextStringToUCS4() removes the two leading Byte Order Mark (BOM) code points +- QCOMPARE(len1, len2); +- QCOMPARE(len1, 4); ++ QCOMPARE(UCS4fromLE.size(), UCS4fromBE.size()); ++ QCOMPARE(UCS4fromLE.size(), 4); + + // Check that now after conversion, UCS4fromLE and UCS4fromBE are now the same +- for (int i = 0; i < len1; i++) { ++ for (size_t i = 0; i < UCS4fromLE.size(); i++) { + QCOMPARE(UCS4fromLE[i], UCS4fromBE[i]); + } + + const QString expected = QStringLiteral("HI!☑"); + + // Do some final verifications, checking the strings to be "HI!" +- QVERIFY(*UCS4fromLE == *UCS4fromBE); +- QVERIFY(compare(UCS4fromLE, expected.utf16(), len1)); +- QVERIFY(compare(UCS4fromBE, expected.utf16(), len1)); ++ QVERIFY(UCS4fromLE == UCS4fromBE); ++ QVERIFY(compare(UCS4fromLE.data(), expected.utf16(), UCS4fromLE.size())); ++ QVERIFY(compare(UCS4fromBE.data(), expected.utf16(), UCS4fromBE.size())); + } + + QTEST_GUILESS_MAIN(TestUTFConversion) +diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc +index ca7d4a4..9f25621 100644 +--- a/utils/HtmlFonts.cc ++++ b/utils/HtmlFonts.cc +@@ -230,9 +230,9 @@ GooString *HtmlFont::getFullName() + } + + // this method if plain wrong todo +-GooString *HtmlFont::HtmlFilter(const Unicode *u, int uLen) ++std::unique_ptr HtmlFont::HtmlFilter(const Unicode *u, int uLen) + { +- GooString *tmp = new GooString(); ++ auto tmp = std::make_unique(); + const UnicodeMap *uMap; + char buf[8]; + int n; +diff --git a/utils/HtmlFonts.h b/utils/HtmlFonts.h +index ca4ae54..74cdca0 100644 +--- a/utils/HtmlFonts.h ++++ b/utils/HtmlFonts.h +@@ -104,7 +104,7 @@ public: + } + const double *getRotMat() const { return rotSkewMat; } + GooString *getFontName(); +- static GooString *HtmlFilter(const Unicode *u, int uLen); // char* s); ++ static std::unique_ptr HtmlFilter(const Unicode *u, int uLen); // char* s); + bool isEqual(const HtmlFont &x) const; + bool isEqualIgnoreBold(const HtmlFont &x) const; + void print() const { printf("font: %s (%s) %d %s%s\n", FontName->c_str(), familyName.c_str(), size, bold ? "bold " : "", italic ? "italic " : ""); }; +diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc +index 2611e06..b45a5ff 100644 +--- a/utils/HtmlOutputDev.cc ++++ b/utils/HtmlOutputDev.cc +@@ -124,11 +124,11 @@ static bool debug = false; + + #if 0 + static GooString* Dirname(GooString* str){ +- ++ + char *p=str->c_str(); + int len=str->getLength(); + for (int i=len-1;i>=0;i--) +- if (*(p+i)==SLASH) ++ if (*(p+i)==SLASH) + return new GooString(p,i+1); + return new GooString(); + } +@@ -219,14 +219,13 @@ HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu *_fonts) : + len = size = 0; + yxNext = nullptr; + xyNext = nullptr; +- htext = new GooString(); ++ htext = std::make_unique(); + dir = textDirUnknown; + } + + HtmlString::~HtmlString() + { + gfree(text); +- delete htext; + gfree(xRight); + } + +@@ -345,7 +344,6 @@ void HtmlPage::beginString(GfxState *state, const GooString *s) + void HtmlPage::conv() + { + for (HtmlString *tmp = yxStrings; tmp; tmp = tmp->yxNext) { +- delete tmp->htext; + tmp->htext = HtmlFont::HtmlFilter(tmp->text, tmp->len); + + size_t linkIndex = 0; +@@ -641,7 +639,7 @@ void HtmlPage::coalesce() + bool finish_a = switch_links && hlink1 != nullptr; + bool finish_italic = hfont1->isItalic() && (!hfont2->isItalic() || finish_a); + bool finish_bold = hfont1->isBold() && (!hfont2->isBold() || finish_a || finish_italic); +- CloseTags(str1->htext, finish_a, finish_italic, finish_bold); ++ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold); + if (switch_links && hlink2 != nullptr) { + GooString *ls = hlink2->getLinkStart(); + str1->htext->append(ls); +@@ -654,7 +652,7 @@ void HtmlPage::coalesce() + str1->htext->append("", 3); + } + +- str1->htext->append(str2->htext); ++ str1->htext->append(str2->htext.get()); + // str1 now contains href for link of str2 (if it is defined) + str1->link = str2->link; + hfont1 = hfont2; +@@ -671,7 +669,7 @@ void HtmlPage::coalesce() + bool finish_a = str1->getLink() != nullptr; + bool finish_bold = hfont1->isBold(); + bool finish_italic = hfont1->isItalic(); +- CloseTags(str1->htext, finish_a, finish_italic, finish_bold); ++ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold); + + str1->xMin = curX; + str1->yMin = curY; +@@ -698,14 +696,14 @@ void HtmlPage::coalesce() + bool finish_bold = hfont1->isBold(); + bool finish_italic = hfont1->isItalic(); + bool finish_a = str1->getLink() != nullptr; +- CloseTags(str1->htext, finish_a, finish_italic, finish_bold); ++ CloseTags(str1->htext.get(), finish_a, finish_italic, finish_bold); + + #if 0 //~ for debugging + for (str1 = yxStrings; str1; str1 = str1->yxNext) { + printf("x=%3d..%3d y=%3d..%3d size=%2d ", + (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax, + (int)(str1->yMax - str1->yMin)); +- printf("'%s'\n", str1->htext->c_str()); ++ printf("'%s'\n", str1->htext->c_str()); + } + printf("\n------------------------------------------------------------\n\n"); + #endif +@@ -1225,10 +1223,10 @@ void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref) + exit(1); + } + delete fname; +- // if(state->getRotation()!=0) ++ // if(state->getRotation()!=0) + // fprintf(tin,"ROTATE=%d rotate %d neg %d neg translate\n",state->getRotation(),state->getX1(),-state->getY1()); +- // else +- fprintf(tin,"ROTATE=%d neg %d neg translate\n",state->getX1(),state->getY1()); ++ // else ++ fprintf(tin,"ROTATE=%d neg %d neg translate\n",state->getX1(),state->getY1()); + } + } + #endif +@@ -1723,10 +1721,11 @@ bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector\n", output); + + for (OutlineItem *item : *outlines) { +- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength()); ++ const auto &title = item->getTitle(); ++ std::unique_ptr titleStr = HtmlFont::HtmlFilter(title.data(), title.size()); + + GooString *linkName = nullptr; +- ; ++ + const int itemPage = getOutlinePageNum(item); + if (itemPage > 0) { + /* complex simple +@@ -1753,12 +1752,13 @@ bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector", linkName->c_str()); + } +- fputs(titleStr->c_str(), output); ++ if (titleStr) { ++ fputs(titleStr->c_str(), output); ++ } + if (linkName) { + fputs("", output); + delete linkName; + } +- delete titleStr; + atLeastOne = true; + + item->open(); +@@ -1778,14 +1778,14 @@ void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const std::vector\n", output); + + for (OutlineItem *item : *outlines) { +- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength()); ++ const std::vector &title = item->getTitle(); ++ auto titleStr = HtmlFont::HtmlFilter(title.data(), title.size()); + const int itemPage = getOutlinePageNum(item); + if (itemPage > 0) { + fprintf(output, "%s\n", itemPage, titleStr->c_str()); + } else { + fprintf(output, "%s\n", titleStr->c_str()); + } +- delete titleStr; + + item->open(); + if (item->hasKids() && item->getKids()) { +diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h +index c7b08d1..e490eff 100644 +--- a/utils/HtmlOutputDev.h ++++ b/utils/HtmlOutputDev.h +@@ -95,7 +95,7 @@ private: + HtmlString *yxNext; // next string in y-major order + HtmlString *xyNext; // next string in x-major order + int fontpos; +- GooString *htext; ++ std::unique_ptr htext; + int len; // length of text and xRight + int size; // size of text and xRight arrays + UnicodeTextDirection dir; // direction (left to right/right to left) +diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc +index 1f4ca79..2057d22 100644 +--- a/utils/pdfinfo.cc ++++ b/utils/pdfinfo.cc +@@ -114,14 +114,12 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to + + static void printTextString(const GooString *s, const UnicodeMap *uMap) + { +- Unicode *u; + char buf[8]; +- int len = TextStringToUCS4(s->toStr(), &u); +- for (int i = 0; i < len; i++) { +- int n = uMap->mapUnicode(u[i], buf, sizeof(buf)); ++ std::vector u = TextStringToUCS4(s->toStr()); ++ for (const auto &c : u) { ++ int n = uMap->mapUnicode(c, buf, sizeof(buf)); + fwrite(buf, 1, n, stdout); + } +- gfree(u); + } + + static void printUCS4String(const Unicode *u, int len, const UnicodeMap *uMap) +diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc +index 490795f..e15a360 100644 +--- a/utils/pdfsig.cc ++++ b/utils/pdfsig.cc +@@ -224,16 +224,14 @@ static std::string TextStringToUTF8(const std::string &str) + { + const UnicodeMap *utf8Map = globalParams->getUtf8Map(); + +- Unicode *u; +- const int len = TextStringToUCS4(str, &u); ++ std::vector u = TextStringToUCS4(str); + + std::string convertedStr; +- for (int i = 0; i < len; ++i) { ++ for (auto &c : u) { + char buf[8]; +- const int n = utf8Map->mapUnicode(u[i], buf, sizeof(buf)); ++ const int n = utf8Map->mapUnicode(c, buf, sizeof(buf)); + convertedStr.append(buf, n); + } +- gfree(u); + + return convertedStr; + } +diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc +index 97b141a..d7c0889 100644 +--- a/utils/pdftohtml.cc ++++ b/utils/pdftohtml.cc +@@ -99,7 +99,7 @@ static char ownerPassword[33] = ""; + static char userPassword[33] = ""; + static bool printVersion = false; + +-static GooString *getInfoString(Dict *infoDict, const char *key); ++static std::unique_ptr getInfoString(Dict *infoDict, const char *key); + static GooString *getInfoDate(Dict *infoDict, const char *key); + + static char textEncName[128] = ""; +@@ -158,8 +158,11 @@ int main(int argc, char *argv[]) + { + std::unique_ptr doc; + GooString *fileName = nullptr; +- GooString *docTitle = nullptr; +- GooString *author = nullptr, *keywords = nullptr, *subject = nullptr, *date = nullptr; ++ std::unique_ptr docTitle; ++ std::unique_ptr author; ++ std::unique_ptr keywords; ++ std::unique_ptr subject; ++ GooString *date = nullptr; + GooString *htmlFileName = nullptr; + HtmlOutputDev *htmlOut = nullptr; + SplashOutputDev *splashOut = nullptr; +@@ -317,7 +320,7 @@ int main(int argc, char *argv[]) + } + } + if (!docTitle) { +- docTitle = new GooString(htmlFileName); ++ docTitle = std::make_unique(htmlFileName); + } + + if (!singleHtml) { +@@ -330,16 +333,6 @@ int main(int argc, char *argv[]) + // write text file + 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, + rawOrder, firstPage, doOutline); +- delete docTitle; +- if (author) { +- delete author; +- } +- if (keywords) { +- delete keywords; +- } +- if (subject) { +- delete subject; +- } + if (date) { + delete date; + } +@@ -397,7 +390,7 @@ error: + return exit_status; + } + +-static GooString *getInfoString(Dict *infoDict, const char *key) ++static std::unique_ptr getInfoString(Dict *infoDict, const char *key) + { + Object obj; + // Raw value as read from PDF (may be in pdfDocEncoding or UCS2) +@@ -406,7 +399,7 @@ static GooString *getInfoString(Dict *infoDict, const char *key) + Unicode *unicodeString; + int unicodeLength; + // Value HTML escaped and converted to desired encoding +- GooString *encodedString = nullptr; ++ std::unique_ptr encodedString; + // Is rawString UCS2 (as opposed to pdfDocEncoding) + bool isUnicode; + +-- +2.40.0 + 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 000000000..cb9ef4237 --- /dev/null +++ b/meta-oe/recipes-support/poppler/poppler/CVE-2024-6239-0002.patch @@ -0,0 +1,111 @@ +From 0554731052d1a97745cb179ab0d45620589dd9c4 Mon Sep 17 00:00:00 2001 +From: Albert Astals Cid +Date: Fri, 17 Jun 2024 00:54:55 +0200 +Subject: [PATCH] pdfinfo: Fix crash in broken documents when using -dests + +CVE: CVE-2024-6239 +Upstream-Status: Backport [https://gitlab.freedesktop.org/poppler/poppler/-/commit/0554731052d1a97745cb179ab0d45620589dd9c4] + +Signed-off-by: Yogita Urade +--- + utils/pdfinfo.cc | 35 +++++++++++++++-------------------- + 1 file changed, 15 insertions(+), 20 deletions(-) + +diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc +index 2057d22..5f96b41 100644 +--- a/utils/pdfinfo.cc ++++ b/utils/pdfinfo.cc +@@ -15,7 +15,7 @@ + // under GPL version 2 or later + // + // Copyright (C) 2006 Dom Lachowicz +-// Copyright (C) 2007-2010, 2012, 2016-2022 Albert Astals Cid ++// Copyright (C) 2007-2010, 2012, 2016-2022, 2024 Albert Astals Cid + // Copyright (C) 2010 Hib Eris + // Copyright (C) 2011 Vittal Aithal + // Copyright (C) 2012, 2013, 2016-2018, 2021 Adrian Johnson +@@ -112,16 +112,21 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to + { "-?", argFlag, &printHelp, 0, "print usage information" }, + {} }; + +-static void printTextString(const GooString *s, const UnicodeMap *uMap) ++static void printStdTextString(const std::string &s, const UnicodeMap *uMap) + { + char buf[8]; +- std::vector u = TextStringToUCS4(s->toStr()); ++ const std::vector u = TextStringToUCS4(s); + for (const auto &c : u) { + int n = uMap->mapUnicode(c, buf, sizeof(buf)); + fwrite(buf, 1, n, stdout); + } + } + ++static void printTextString(const GooString *s, const UnicodeMap *uMap) ++{ ++ printStdTextString(s->toStr(), uMap); ++} ++ + static void printUCS4String(const Unicode *u, int len, const UnicodeMap *uMap) + { + char buf[8]; +@@ -293,11 +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; +@@ -368,29 +368,25 @@ static void printLinkDest(const std::unique_ptr &dest) + + 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; + } + } + +@@ -404,9 +400,8 @@ static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap) + printf("%4d ", i); + printLinkDest(it.second); + printf(" \""); +- printTextString(it.first, uMap); ++ printStdTextString(it.first, uMap); + printf("\"\n"); +- delete it.first; + } + } + } +-- +2.40.0 diff --git a/meta-oe/recipes-support/poppler/poppler_23.04.0.bb b/meta-oe/recipes-support/poppler/poppler_23.04.0.bb index f4411e116..e57760d85 100644 --- a/meta-oe/recipes-support/poppler/poppler_23.04.0.bb +++ b/meta-oe/recipes-support/poppler/poppler_23.04.0.bb @@ -9,6 +9,8 @@ SRC_URI = "http://poppler.freedesktop.org/${BP}.tar.xz \ file://0001-cmake-Do-not-use-isystem.patch \ file://jpeg-stdio.patch \ file://CVE-2023-34872.patch \ + file://CVE-2024-6239-0001.patch \ + file://CVE-2024-6239-0002.patch \ " SRC_URI[sha256sum] = "b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1"