Thread-unsafe initialisation of FT_Library in CairoOutputDev.cc
Constructor CairoOutputDev::CairoOutputDev
is called whenever is opened a PDF file. Opening PDF files from multiple threads can cause multiple initialisation of ft_lib
.
FT_Library CairoOutputDev::ft_lib;
bool CairoOutputDev::ft_lib_initialized = false;
CairoOutputDev::CairoOutputDev() {
doc = nullptr;
if (!ft_lib_initialized) {
FT_Init_FreeType(&ft_lib);
ft_lib_initialized = true;
}
This could cause memory leak or even something worse depending on what is doing FT_Init_FreeType
. And seems it is accessing and dereferencing its parameter multiple times instead of simply outputing FT_Library
into pointer so something really bad can happen:
FT_Init_FreeType( FT_Library *alibrary )
{
...
error = FT_New_Library( memory, alibrary );
if ( error )
FT_Done_Memory( memory );
else
FT_Add_Default_Modules( *alibrary );
FT_Set_Default_Properties( *alibrary );
There can be either used singleton with static local variable or std::call_once:
FT_Library CairoOutputDev::ft_lib;
std::once_flag CairoOutputDev::ft_lib_once_flag;
CairoOutputDev::CairoOutputDev() {
doc = nullptr;
std::call_once(ft_lib_once_flag, []()
{
FT_Init_FreeType(&ft_lib);
});
Or:
...
std::call_once(ft_lib_once_flag, FT_Init_FreeType, &ft_lib);