vcl/inc/sft.hxx | 4 +++- vcl/source/fontsubset/sft.cxx | 14 ++++++++++---- vcl/source/fontsubset/ttcr.cxx | 5 +++-- 3 files changed, 16 insertions(+), 7 deletions(-)
New commits: commit 2cd059c04e15678114ecbbcf1cb50467fa5a3619 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon May 5 21:10:22 2025 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue May 6 09:24:51 2025 +0200 bogus "Endless loop found in a compound glyph" warnings probably since: commit 3a371df3ecce456c9329a493f48600431d2ade69 CommitDate: Wed Mar 2 12:56:25 2022 +0100 ofz: detect endless loop in font processing I see this on e.g. export of forum-mso-en4-726282.xlsx to pdf and with the original guard disabled there isn't an endless loop or recursion. Adjust this to explicitly check what I believe was the original issue. Change-Id: I9d7bd5f7c24e6ae1ae06d61725a5fad45a2326ad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184971 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx index 0a2697c3e062..df390ec4fad3 100644 --- a/vcl/inc/sft.hxx +++ b/vcl/inc/sft.hxx @@ -536,7 +536,9 @@ class TrueTypeFont; * @ingroup sft * */ - int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< sal_uInt32 >& glyphlist); + int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, + std::vector<sal_uInt32>& glyphlist, + std::vector<sal_uInt32>& currentGlyphStack); /** * Extracts all Name Records from the font and stores them in an allocated diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 4d8a316feb20..10b2f6fc3c2b 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -1239,7 +1239,9 @@ int GetTTGlyphPoints(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< return GetTTGlyphOutline(ttf, glyphID, pointArray, nullptr, nullptr); } -int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< sal_uInt32 >& glyphlist) +int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, + std::vector<sal_uInt32>& glyphlist, + std::vector<sal_uInt32>& currentGlyphStack) { int n = 1; @@ -1257,9 +1259,9 @@ int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vec if (nOffset > nNextOffset) return 0; - if (std::find(glyphlist.begin(), glyphlist.end(), glyphID) != glyphlist.end()) + if (std::find(currentGlyphStack.begin(), currentGlyphStack.end(), glyphID) != currentGlyphStack.end()) { - SAL_WARN("vcl.fonts", "Endless loop found in a compound glyph."); + SAL_WARN("vcl.fonts", "Endless glyph chain found in a compound glyph."); return 0; } @@ -1269,6 +1271,8 @@ int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vec if (nOffset == nNextOffset) return n; + currentGlyphStack.push_back(glyphID); + const auto* ptr = glyf + nOffset; sal_uInt32 nRemainingData = glyflength - nOffset; @@ -1287,7 +1291,7 @@ int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vec ptr += 4; nRemainingData -= 4; - n += GetTTGlyphComponents(ttf, index, glyphlist); + n += GetTTGlyphComponents(ttf, index, glyphlist, currentGlyphStack); sal_uInt32 nAdvance; if (flags & ARG_1_AND_2_ARE_WORDS) { @@ -1313,6 +1317,8 @@ int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vec } while (flags & MORE_COMPONENTS); } + currentGlyphStack.pop_back(); + return n; } diff --git a/vcl/source/fontsubset/ttcr.cxx b/vcl/source/fontsubset/ttcr.cxx index e2095f987338..53673ad36f3f 100644 --- a/vcl/source/fontsubset/ttcr.cxx +++ b/vcl/source/fontsubset/ttcr.cxx @@ -802,9 +802,10 @@ sal_uInt32 TrueTypeTableGlyf::glyfAdd(std::unique_ptr<GlyphData> glyphdata, Abst if (!glyphdata) return sal_uInt32(~0); - std::vector< sal_uInt32 > glyphlist; + std::vector<sal_uInt32> glyphlist; + std::vector<sal_uInt32> currentGlyphStack; - ncomponents = GetTTGlyphComponents(fnt, glyphdata->glyphID, glyphlist); + ncomponents = GetTTGlyphComponents(fnt, glyphdata->glyphID, glyphlist, currentGlyphStack); if (m_list.size() > 0) { ret = n = m_list.back()->newID + 1;