From ec38f0002de74f343e808c2f5d6363003f5264e8 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 1 Feb 2024 12:53:16 +0100 Subject: [PATCH] Fix memory leak in DirectWrite backend This fixes a memory leak due to a missing call to release on the localized names in populateFamilyAliases(). The DirectWriteScope makes this automatic when it goes out of scope. We did release in the other places, but for hardening the code a bit, this also adjusts them to use the scope guard. Change-Id: I88402fad930e36cdd3a78244941fb53ca214520e Reviewed-by: Lars Knoll --- .../qwindowsdirectwritefontdatabase.cpp | 64 +++++++------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp index 499f43debbc..ed6f1ae4450 100644 --- a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp +++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp @@ -130,7 +130,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) const bool antialias = false; const int size = SMOOTH_SCALABLE; - IDWriteFontList *matchingFonts; + DirectWriteScope matchingFonts; if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, @@ -138,7 +138,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) { IDWriteFont *font; if (SUCCEEDED(matchingFonts->GetFont(j, &font))) { - IDWriteFont1 *font1 = nullptr; + DirectWriteScope font1; if (!SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1), reinterpret_cast(&font1)))) { qCWarning(lcQpaFonts) << "COM object does not support IDWriteFont1"; @@ -148,27 +148,23 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) QString defaultLocaleFamilyName; QString englishLocaleFamilyName; - IDWriteFontFamily *fontFamily2; + DirectWriteScope fontFamily2; if (SUCCEEDED(font1->GetFontFamily(&fontFamily2))) { - IDWriteLocalizedStrings *names; + DirectWriteScope names; if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) { - defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString(); - englishLocaleFamilyName = localeString(names, englishLocale); - - names->Release(); + defaultLocaleFamilyName = hasDefaultLocale ? localeString(*names, defaultLocale) : QString(); + englishLocaleFamilyName = localeString(*names, englishLocale); } - - fontFamily2->Release(); } if (defaultLocaleFamilyName.isEmpty() && englishLocaleFamilyName.isEmpty()) englishLocaleFamilyName = familyName; { - IDWriteLocalizedStrings *names; + DirectWriteScope names; if (SUCCEEDED(font1->GetFaceNames(&names))) { - QString defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString(); - QString englishLocaleStyleName = localeString(names, englishLocale); + QString defaultLocaleStyleName = hasDefaultLocale ? localeString(*names, defaultLocale) : QString(); + QString englishLocaleStyleName = localeString(*names, englishLocale); QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch()); QFont::Style style = fromDirectWriteStyle(font1->GetStyle()); @@ -177,9 +173,9 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) qCDebug(lcQpaFonts) << "Family" << familyName << "has english variant" << englishLocaleStyleName << ", in default locale:" << defaultLocaleStyleName << stretch << style << weight << fixed; - IDWriteFontFace *face = nullptr; + DirectWriteScope face; if (SUCCEEDED(font->CreateFontFace(&face))) { - QSupportedWritingSystems writingSystems = supportedWritingSystems(face); + QSupportedWritingSystems writingSystems = supportedWritingSystems(*face); if (!englishLocaleStyleName.isEmpty() || defaultLocaleStyleName.isEmpty()) { qCDebug(lcQpaFonts) << "Font" << englishLocaleFamilyName << englishLocaleStyleName << "supports writing systems:" << writingSystems; @@ -195,7 +191,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) size, fixed, writingSystems, - new FontHandle(face, englishLocaleFamilyName)); + new FontHandle(*face, englishLocaleFamilyName)); } if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) { @@ -210,22 +206,13 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName) size, fixed, writingSystems, - new FontHandle(face, defaultLocaleFamilyName)); + new FontHandle(*face, defaultLocaleFamilyName)); } - - face->Release(); } - - names->Release(); } } - - font1->Release(); - font->Release(); } } - - matchingFonts->Release(); } } @@ -306,10 +293,10 @@ bool QWindowsDirectWriteFontDatabase::populateFamilyAliases(const QString &missi DirectWriteScope font1; if (SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1), reinterpret_cast(&font1)))) { - IDWriteLocalizedStrings *names; + DirectWriteScope names; if (SUCCEEDED(font1->GetFaceNames(&names))) { wchar_t englishLocale[] = L"en-us"; - QString englishLocaleStyleName = localeString(names, englishLocale); + QString englishLocaleStyleName = localeString(*names, englishLocale); QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch()); QFont::Style style = fromDirectWriteStyle(font1->GetStyle()); @@ -747,47 +734,45 @@ void QWindowsDirectWriteFontDatabase::populateFontDatabase() DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, &fontCollection))) { for (uint i = 0; i < fontCollection->GetFontFamilyCount(); ++i) { - IDWriteFontFamily2 *fontFamily; + DirectWriteScope fontFamily; if (SUCCEEDED(fontCollection->GetFontFamily(i, &fontFamily))) { QString defaultLocaleName; QString englishLocaleName; - IDWriteLocalizedStrings *names; + DirectWriteScope names; if (SUCCEEDED(fontFamily->GetFamilyNames(&names))) { if (hasDefaultLocale) - defaultLocaleName = localeString(names, defaultLocale); + defaultLocaleName = localeString(*names, defaultLocale); - englishLocaleName = localeString(names, englishLocale); + englishLocaleName = localeString(*names, englishLocale); } qCDebug(lcQpaFonts) << "Registering font, english name = " << englishLocaleName << ", name in current locale = " << defaultLocaleName; if (!defaultLocaleName.isEmpty()) { registerFontFamily(defaultLocaleName); - m_populatedFonts.insert(defaultLocaleName, fontFamily); + m_populatedFonts.insert(defaultLocaleName, *fontFamily); fontFamily->AddRef(); if (defaultLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) { qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << defaultLocaleName; - m_populatedFonts.insert(systemDefaultFontName, fontFamily); + m_populatedFonts.insert(systemDefaultFontName, *fontFamily); fontFamily->AddRef(); } } if (!englishLocaleName.isEmpty() && englishLocaleName != defaultLocaleName) { registerFontFamily(englishLocaleName); - m_populatedFonts.insert(englishLocaleName, fontFamily); + m_populatedFonts.insert(englishLocaleName, *fontFamily); fontFamily->AddRef(); if (englishLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) { qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << englishLocaleName; - m_populatedFonts.insert(systemDefaultFontName, fontFamily); + m_populatedFonts.insert(systemDefaultFontName, *fontFamily); fontFamily->AddRef(); } } - - fontFamily->Release(); } } } @@ -812,10 +797,9 @@ QFont QWindowsDirectWriteFontDatabase::defaultFont() const bool QWindowsDirectWriteFontDatabase::supportsVariableApplicationFonts() const { QSharedPointer fontEngineData = data(); - IDWriteFactory5 *factory5 = nullptr; + DirectWriteScope factory5; if (SUCCEEDED(fontEngineData->directWriteFactory->QueryInterface(__uuidof(IDWriteFactory5), reinterpret_cast(&factory5)))) { - factory5->Release(); return true; }