From f468f568b4aedef1606b0692addf47cb9f02b328 Mon Sep 17 00:00:00 2001 From: Patrick Lam Date: Thu, 26 Jan 2006 16:09:12 +0000 Subject: [PATCH] Stop trampling the directory name when writing out caches. (with Mike Fabian:) Beef up FcConfigNormalizeFontDir to scan subdirs when necessary. Don't scan directories that can't be normalized. --- ChangeLog | 11 +++++++++++ src/fccache.c | 16 +++++++++++++--- src/fccfg.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/fcdir.c | 6 +++++- src/fcxml.c | 2 +- 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cad05d3..328b0fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-01-26 Patirck Lam + * src/fccache.c (FcGlobalCacheSave, FcDirCacheWrite): + * src/fccfg.c (FcConfigAddFontDirSubdirs, FcConfigNormalizeFontDir): + * src/fcdir.c (FcDirScanConfig): + * src/fcxml.c (FcEndElement): + + Stop trampling the directory name when writing out caches. + (with Mike Fabian:) Beef up FcConfigNormalizeFontDir to scan + subdirs when necessary. Don't scan directories that can't be + normalized. + 2006-01-25 Patrick Lam * src/fccache.c (FcDirCacheOpen, FcDirCacheWrite): * src/fccfg.c (FcConfigEvaluate): diff --git a/src/fccache.c b/src/fccache.c index 742e9aa..349bc9a 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -382,6 +382,7 @@ FcGlobalCacheSave (FcGlobalCache *cache, S_IRUSR | S_IWUSR); if (fd == -1) goto bail2; + FcCacheWriteString (fd, FC_GLOBAL_MAGIC_COOKIE); fd_orig = open ((char *) FcAtomicOrigFile(atomic), O_RDONLY); @@ -393,7 +394,12 @@ FcGlobalCacheSave (FcGlobalCache *cache, current_arch_machine_name); if (current_arch_start < 0) - current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END)); + { + off_t i = lseek(fd_orig, 0, SEEK_END); + if (i < strlen (FC_GLOBAL_MAGIC_COOKIE)+1) + i = strlen (FC_GLOBAL_MAGIC_COOKIE)+1; + current_arch_start = FcCacheNextOffset (i); + } if (!FcCacheCopyOld(fd, fd_orig, current_arch_start)) goto bail3; @@ -419,7 +425,6 @@ FcGlobalCacheSave (FcGlobalCache *cache, } truncate_to -= current_arch_start; - FcCacheWriteString (fd, FC_GLOBAL_MAGIC_COOKIE); sprintf (header, "%8x ", (int)truncate_to); strcat (header, current_arch_machine_name); if (!FcCacheWriteString (fd, header)) @@ -1159,7 +1164,12 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) FcCacheSkipToArch(fd_orig, current_arch_machine_name); if (current_arch_start < 0) - current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END)); + { + off_t i = lseek(fd_orig, 0, SEEK_END); + if (i < strlen (FC_GLOBAL_MAGIC_COOKIE)+1) + i = strlen (FC_GLOBAL_MAGIC_COOKIE)+1; + current_arch_start = FcCacheNextOffset (i); + } if (fd_orig != -1 && !FcCacheCopyOld(fd, fd_orig, current_arch_start)) goto bail4; diff --git a/src/fccfg.c b/src/fccfg.c index 2135d67..6e5174b 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -22,6 +22,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include +#include #include "fcint.h" #if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT)) @@ -388,6 +390,41 @@ FcConfigAddFontDir (FcConfig *config, return FcStrSetAddFilename (config->fontDirs, d); } +static FcBool +FcConfigAddFontDirSubdirs (FcConfig *config, + const FcChar8 *d) +{ + DIR *dir; + struct dirent *e; + FcChar8 *subdir; + + if (!(dir = opendir ((char *) d))) + return FcFalse; + if (!(subdir = (FcChar8 *) malloc (strlen ((char *) d) + FC_MAX_FILE_LEN + 2))) + { + fprintf (stderr, "out of memory"); + return FcFalse; + } + while ((e = readdir (dir))) + { + if (strcmp (e->d_name, ".") && strcmp (e->d_name, "..") && + strlen (e->d_name) < FC_MAX_FILE_LEN) + { + strcpy ((char *)subdir, (char *)d); + strcat ((char *)subdir, "/"); + strcat ((char *)subdir, e->d_name); + if (FcFileIsDir (subdir)) + { + FcConfigAddFontDir (config, subdir); + FcConfigAddFontDirSubdirs (config, subdir); + } + } + } + free (subdir); + closedir (dir); + return FcTrue; +} + const FcChar8 * FcConfigNormalizeFontDir (FcConfig *config, const FcChar8 *d) @@ -409,6 +446,21 @@ FcConfigNormalizeFontDir (FcConfig *config, if (di == s.st_ino && dd == s.st_dev) return config->fontDirs->strs[n]; } + + /* Ok, we didn't find it in fontDirs; let's add subdirs.... */ + for (n = 0; n < config->fontDirs->num; n++) + FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]); + + /* ... and try again. */ + for (n = 0; n < config->fontDirs->num; n++) + { + if (stat ((char *)config->fontDirs->strs[n], &s) == -1) + continue; + if (di == s.st_ino && dd == s.st_dev) + return config->fontDirs->strs[n]; + } + + /* if it fails, then really give up. */ return 0; } diff --git a/src/fcdir.c b/src/fcdir.c index 6db0b8b..adb39fb 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -132,7 +132,11 @@ FcDirScanConfig (FcFontSet *set, return FcTrue; if (config) - FcConfigAddFontDir (config, dir); + dir = FcConfigNormalizeFontDir (config, dir); + + /* refuse to scan a directory that can't be normalized. */ + if (!dir) + return FcFalse; if (!force) { diff --git a/src/fcxml.c b/src/fcxml.c index 0aaec1d..e65ccbf 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -2050,7 +2050,7 @@ FcEndElement(void *userData, const XML_Char *name) if (!FcStrUsesHome (data) || FcConfigHome ()) { if (!FcConfigAddDir (parse->config, data)) - FcConfigMessage (parse, FcSevereError, "out of memory"); + FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data); } FcStrFree (data); break;