From 11344f57235b5c8149d231c1331f86bcff51bd50 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Jan 2024 09:51:55 +0100 Subject: [PATCH] windows: Avoid infinite recursion with certain fonts Amends 922d195020d54d7e599d135f6a5e0338100e08f1. Another infinite recursion was found in the case of populating font families for cases where the typographical name is different from the populated name. The specific font triggering this had two "preferred name" entries in its name data. This was one for Chinese (PRC) and another for Chinese (Taiwan). Our GDI backend does not do matching based on locale, but will prefer the English if available, otherwise it will just pick the first one. The font in question does not have the English preferred name. For this particular font, we would select the Chinese (Taiwan) name as preferred and since it had not been populated, we would populate this. However, on Chinese (PRC) locale, Windows would report this according to the Chinese (PRC) name. We would once again translate this to Chinese (Taiwan) and go into an infinite recursion populating it. The quick fix is to mark the preferred family as populated before entering the recursion, so that we do not re-populate it a second time later. Ideally, the font database would match the preferred name based on locale, but since we are moving away from the GDI font database and this is already handled better with the DirectWrite database, just fixing the recursion is sufficient here. [ChangeLog][Windows] Fixed an issue where an infinite recursion could occur if the system had a font with multiple preferred names in non-English languages. Pick-to: 5.15 6.2 6.5 6.6 6.7 Fixes: QTBUG-118238 Change-Id: I6ded369f1c908e51c0ba2ad9127538faf07e192e Reviewed-by: Lars Knoll Reviewed-by: Liang Qi --- src/gui/text/windows/qwindowsfontdatabase.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp index ef516068a7a..51254f7727b 100644 --- a/src/gui/text/windows/qwindowsfontdatabase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabase.cpp @@ -552,19 +552,11 @@ static bool addFontToDatabase(QString familyName, writingSystems.setSupported(ws); } - // We came here from populating a different font family, so we have - // to ensure the entire typographic family is populated before we - // mark it as such inside registerFont() - if (!subFamilyName.isEmpty() - && familyName != subFamilyName - && sfp->populatedFontFamily != familyName - && !QPlatformFontDatabase::isFamilyPopulated(familyName)) { - sfp->windowsFontDatabase->populateFamily(familyName); - } - + const bool wasPopulated = QPlatformFontDatabase::isFamilyPopulated(familyName); QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); + // add fonts windows can generate for us: if (weight <= QFont::DemiBold && styleName.isEmpty()) QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, @@ -576,6 +568,16 @@ static bool addFontToDatabase(QString familyName, QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); + // We came here from populating a different font family, so we have + // to ensure the entire typographic family is populated before we + // mark it as such inside registerFont() + if (!subFamilyName.isEmpty() + && familyName != subFamilyName + && sfp->populatedFontFamily != familyName + && !wasPopulated) { + sfp->windowsFontDatabase->populateFamily(familyName); + } + if (!subFamilyName.isEmpty() && familyName != subFamilyName) { QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName));