From: Keith Packard Date: Mon, 28 Aug 2006 06:40:51 +0000 (-0700) Subject: Eliminate ./ and ../ elements from font directory names when scanning. X-Git-Tag: 2.3.96~45 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=0d9e31c810a36cddadff7572fdbb5a1b505e495e;p=fontconfig.git Eliminate ./ and ../ elements from font directory names when scanning. FcStrCanonFilename eliminates ./ and ../ elements from pathnames through simple string editing. Also, relative path names are fixed by prepending the current working directory. --- diff --git a/src/fcdir.c b/src/fcdir.c index c15b727..86d391b 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -132,6 +132,7 @@ FcDirScanConfig (FcFontSet *set, FcConfig *config) { DIR *d; + FcChar8 *canon_dir; struct dirent *e; FcStrSet *dirlist, *filelist; FcChar8 *file; @@ -140,38 +141,49 @@ FcDirScanConfig (FcFontSet *set, FcFontSet *tmpSet; int i; - if (config && !FcConfigAcceptFilename (config, dir)) - return FcTrue; + canon_dir = FcStrCanonFilename (dir); + if (!canon_dir) canon_dir = (FcChar8 *) dir; + printf ("dir %s canon %s\n", dir, canon_dir); + + if (config && !FcConfigAcceptFilename (config, canon_dir)) { + ret = FcTrue; + goto bail; + } if (!force) { - if (FcDirCacheRead (set, dirs, dir, config)) - return FcTrue; + if (FcDirCacheRead (set, dirs, canon_dir, config)) { + ret = FcTrue; + goto bail; + } } if (FcDebug () & FC_DBG_FONTSET) - printf ("cache scan dir %s\n", dir); + printf ("cache scan dir %s\n", canon_dir); /* freed below */ - file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1); - if (!file) - return FcFalse; + file = (FcChar8 *) malloc (strlen ((char *) canon_dir) + 1 + FC_MAX_FILE_LEN + 1); + if (!file) { + ret = FcFalse; + goto bail; + } - strcpy ((char *) file, (char *) dir); + strcpy ((char *) file, (char *) canon_dir); strcat ((char *) file, "/"); base = file + strlen ((char *) file); if (FcDebug () & FC_DBG_SCAN) - printf ("\tScanning dir %s\n", dir); + printf ("\tScanning dir %s\n", canon_dir); - d = opendir ((char *) dir); + d = opendir ((char *) canon_dir); if (!d) { - free (file); /* Don't complain about missing directories */ if (errno == ENOENT) - return FcTrue; - return FcFalse; + ret = FcTrue; + else + ret = FcFalse; + goto bail_1; } tmpSet = FcFontSetCreate(); @@ -224,7 +236,7 @@ FcDirScanConfig (FcFontSet *set, * Now that the directory has been scanned, * write out the cache file */ - FcDirCacheWrite (tmpSet, dirlist, dir, config); + FcDirCacheWrite (tmpSet, dirlist, canon_dir, config); /* * Add the discovered fonts to our internal non-cache list @@ -256,7 +268,10 @@ FcDirScanConfig (FcFontSet *set, bail0: closedir (d); + bail_1: free (file); + bail: + if (canon_dir != dir) free (canon_dir); return ret; } diff --git a/src/fcint.h b/src/fcint.h index cb137d3..fbbdf77 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -926,4 +926,7 @@ FcStrLastSlash (const FcChar8 *path); FcChar32 FcStrHashIgnoreCase (const FcChar8 *s); +FcChar8 * +FcStrCanonFilename (const FcChar8 *s); + #endif /* _FC_INT_H_ */ diff --git a/src/fcstr.c b/src/fcstr.c index 5d1961c..37bad6b 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -835,6 +835,63 @@ FcStrBasename (const FcChar8 *file) return FcStrCopy (slash + 1); } +FcChar8 * +FcStrCanonFilename (const FcChar8 *s) +{ + FcChar8 *file; + FcChar8 *f; + const FcChar8 *slash; + + if (*s != '/') + { + FcChar8 *full; + + FcChar8 cwd[FC_MAX_FILE_LEN + 2]; + if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL) + return NULL; + strcat ((char *) cwd, "/"); + full = FcStrPlus (cwd, s); + file = FcStrCanonFilename (full); + FcStrFree (full); + return file; + } + file = malloc (strlen ((char *) s) + 1); + if (!file) + return NULL; + slash = NULL; + f = file; + for (;;) { + if (*s == '/' || *s == '\0') + { + if (slash) + { + switch (s - slash) { + case 2: + if (!strncmp ((char *) slash, "/.", 2)) + { + f -= 2; /* trim /. from file */ + } + break; + case 3: + if (!strncmp ((char *) slash, "/..", 3)) + { + f -= 3; /* trim /.. from file */ + while (f > file) { + if (*--f == '/') + break; + } + } + break; + } + } + slash = s; + } + if (!(*f++ = *s++)) + break; + } + return file; +} + FcStrSet * FcStrSetCreate (void) {