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.
This commit is contained in:
Keith Packard 2006-08-27 23:40:51 -07:00
parent af180c4037
commit 0d9e31c810
3 changed files with 90 additions and 15 deletions

View File

@ -132,6 +132,7 @@ FcDirScanConfig (FcFontSet *set,
FcConfig *config) FcConfig *config)
{ {
DIR *d; DIR *d;
FcChar8 *canon_dir;
struct dirent *e; struct dirent *e;
FcStrSet *dirlist, *filelist; FcStrSet *dirlist, *filelist;
FcChar8 *file; FcChar8 *file;
@ -140,38 +141,49 @@ FcDirScanConfig (FcFontSet *set,
FcFontSet *tmpSet; FcFontSet *tmpSet;
int i; int i;
if (config && !FcConfigAcceptFilename (config, dir)) canon_dir = FcStrCanonFilename (dir);
return FcTrue; 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 (!force)
{ {
if (FcDirCacheRead (set, dirs, dir, config)) if (FcDirCacheRead (set, dirs, canon_dir, config)) {
return FcTrue; ret = FcTrue;
goto bail;
}
} }
if (FcDebug () & FC_DBG_FONTSET) if (FcDebug () & FC_DBG_FONTSET)
printf ("cache scan dir %s\n", dir); printf ("cache scan dir %s\n", canon_dir);
/* freed below */ /* freed below */
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1); file = (FcChar8 *) malloc (strlen ((char *) canon_dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file) if (!file) {
return FcFalse; ret = FcFalse;
goto bail;
}
strcpy ((char *) file, (char *) dir); strcpy ((char *) file, (char *) canon_dir);
strcat ((char *) file, "/"); strcat ((char *) file, "/");
base = file + strlen ((char *) file); base = file + strlen ((char *) file);
if (FcDebug () & FC_DBG_SCAN) 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) if (!d)
{ {
free (file);
/* Don't complain about missing directories */ /* Don't complain about missing directories */
if (errno == ENOENT) if (errno == ENOENT)
return FcTrue; ret = FcTrue;
return FcFalse; else
ret = FcFalse;
goto bail_1;
} }
tmpSet = FcFontSetCreate(); tmpSet = FcFontSetCreate();
@ -224,7 +236,7 @@ FcDirScanConfig (FcFontSet *set,
* Now that the directory has been scanned, * Now that the directory has been scanned,
* write out the cache file * 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 * Add the discovered fonts to our internal non-cache list
@ -256,7 +268,10 @@ FcDirScanConfig (FcFontSet *set,
bail0: bail0:
closedir (d); closedir (d);
bail_1:
free (file); free (file);
bail:
if (canon_dir != dir) free (canon_dir);
return ret; return ret;
} }

View File

@ -926,4 +926,7 @@ FcStrLastSlash (const FcChar8 *path);
FcChar32 FcChar32
FcStrHashIgnoreCase (const FcChar8 *s); FcStrHashIgnoreCase (const FcChar8 *s);
FcChar8 *
FcStrCanonFilename (const FcChar8 *s);
#endif /* _FC_INT_H_ */ #endif /* _FC_INT_H_ */

View File

@ -835,6 +835,63 @@ FcStrBasename (const FcChar8 *file)
return FcStrCopy (slash + 1); 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 * FcStrSet *
FcStrSetCreate (void) FcStrSetCreate (void)
{ {