[Fontconfig] FcConfigNormalizeFontDir considered harmful

Patrick Lam plam at MIT.EDU
Sun Aug 27 21:34:11 PDT 2006


Keith Packard wrote:
> In looking at this code, it's reading every directory in the font
> hierarchy and stat'ing every file. That's a lot of what the font caches
> are supposed to avoid; all of those syscalls at application startup.
> 
> I'm trying to figure out what we're attempting here; the old cache code
> would already infinite loop if the font directories had circular
> symlinks, so this isn't necessary from a robustness perspective.
> 
> If the only thing the code is for is to eliminate duplicate caches for
> the same directory reached by multiple paths, then I don't think that's
> necessary either; again, the old code would have loaded the caches twice
> in that case.
> 
> I think we can just eliminate the path normalization entirely.
> Arguments?

I think that path normalization needs to run at least on strings that
are input to fc-cache.  For instance, `fc-cache .' is going to create a
cache file which claims to be for the directory .; not quite what we want.

Normalization definitely avoids infinite loops in the presence of
circular symlinks, which is nice behaviour, but doesn't justify scanning
all cache dirs on all fontconfig clients.  See below in the discussion
of FcCacheReadDirs.

However, the original motivation for FcConfigNormalizeFontDir was the
multiple path problem.  Not loading caches multiple times, but at least
having incorrect names for directories and then putting them in the
global cache.  I'm not sure that we need to run FcConfigNormalizeFontDir
on startup to avoid that.

Since the global cache goes away, then all of the NormalizeFontDir uses
in global cache code go away anyway.  That leaves calls in
FcDirCacheUnlink, FcCacheReadDirs, FcDirCacheWrite, and FcDirScanConfig
(aside from the call in fc-cache/fc-cache.c).

There was some trickiness in calls to FcDirCacheUnlink due to multi-arch
cache files.  Separating cache files on a per-arch basis will make that
problem go away; after we separate them, then we can preemptively blow
away cache files and nothing bad will happen.

The call in FcCacheReadDirs seems a bit strange.  One might
want to normalize before calling FcConfigAcceptFilename to make sure
that the masks do the right thing (they didn't in 2.3.2), because we can
require that masks must be on canonical filenames (as stated in the
<dir> entries).  But that's not what happens right now.  And otherwise,
the arguments to FcCacheReadDirs should be, by definition, normalized,
since they come from the <dir> entries in the config file.  So the call
there just seems to prevent infinite loops, as per bug 2667 (and 4754).

FcDirCacheWrite is only called from fc-cache.  It's probably redundant
due to the call in fc-cache itself.

Now FcDirScanConfig might create global caches with incorrect names if
the paths are not normalized.  I haven't analyzed that case yet, but it
seems like it could be potentially bad.

pat


More information about the Fontconfig mailing list