Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • P poppler
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 656
    • Issues 656
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 42
    • Merge requests 42
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • poppler
  • poppler
  • Issues
  • #844

Closed
Open
Created Nov 27, 2019 by Michal@misoContributor

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);
Edited Nov 27, 2019 by Michal
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking