Patch: fix endless loop problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(Once again without the broken ~/.fonts.cache-2 file attached
because the message size was too big)

If this broken ~/.fonts.cache file exists (and no cache files are in
/var/cache/fontconfig) fontconfig (e.g. fc-match) loops endlessly,
eating up all system resources.

mfabian@magellan:~$ fc-cat .fonts.cache-2 | grep printing
fc-cat: printing global cache contents for dir /usr/share/fonts/wine
fc-cat: printing global cache contents for dir /usr/share/fonts
fc-cat: printing global cache contents for dir /usr/share/fonts/bdf
fc-cat: printing global cache contents for dir tmp.xemacs-patches.200505:xemacs-patches.200505.SCORE〓
mfabian@magellan:~$ 

Don't ask me how that strange last "directory" which doesn't really
exist of course got into that cache file. That must be due to yet
another weird bug in fontconfig. I have a *file* (not a directory!)
with a similar name in the "News" folder in my home directory:

mfabian@magellan:~$ ls News/*xemacs-patches.200505*
News/nndoc+.tmp.xemacs-patches.200505:xemacs-patches.200505.SCORE
mfabian@magellan:~$ 

But fontconfig has no business in ~/News, it is not listed as a
font directory in any config file.

Anyway, when reading this broken cache file, fontconfig loops
endlessly because the return value of FcCacheReadString () is not
checked in fccache.c around line 242:

	FcCacheReadString (cache->fd, name_buf, sizeof (name_buf));
	if (!strlen(name_buf))
	    break;

The return value of FcCacheReadString () is zero because the end of
the cache file has been reached but "name_buf" still contains the
previous contents, therefore it never breaks (by the way, it might be
a good idea to check the return value of the read () a few lines later
as well).

I've tried to fix this (and also tried to check the return value
at the other places where FcCacheReadString () was called, just
to make sure).

Patch attached.

diff -ru fontconfig-2.3.93.20060127.orig/src/fccache.c fontconfig-2.3.93.20060127/src/fccache.c
--- fontconfig-2.3.93.20060127.orig/src/fccache.c	2006-01-27 11:10:27.000000000 +0100
+++ fontconfig-2.3.93.20060127/src/fccache.c	2006-01-27 19:17:33.000000000 +0100
@@ -216,7 +216,8 @@
 
     cache->updated = FcFalse;
 
-    FcCacheReadString (cache->fd, name_buf, sizeof (name_buf));
+    if (!FcCacheReadString (cache->fd, name_buf, sizeof (name_buf)))
+	return;
     if (strcmp (name_buf, FC_GLOBAL_MAGIC_COOKIE) != 0)
 	return;
 
@@ -227,8 +228,9 @@
         goto bail_and_destroy;
 
     lseek (cache->fd, current_arch_start, SEEK_SET);
-    FcCacheReadString (cache->fd, candidate_arch_machine_name, 
-                       sizeof (candidate_arch_machine_name));
+    if (!FcCacheReadString (cache->fd, candidate_arch_machine_name, 
+			    sizeof (candidate_arch_machine_name)))
+	goto bail_and_destroy;
     if (strlen(candidate_arch_machine_name) == 0)
 	goto bail_and_destroy;
 
@@ -236,8 +238,7 @@
     {
 	off_t targ;
 
-	FcCacheReadString (cache->fd, name_buf, sizeof (name_buf));
-	if (!strlen(name_buf))
+	if (!FcCacheReadString (cache->fd, name_buf, sizeof (name_buf)) || !strlen(name_buf))
 	    break;
 
 	/* Directory must be older than the global cache file; also
@@ -700,8 +701,7 @@
 	    return FcTrue;
 	}
 
-	FcCacheReadString (fd, name_buf, sizeof (name_buf));
-	if (!strlen(name_buf))
+	if (!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || !strlen(name_buf))
 	{
 	    FcStrFree ((FcChar8 *)cache_hashed);
 	    goto bail;
@@ -922,8 +922,7 @@
 	    FcStrFree ((FcChar8 *)cache_file);
 	    return -1;
 	}
-	FcCacheReadString (fd, name_buf, sizeof (name_buf));
-	if (!strlen(name_buf))
+	if (!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || !strlen(name_buf))
 	    goto bail;
 
 	name_buf_dir = FcStrDirname ((FcChar8 *)name_buf);
@@ -969,7 +968,7 @@
 			   sizeof (candidate_arch_machine_name)) == 0)
 	goto bail1;
 
-    while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
+    while (FcCacheReadString (fd, subdirName, sizeof (subdirName)) && strlen (subdirName) > 0)
         FcStrSetAdd (dirs, (FcChar8 *)subdirName);
 
     if (!FcDirCacheConsume (fd, (const char *)dir, set, config))
@@ -1109,11 +1108,12 @@
 	fd = open(cache_hashed, O_RDONLY);
 	if (fd == -1)
 	    break;
-	FcCacheReadString (fd, name_buf, sizeof (name_buf));
-	close (fd);
-
-	if (!strlen(name_buf))
+	if(!FcCacheReadString (fd, name_buf, sizeof (name_buf)) || !strlen(name_buf))
+	{
+	    close (fd);
 	    break;
+	}
+	close (fd);
 
 	if (strcmp (name_buf, cache_file) != 0)
 	    continue;
-- 
Mike FABIAN   <mfabian@xxxxxxx>   http://www.suse.de/~mfabian
睡眠不足はいい仕事の敵だ。
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux