]> git.wh0rd.org Git - fontconfig.git/commitdiff
Eliminate ./ and ../ elements from font directory names when scanning.
authorKeith Packard <keithp@neko.keithp.com>
Mon, 28 Aug 2006 06:40:51 +0000 (23:40 -0700)
committerKeith Packard <keithp@neko.keithp.com>
Mon, 28 Aug 2006 06:40:51 +0000 (23:40 -0700)
FcStrCanonFilename eliminates ./ and ../ elements from pathnames through
simple string editing. Also, relative path names are fixed by prepending the
current working directory.

src/fcdir.c
src/fcint.h
src/fcstr.c

index c15b7277b10216a9959847f60215150e91546620..86d391b5b4ab38156e9cc6d21c4a15a696379dc7 100644 (file)
@@ -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;
 }
 
index cb137d389615646d802285ad37a09437a53867d3..fbbdf7799548259469687d05f781a196409eb046 100644 (file)
@@ -926,4 +926,7 @@ FcStrLastSlash (const FcChar8  *path);
 FcChar32
 FcStrHashIgnoreCase (const FcChar8 *s);
 
+FcChar8 *
+FcStrCanonFilename (const FcChar8 *s);
+
 #endif /* _FC_INT_H_ */
index 5d1961c3af47ee0f74857d6ed7df4e9cea976cfc..37bad6b16379f4cd5cf7128d3b163d5eae5d54e6 100644 (file)
@@ -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)
 {