src/fccfg.c | 28 ++-------------------------- src/fcint.h | 3 +++ src/fcstr.c | 24 ++++++++++++++++++++++++ src/fcxml.c | 9 ++++++++- 4 files changed, 37 insertions(+), 27 deletions(-) New commits: commit 1d7669992798bb7fec7dc613c05310741d7b3781 Author: Akira TAGOH <akira@xxxxxxxxx> Date: Mon Oct 11 18:35:58 2021 +0900 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 diff --git a/src/fccfg.c b/src/fccfg.c index 21fc9b1..eb174a4 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -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; } diff --git a/src/fcint.h b/src/fcint.h index f7141c1..d6d44b0 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -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); diff --git a/src/fcstr.c b/src/fcstr.c index 765f711..3fe518f 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -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) { diff --git a/src/fcxml.c b/src/fcxml.c index 83019c0..33af948 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -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); + FcChar8 *p = FcStrRealPath (parse->name); + + if (!p) + return NULL; + parent = FcStrDirname (p); if (!parent) + { + free (p); return NULL; + } } } #ifndef _WIN32