Resolves symlinks against <dir prefix="relative">

When a config file is symlinked and obtaining an relative path from it for <dir>,
it behaved like:

$ realpath /path/to/foo.conf
/path/to/realpath/foo.conf
$ FONTCONFIG_FILE=/path/to/foo.conf fc-cache -v
Font directories:
        /path/to/fonts
/path/to/fonts: skipping, existing cache is valid: 1 fonts, 0 dirs
/path/to/cachedir: cleaning cache directory
fc-cache: succeeded

And after this change:

$ FONTCONFIG_FILE=/path/to/foo.conf fc-cache -v
Font directories:
        /path/to/relpath/fonts
/path/to/realpath/fonts: skipping, existing cache is valid: 1 fonts, 0 dirs
/path/to/cachedir: cleaning cache directory
fc-cache: succeeded

Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/290
This commit is contained in:
Akira TAGOH 2021-10-11 18:35:58 +09:00
parent 2d17232a45
commit 1d76699927
4 changed files with 38 additions and 28 deletions

View File

@ -131,30 +131,6 @@ FcConfigFini (void)
free_lock ();
}
static FcChar8 *
FcConfigRealPath(const FcChar8 *path)
{
char resolved_name[FC_PATH_MAX+1];
char *resolved_ret;
if (!path)
return NULL;
#ifndef _WIN32
resolved_ret = realpath((const char *) path, resolved_name);
#else
if (GetFullPathNameA ((LPCSTR) path, FC_PATH_MAX, resolved_name, NULL) == 0)
{
fprintf (stderr, "Fontconfig warning: GetFullPathNameA failed.\n");
return NULL;
}
resolved_ret = resolved_name;
#endif
if (resolved_ret)
path = (FcChar8 *) resolved_ret;
return FcStrCopyFilename(path);
}
FcConfig *
FcConfigCreate (void)
{
@ -221,7 +197,7 @@ FcConfigCreate (void)
config->expr_pool = NULL;
config->sysRoot = FcConfigRealPath((const FcChar8 *) getenv("FONTCONFIG_SYSROOT"));
config->sysRoot = FcStrRealPath ((const FcChar8 *) getenv("FONTCONFIG_SYSROOT"));
config->rulesetList = FcPtrListCreate (FcDestroyAsRuleSet);
if (!config->rulesetList)
@ -3048,7 +3024,7 @@ retry:
if (sysroot)
{
s = FcConfigRealPath(sysroot);
s = FcStrRealPath (sysroot);
if (!s)
return;
}

View File

@ -1345,6 +1345,9 @@ FcStrHashIgnoreCase (const FcChar8 *s);
FcPrivate FcChar32
FcStrHashIgnoreBlanksAndCase (const FcChar8 *s);
FcPrivate FcChar8 *
FcStrRealPath (const FcChar8 *path);
FcPrivate FcChar8 *
FcStrCanonFilename (const FcChar8 *s);

View File

@ -1091,6 +1091,30 @@ FcStrBasename (const FcChar8 *file)
return FcStrCopy (slash + 1);
}
FcChar8 *
FcStrRealPath (const FcChar8 *path)
{
char resolved_name[FC_PATH_MAX+1];
char *resolved_ret;
if (!path)
return NULL;
#ifndef _WIN32
resolved_ret = realpath((const char *) path, resolved_name);
#else
if (GetFullPathNameA ((LPCSTR) path, FC_PATH_MAX, resolved_name, NULL) == 0)
{
fprintf (stderr, "Fontconfig warning: GetFullPathNameA failed.\n");
return NULL;
}
resolved_ret = resolved_name;
#endif
if (resolved_ret)
path = (FcChar8 *) resolved_ret;
return FcStrCopyFilename(path);
}
static FcChar8 *
FcStrCanonAbsoluteFilename (const FcChar8 *s)
{

View File

@ -1318,9 +1318,16 @@ _get_real_paths_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcC
}
else if (FcStrCmp (prefix, (const FcChar8 *) "relative") == 0)
{
parent = FcStrDirname (parse->name);
if (!parent)
FcChar8 *p = FcStrRealPath (parse->name);
if (!p)
return NULL;
parent = FcStrDirname (p);
if (!parent)
{
free (p);
return NULL;
}
}
}
#ifndef _WIN32