mono / libgdiplus

C-based implementation of the GDI+ API
http://www.mono-project.com/
MIT License
329 stars 171 forks source link

GdipPrivateAddMemoryFont does not clean up temporary files #690

Open trungnt2910 opened 3 years ago

trungnt2910 commented 3 years ago

Trying to use a C# application that calls System.PrivateFontCollection.AddMemoryFont on Linux leaves a bunch of unused font files in the tmp folder, even after calling Dispose.

Most functions in Mono's PrivateFontCollection are simply wrappers to libgdiplus calls, so I guess the bug originates from here.

Digging through the source code, it seems that this piece of code here is responsible:

#ifdef WIN32
    f = CreateTempFile (fontfile);
    if (!f)
        return FileNotFound;

    if (fwrite(memory, sizeof(BYTE), length, f) != length) {
        fclose (f);
        return FileNotFound;
    }

    fclose (f);
#else
    strcpy ((char *) fontfile, "/tmp/ffXXXXXX");
    f = mkstemp ((char *) fontfile);

    if (f == -1)
        return FileNotFound;

    if (write (f, memory, length) != length) {
        close (f);
        return FileNotFound;
    }
    close (f);
#endif

    FcConfigAppFontAddFile (fontCollection->config, fontfile);
    /* FIXME - May we delete our temporary font file or does 
       FcConfigAppFontAddFile just reference our file?  */
    /* unlink(fontfile); */

    return Ok;

After research, at least on my Ubuntu 20.04 machine, FcConfigAppFontAddFile simply references that file, deleting the font makes the app crash when a new Form or Control is drawn. However, the function does not seem to save the temp files anywhere.