From c1c3ba06d5f5e00a1bfef4ef0dbf10f28fa86ce2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 27 Apr 2006 07:11:44 +0000 Subject: [PATCH] Make path names in cache files absolute (NB, cache format change) Stop permitting cache files to be stored in font dirs. Bump cache magic. Don't include /fonts.cache-2 in cache hash construction. reviewed by: Patrick Lam --- ChangeLog | 30 +++++++++++ src/fccache.c | 104 +++++++++---------------------------- src/fcfreetype.c | 10 +--- src/fcint.h | 8 +-- src/fclist.c | 4 -- src/fcmatch.c | 3 -- src/fcpat.c | 130 ----------------------------------------------- 7 files changed, 57 insertions(+), 232 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b990bf..153fb9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2006-04-27 Keith Packard + + reviewed by: Patrick Lam + + * src/fccache.c: (FcDirCacheUnlink), (FcDirCacheHashName), + (FcDirCacheOpen), (FcDirCacheWrite): + * src/fcfreetype.c: (FcFreeTypeQuery): + * src/fcint.h: + * src/fclist.c: (FcListAppend): + * src/fcmatch.c: (FcFontRenderPrepare): + * src/fcpat.c: (FcPatternDestroy), (FcPatternBaseFreeze), + (FcPatternFreeze), (FcPatternGet), (FcPatternDuplicate), + (FcStrUnserialize): + Make path names in cache files absolute (NB, cache format change) + Stop permitting cache files to be stored in font dirs. + Bump cache magic. + Don't include /fonts.cache-2 in cache hash construction. + +2006-04-26 Keith Packard + + * src/fccache.c: (FcDirCacheUnlink), (FcDirCacheOpen), + (FcDirCacheWrite): + * src/fcfreetype.c: (FcFreeTypeQuery): + * src/fcint.h: + * src/fclist.c: (FcListAppend): + * src/fcmatch.c: (FcFontRenderPrepare): + * src/fcpat.c: (FcPatternDestroy), (FcPatternBaseFreeze), + (FcPatternFreeze), (FcPatternGet), (FcPatternDuplicate), + (FcStrUnserialize): + 2006-04-25 Patrick Lam * ChangeLog: * README: diff --git a/src/fccache.c b/src/fccache.c index 7467f2d..5cb49bd 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -48,7 +48,7 @@ static int FcDirCacheOpen (const FcChar8 * dir); static char * -FcDirCacheHashName (char * cache_file, int collisions); +FcDirCacheHashName (const FcChar8 * dir, int collisions); static off_t FcCacheSkipToArch (int fd, const char * arch); @@ -828,29 +828,21 @@ FcDirCacheHasCurrentArch (const FcChar8 *dir) FcBool FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) { - char *cache_file; char *cache_hashed = 0; int fd, collisions; struct stat cache_stat; - char name_buf[FC_MAX_FILE_LEN]; + char dir_buf[FC_MAX_FILE_LEN]; dir = FcConfigNormalizeFontDir (config, dir); - cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); - if (!cache_file) - return FcFalse; - - /* First remove normal cache file. */ - if (stat ((char *) cache_file, &cache_stat) == 0) - unlink ((char *)cache_file); - /* Next remove any applicable hashed files. */ + /* Remove any applicable hashed files. */ fd = -1; collisions = 0; do { if (cache_hashed) FcStrFree ((FcChar8 *)cache_hashed); - cache_hashed = FcDirCacheHashName (cache_file, collisions++); + cache_hashed = FcDirCacheHashName (dir, collisions++); if (!cache_hashed) goto bail; @@ -860,16 +852,15 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) if (fd == -1) { FcStrFree ((FcChar8 *)cache_hashed); - FcStrFree ((FcChar8 *)cache_file); return FcTrue; } - if (!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || !strlen(name_buf)) + if (!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) || !strlen(dir_buf)) { FcStrFree ((FcChar8 *)cache_hashed); goto bail; } - } while (strcmp (name_buf, cache_file) != 0); + } while (strcmp ((char *) dir_buf, (char *) dir) != 0); close (fd); @@ -880,12 +871,10 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) goto bail; } - FcStrFree ((FcChar8 *)cache_file); FcStrFree ((FcChar8 *)cache_hashed); return FcTrue; bail: - FcStrFree ((FcChar8 *)cache_file); return FcFalse; } @@ -1024,7 +1013,7 @@ static const char bin2hex[] = { '0', '1', '2', '3', 'c', 'd', 'e', 'f' }; static char * -FcDirCacheHashName (char * cache_file, int collisions) +FcDirCacheHashName (const FcChar8 * dir, int collisions) { unsigned char hash[16], hex_hash[33]; char *cache_hashed; @@ -1034,7 +1023,7 @@ FcDirCacheHashName (char * cache_file, int collisions) struct MD5Context ctx; MD5Init (&ctx); - MD5Update (&ctx, (unsigned char *)cache_file, strlen (cache_file)); + MD5Update (&ctx, (unsigned char *)dir, strlen ((char *) dir)); for (i = 0; i < collisions; i++) MD5Update (&ctx, &uscore, 1); @@ -1066,60 +1055,40 @@ FcDirCacheOpen (const FcChar8 *dir) { FcBool found; int fd = -1, collisions = 0; - char *cache_file, *cache_hashed; - char name_buf[FC_MAX_FILE_LEN]; + char *cache_hashed; + char dir_buf[FC_MAX_FILE_LEN]; struct stat dir_stat; if (stat ((char *)dir, &dir_stat) == -1) return -1; - cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); - if (!cache_file) - return -1; - found = FcFalse; do { struct stat c; - FcChar8 *name_buf_dir; if (fd >= 0) close (fd); - cache_hashed = FcDirCacheHashName (cache_file, collisions++); + cache_hashed = FcDirCacheHashName (dir, collisions++); if (!cache_hashed) - { - FcStrFree ((FcChar8 *)cache_file); return -1; - } fd = open(cache_hashed, O_RDONLY | O_BINARY); FcStrFree ((FcChar8 *)cache_hashed); if (fd == -1) break; - if (!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || - !strlen(name_buf)) + if (!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) || + !strlen(dir_buf)) break; - name_buf_dir = FcStrDirname ((FcChar8 *)name_buf); - if (stat ((char *)name_buf_dir, &c) == -1) - { - FcStrFree (name_buf_dir); + if (stat ((char *)dir_buf, &c) == -1) continue; - } - FcStrFree (name_buf_dir); + found = (c.st_ino == dir_stat.st_ino) && (c.st_dev == dir_stat.st_dev); } while (!found); - if (!found || fd < 0) - { - if (fd >= 0) - close (fd); - fd = open(cache_file, O_RDONLY | O_BINARY); - } - - FcStrFree ((FcChar8 *)cache_file); return fd; } @@ -1311,13 +1280,12 @@ FcDirCacheProduce (FcFontSet *set, FcCache *metadata) FcBool FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) { - char *cache_file; char *cache_hashed; int fd, fd_orig, i, dirs_count; FcAtomic *atomic; FcCache metadata; off_t current_arch_start = 0, truncate_to; - char name_buf[FC_MAX_FILE_LEN]; + char dir_buf[FC_MAX_FILE_LEN]; int collisions; char *current_arch_machine_name, * header; @@ -1327,17 +1295,13 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) if (!dir) return FcFalse; - cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); - if (!cache_file) - goto bail; - /* Ensure that we're not trampling a cache for some other dir. */ /* This is slightly different from FcDirCacheOpen, since it * needs the filename, not the file descriptor. */ fd = -1; collisions = 0; do { - cache_hashed = FcDirCacheHashName (cache_file, collisions++); + cache_hashed = FcDirCacheHashName (dir, collisions++); if (!cache_hashed) goto bail0; @@ -1346,7 +1310,7 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) fd = open(cache_hashed, O_RDONLY | O_BINARY); if (fd == -1) break; - if(!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || !strlen(name_buf)) + if(!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) || !strlen(dir_buf)) { close (fd); FcStrFree ((FcChar8 *)cache_hashed); @@ -1354,7 +1318,7 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) } close (fd); - if (strcmp (name_buf, cache_file) != 0) + if (strcmp (dir_buf, (char *) dir) != 0) { FcStrFree ((FcChar8 *)cache_hashed); continue; @@ -1369,38 +1333,24 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) goto bail1; if (FcDebug () & FC_DBG_CACHE) - printf ("FcDirCacheWriteDir cache_file \"%s\"\n", cache_file); + printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n", + dir, cache_hashed); atomic = FcAtomicCreate ((FcChar8 *)cache_hashed); if (!atomic) goto bail1; if (!FcAtomicLock (atomic)) - { - /* Now try rewriting the original version of the file. */ - FcAtomicDestroy (atomic); - - atomic = FcAtomicCreate ((FcChar8 *)cache_file); - fd_orig = open (cache_file, O_RDONLY | O_BINARY); - if (fd_orig == -1) - fd_orig = open((char *)FcAtomicOrigFile (atomic), O_RDONLY | O_BINARY); - - fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); - if (fd == -1) - goto bail2; - } + goto bail2; - /* In all cases, try opening the real location of the cache file first. */ - /* (even if that's not atomic.) */ - fd_orig = open (cache_file, O_RDONLY | O_BINARY); - if (fd_orig == -1) - fd_orig = open((char *)FcAtomicOrigFile (atomic), O_RDONLY | O_BINARY); + /* open the original file to save relevant portions */ + fd_orig = open((char *)FcAtomicOrigFile (atomic), O_RDONLY | O_BINARY); fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); if (fd == -1) goto bail3; - FcCacheWriteString (fd, cache_file); + FcCacheWriteString (fd, (char *) dir); current_arch_machine_name = FcCacheMachineSignature (); current_arch_start = 0; @@ -1489,7 +1439,6 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) if (!FcAtomicReplaceOrig(atomic)) goto bail3; FcStrFree ((FcChar8 *)cache_hashed); - FcStrFree ((FcChar8 *)cache_file); FcAtomicUnlock (atomic); FcAtomicDestroy (atomic); return FcTrue; @@ -1505,11 +1454,8 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) bail1: FcStrFree ((FcChar8 *)cache_hashed); bail0: - unlink ((char *)cache_file); - FcStrFree ((FcChar8 *)cache_file); if (current_dir_block) free (current_dir_block); - bail: return FcFalse; } diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 9eb591e..2cab48a 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -997,7 +997,6 @@ FcFreeTypeQuery (const FcChar8 *file, FcChar8 *family = 0; #endif FcChar8 *complex; - FcChar8 *file2; const FcChar8 *foundry = 0; int spacing; TT_OS2 *os2; @@ -1278,15 +1277,8 @@ FcFreeTypeQuery (const FcChar8 *file, printf ("Saving unique fullname %s\n", full); } - file2 = FcStrCopy (file); - if (!FcPatternAddString (pat, FC_FILE, FcStrBasename(file2))) - { - FcStrFree (file2); + if (!FcPatternAddString (pat, FC_FILE, file)) goto bail1; - } - FcStrFree (file2); - - FcPatternAddFullFname (pat, (const char *)FcStrCopy (file)); if (!FcPatternAddInteger (pat, FC_INDEX, id)) goto bail1; diff --git a/src/fcint.h b/src/fcint.h index 61a0517..ae348b8 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -333,7 +333,7 @@ typedef struct _FcCaseFold { * cache which is then rewritten to the users home directory */ -#define FC_CACHE_MAGIC 0xFC02FC03 +#define FC_CACHE_MAGIC 0xFC02FC04 typedef struct _FcGlobalCacheDir FcGlobalCacheDir; @@ -871,12 +871,6 @@ FcPatternFini (void); FcBool FcPatternAppend (FcPattern *p, FcPattern *s); -void -FcPatternAddFullFname (const FcPattern *p, const char *fname); - -void -FcPatternTransferFullFname (const FcPattern *new, const FcPattern *orig); - const FcChar8 * FcStrStaticName (const FcChar8 *name); diff --git a/src/fclist.c b/src/fclist.c index 452268b..9aef842 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -422,10 +422,6 @@ FcListAppend (FcListHashTable *table, else defidx = 0; - /* Also, copy over the full path info. */ - if (!strcmp (os->objects[o], FC_FILE)) - FcPatternTransferFullFname (bucket->pattern, font); - e = FcPatternFindElt (font, os->objects[o]); if (e) { diff --git a/src/fcmatch.c b/src/fcmatch.c index e3748e5..88feb8a 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -495,9 +495,6 @@ FcFontRenderPrepare (FcConfig *config, FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue); } - if (FcPatternFindElt (font, FC_FILE)) - FcPatternTransferFullFname (new, font); - FcConfigSubstituteWithPat (config, new, pat, FcMatchFont); return new; } diff --git a/src/fcpat.c b/src/fcpat.c index bc4270b..c78e670 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -39,16 +39,6 @@ FcPatternEltPtrCreateDynamic (FcPatternElt * e); static FcBool FcStrHashed (const FcChar8 *name); -static const char * -FcPatternFindFullFname (const FcPattern *p); - -/* If you are trying to duplicate an FcPattern which will be used for - * rendering, be aware that (internally) you also have to use - * FcPatternTransferFullFname to transfer the associated filename. If - * you are copying the font (externally) using FcPatternGetString, - * then everything's fine; this caveat only applies if you're copying - * the bits individually. */ - FcPattern * FcPatternCreate (void) { @@ -311,12 +301,6 @@ FcPatternDestroy (FcPattern *p) if (p->ref == FC_REF_CONSTANT || --p->ref > 0) return; - if (FcPatternFindFullFname (p)) - { - FcStrFree ((FcChar8 *)FcPatternFindFullFname (p)); - FcPatternAddFullFname (p, 0); - } - for (i = 0; i < p->num; i++) FcValueListDestroy ((FcPatternEltU(p->elts)+i)->values); @@ -602,9 +586,6 @@ FcPatternBaseFreeze (FcPattern *b) (FcPatternEltU(b->elts)+i)->object; } - if (FcPatternFindElt (b, FC_FILE)) - FcPatternTransferFullFname (ep, b); - ent->hash = hash; ent->next = *bucket; *bucket = ent; @@ -679,9 +660,6 @@ FcPatternFreeze (FcPattern *p) } } - if (FcPatternFindElt (p, FC_FILE)) - FcPatternTransferFullFname (b, p); - /* * Freeze base */ @@ -1112,39 +1090,6 @@ FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls) return FcPatternAdd (p, object, v, FcTrue); } -static FcResult -FcPatternGetFile (const FcPattern *p, const char *object, int id, FcChar8 ** s) -{ - const char *fn, *fpath; - FcChar8 *fname; - int size; - - fn = FcPatternFindFullFname(p); - if (fn) - { - *s = (FcChar8 *) fn; - return FcResultMatch; - } - - if (!p->bank) - return FcResultMatch; - - fpath = FcCacheFindBankDir (p->bank); - size = strlen((char *)fpath) + 1 + strlen ((char *)*s) + 1; - fname = malloc (size); - if (!fname) - return FcResultOutOfMemory; - - FcMemAlloc (FC_MEM_STRING, size); - strcpy ((char *)fname, (char *)fpath); - strcat ((char *)fname, "/"); - strcat ((char *)fname, (char *)*s); - - FcPatternAddFullFname (p, (const char *)fname); - *s = (FcChar8 *)fname; - return FcResultMatch; -} - FcResult FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) { @@ -1159,12 +1104,6 @@ FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) if (!id) { *v = FcValueCanonicalize(&FcValueListPtrU(l)->value); - - /* Pull the FC_FILE trick here too. */ - if (v->type == FcTypeString && - FcObjectToPtr(object) == FcObjectToPtr(FC_FILE)) - return FcPatternGetFile (p, object, id, (FcChar8 **)&(v->u.s)); - return FcResultMatch; } id--; @@ -1332,7 +1271,6 @@ FcPatternDuplicate (const FcPattern *orig) FcTrue)) goto bail1; } - FcPatternTransferFullFname (new, orig); return new; @@ -2025,71 +1963,3 @@ FcStrUnserialize (FcCache * metadata, void *block_ptr) return block_ptr; } - -/* we don't store these in the FcPattern itself because - * we don't want to serialize the directory names */ - -/* I suppose this should be cleaned upon termination, too... */ -typedef struct _FcPatternDirMapping { - const FcPattern *p; - const char *fname; -} FcPatternDirMapping; - -#define PATTERNDIR_HASH_SIZE 31 -static struct patternDirBucket { - struct patternDirBucket *next; - FcPatternDirMapping m; -} FcPatternDirBuckets[PATTERNDIR_HASH_SIZE]; - -void -FcPatternAddFullFname (const FcPattern *p, const char *fname) -{ - struct patternDirBucket *pb; - - /* N.B. FcPatternHash fails, since it's contents-based, not - * address-based, and we're in the process of mutating the FcPattern. */ - for (pb = &FcPatternDirBuckets - [((unsigned long)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE]; - pb->m.p != p && pb->next; - pb = pb->next) - ; - - if (pb->m.p == p) - { - pb->m.fname = fname; - return; - } - - pb->next = malloc (sizeof (struct patternDirBucket)); - if (!pb->next) - return; - FcMemAlloc (FC_MEM_CACHE, sizeof (struct patternDirBucket)); - - pb->next->next = 0; - pb->next->m.p = p; - pb->next->m.fname = fname; -} - -static const char * -FcPatternFindFullFname (const FcPattern *p) -{ - struct patternDirBucket *pb; - - for (pb = &FcPatternDirBuckets - [((unsigned long)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE]; - pb; pb = pb->next) - if (pb->m.p == p) - return pb->m.fname; - - return 0; -} - -void -FcPatternTransferFullFname (const FcPattern *new, const FcPattern *orig) -{ - FcChar8 * s; - FcPatternGetString (orig, FC_FILE, 0, &s); - FcPatternAddFullFname (new, - (char *)FcStrCopy - ((FcChar8 *)FcPatternFindFullFname(orig))); -} -- 2.39.2