mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 03:00:23 +03:00
Fixed the heap-use-after-free, root cause: system fallback loading published a font under desc.family, replacing and destroying an existing same-family font while its getGlyph() call was still executing.
This commit is contained in:
@@ -147,8 +147,13 @@ FontTrueType* FontService::getOrLoadSystemFallbackFont( const FontDesc& desc ) {
|
||||
return ttf;
|
||||
}
|
||||
|
||||
// System fallbacks are implementation resources, not family-name bindings. Publishing one
|
||||
// under desc.family could replace the font whose getGlyph() call requested the fallback and
|
||||
// destroy that font while it is still executing.
|
||||
std::string resourceName =
|
||||
"@system-fallback/" + desc.path + "#" + std::to_string( desc.faceIndex );
|
||||
FontTrueTypePtr ttf =
|
||||
FontTrueType::New( desc.family, desc.path, desc.faceIndex, mResourceScope );
|
||||
FontTrueType::New( resourceName, desc.path, desc.faceIndex, mResourceScope );
|
||||
if ( !ttf || !ttf->loaded() ) {
|
||||
if ( ttf )
|
||||
mResourceScope.eraseLocalFont( ttf.get() );
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <eepp/graphics/shaderprogramregistry.hpp>
|
||||
#include <eepp/graphics/sprite.hpp>
|
||||
#include <eepp/graphics/statelistdrawable.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/graphics/textlayout.hpp>
|
||||
#include <eepp/graphics/textureatlas.hpp>
|
||||
#include <eepp/graphics/textureatlasloader.hpp>
|
||||
@@ -664,6 +665,30 @@ UTEST( ResourcePrerequisites, distinctFallbackResourcesRemainInFallbackChain ) {
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, systemFallbackDoesNotReplaceMatchingFamilyBinding ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "System fallback ownership test" );
|
||||
ResourceScopePtr scope = ResourceScope::New();
|
||||
const std::string fontPath = Sys::getProcessPath() + "assets/fonts/NotoNaskhArabic-Regular.ttf";
|
||||
FontTrueTypePtr familyFont = FontTrueType::New( "Noto Naskh Arabic", fontPath, *scope );
|
||||
ASSERT_TRUE( familyFont && familyFont->loaded() );
|
||||
FontTrueTypeWeakPtr familyFontWeak = familyFont;
|
||||
|
||||
FontDesc desc;
|
||||
desc.family = "Noto Naskh Arabic";
|
||||
desc.path = fontPath;
|
||||
FontTrueType* fallback = scope->getFontService().getOrLoadSystemFallbackFont( desc );
|
||||
ASSERT_TRUE( fallback != nullptr );
|
||||
EXPECT_NE( familyFont.get(), fallback );
|
||||
EXPECT_EQ( familyFont.get(), scope->findFont( desc.family ).get() );
|
||||
|
||||
familyFont.reset();
|
||||
EXPECT_FALSE( familyFontWeak.expired() );
|
||||
scope.reset();
|
||||
EXPECT_TRUE( familyFontWeak.expired() );
|
||||
window->display( false );
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, fontFactoriesPublishIntoExplicitScope ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "Scoped font factories test" );
|
||||
auto scope = ResourceScope::New();
|
||||
|
||||
Reference in New Issue
Block a user