summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2006-08-27 23:40:51 -0700
committerKeith Packard <keithp@neko.keithp.com>2006-08-27 23:40:51 -0700
commit0d9e31c810a36cddadff7572fdbb5a1b505e495e (patch)
treef4982910d4baed6f88e71573bce2d95b4bc2219b
parentaf180c40376690b7ced5262156fbe13c9ebba1e2 (diff)
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.
-rw-r--r--src/fcdir.c45
-rw-r--r--src/fcint.h3
-rw-r--r--src/fcstr.c57
3 files changed, 90 insertions, 15 deletions
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)
{