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;

Reply via email to