Return canonicalized paths from FcConfigRealFilename
FcConfigRealFilename() follows symlinks, but the link may be relative to the
directory containing the link. For example, on my system, I have this file:
/etc/fonts/conf.d/99-language-selector-zh.conf ->
../conf.avail/99-language-selector-zh.conf
Since /etc/fonts/conf.d is probably not in PATH, open()ing the file would fail.
This change makes FcConfigRealFilename() return the canonicalized filename
instead. So for the example above, it would return:
/etc/fonts/conf.avail/99-language-selector-zh.conf
This was causing bad font rendering in Chromium [1] after the regression I
introduced in 7ad010e80b
.
[1] https://bugs.chromium.org/p/chromium/issues/detail?id=857511
This commit is contained in:
parent
48e9e5f4f0
commit
d1f48f11d5
65
src/fccfg.c
65
src/fccfg.c
|
@ -2191,42 +2191,28 @@ FcConfigFilename (const FcChar8 *url)
|
|||
}
|
||||
file = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (isalpha (*url) &&
|
||||
url[1] == ':' &&
|
||||
(url[2] == '/' || url[2] == '\\'))
|
||||
goto absolute_path;
|
||||
#endif
|
||||
if (FcStrIsAbsoluteFilename(url))
|
||||
return FcConfigFileExists (0, url);
|
||||
|
||||
switch (*url) {
|
||||
case '~':
|
||||
if (*url == '~')
|
||||
{
|
||||
dir = FcConfigHome ();
|
||||
if (dir)
|
||||
file = FcConfigFileExists (dir, url + 1);
|
||||
else
|
||||
file = 0;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case '\\':
|
||||
absolute_path:
|
||||
#endif
|
||||
case '/':
|
||||
file = FcConfigFileExists (0, url);
|
||||
break;
|
||||
default:
|
||||
path = FcConfigGetPath ();
|
||||
if (!path)
|
||||
return NULL;
|
||||
for (p = path; *p; p++)
|
||||
{
|
||||
file = FcConfigFileExists (*p, url);
|
||||
if (file)
|
||||
break;
|
||||
}
|
||||
FcConfigFreePath (path);
|
||||
break;
|
||||
}
|
||||
|
||||
path = FcConfigGetPath ();
|
||||
if (!path)
|
||||
return NULL;
|
||||
for (p = path; *p; p++)
|
||||
{
|
||||
file = FcConfigFileExists (*p, url);
|
||||
if (file)
|
||||
break;
|
||||
}
|
||||
FcConfigFreePath (path);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
@ -2252,8 +2238,27 @@ FcConfigRealFilename (FcConfig *config,
|
|||
if ((len = FcReadLink (nn, buf, sizeof (buf) - 1)) != -1)
|
||||
{
|
||||
buf[len] = 0;
|
||||
FcStrFree (nn);
|
||||
nn = FcStrdup (buf);
|
||||
|
||||
if (!FcStrIsAbsoluteFilename (buf))
|
||||
{
|
||||
FcChar8 *dirname = FcStrDirname (nn);
|
||||
FcStrFree (nn);
|
||||
if (!dirname)
|
||||
return NULL;
|
||||
|
||||
FcChar8 *path = FcStrBuildFilename (dirname, buf, NULL);
|
||||
FcStrFree (dirname);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
nn = FcStrCanonFilename (path);
|
||||
FcStrFree (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
FcStrFree (nn);
|
||||
nn = FcStrdup (buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1279,6 +1279,9 @@ FcStrGlobMatch (const FcChar8 *glob,
|
|||
FcPrivate FcBool
|
||||
FcStrUsesHome (const FcChar8 *s);
|
||||
|
||||
FcPrivate FcBool
|
||||
FcStrIsAbsoluteFilename (const FcChar8 *s);
|
||||
|
||||
FcPrivate FcChar8 *
|
||||
FcStrBuildFilename (const FcChar8 *path,
|
||||
...);
|
||||
|
|
11
src/fcstr.c
11
src/fcstr.c
|
@ -867,6 +867,17 @@ FcStrUsesHome (const FcChar8 *s)
|
|||
return *s == '~';
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcStrIsAbsoluteFilename (const FcChar8 *s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (*s == '\\' ||
|
||||
(isalpha (*s) && s[1] == ':' && (s[2] == '/' || s[2] == '\\'))
|
||||
return FcTrue;
|
||||
#endif
|
||||
return *s == '/';
|
||||
}
|
||||
|
||||
FcChar8 *
|
||||
FcStrBuildFilename (const FcChar8 *path,
|
||||
...)
|
||||
|
|
Loading…
Reference in New Issue