Bug 148693

Summary: fontconfig: FcConfigAppFontAddDir () doesn't work right
Product: [openSUSE] SUSE Linux 10.1 Reporter: Mike Fabian <mfabian>
Component: BasesystemAssignee: Mike Fabian <mfabian>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: aj, coolo, dmueller, mmarek, sbrabec, tiwai
Version: Beta 3   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Whiteboard:
Found By: Development Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: ttt.c
fontconfig-bug148693.patch
fc-app-dir-fix.diff
fc-app-dir-fix.diff
fc-app-dir-fix-new.diff
fc-app-dir-fix-new-new.diff

Description Mike Fabian 2006-02-07 14:14:29 UTC
fontconfig: FcConfigAppFontAddDir () doesn't work right.
Comment 1 Mike Fabian 2006-02-07 14:16:51 UTC
The build of "lilypond" fails because of this:

/work/built/info/failed/i386/lilypond has:
ffective prefix: "/usr/src/packages/BUILD/lilypond-2.6.5/share/lilypond/2.6.5"
Initializing FontConfig...
error: adding font directory: /usr/src/packages/BUILD/lilypond-2.6.5/share/lilypo
nd/2.6.5/fonts/otf/
make[2]: *** [out/lilypond-internals.texi] Error 1
make[2]: Leaving directory `/usr/src/packages/BUILD/lilypond-2.6.5/Documentation/
user'
Comment 2 Michal Marek 2006-02-07 14:26:31 UTC
The regression is somewhere in 
/work/SAVE/oldpackages/stable/fontconfig/fontconfig-20060203
/.../fontconfig-20060129 works.
Comment 3 Mike Fabian 2006-02-07 14:36:34 UTC
Created attachment 66754 [details]
ttt.c

Test program to reproduce the bug:

    gcc -g -O0 ttt.c -l fontconfig

    mfabian@magellan:~/c$ ./a.out /usr/share/fonts
    mfabian@magellan:~/c$

OK.

But:

    mfabian@magellan:~/c$ ./a.out /usr/share/
    error adding dir "/usr/share/"
    mfabian@magellan:~/c$

I.e. it doesn't work for directories which are not yet sub directories
of directories configured in .conf files.
Comment 4 Mike Fabian 2006-02-07 14:38:03 UTC
And:

    mfabian@magellan:/usr/share/fonts$ sudo ln -s /usr/share/fonts ttt
    mfabian@magellan:/usr/share/fonts$
    mfabian@magellan:/usr/share/fonts$ /home/mfabian/c/a.out /usr/share/fonts

    -> endless loop

Comment 5 Michal Marek 2006-02-07 15:54:47 UTC
Created attachment 66808 [details]
fontconfig-bug148693.patch

This makes the test program happy (if I understood the code correctly :-)), building lilypond now.
Comment 6 Takashi Iwai 2006-02-07 16:04:29 UTC
The call of NormalizeDir() became already superfluous by the newer patches, so you can simply remove it, and take FcConfigAddFontDir() back (to be sure).

My new patch was already sent to Mike for testing.  Stay tuned.
Comment 7 Mike Fabian 2006-02-07 16:46:53 UTC
Created attachment 66829 [details]
fc-app-dir-fix.diff

Takashi's patch.
Comment 8 Mike Fabian 2006-02-07 16:48:19 UTC
Created attachment 66830 [details]
fc-app-dir-fix.diff

Takashi's patch adapted to today's CVS.
Comment 9 Mike Fabian 2006-02-07 17:46:21 UTC
Takashi's patch introduces an endless loop again.

In fccache.c, Function FcCacheReadDirs (), around line 862,
a call to FcStrSetMember () seems to be necessary:

 + 	dir = FcConfigNormalizeFontDir (config, dir);
 + 	if (! dir)
 + 	    continue;
++	if (FcStrSetMember (processed_dirs, dir))
++	    continue;
 + 	if (! FcStrSetAdd (processed_dirs, dir))
 + 	    continue;
 +

Comment 10 Mike Fabian 2006-02-07 17:47:27 UTC
Created attachment 66842 [details]
fc-app-dir-fix-new.diff

improved patch to avoid the endless loop.
Comment 11 Mike Fabian 2006-02-07 17:53:31 UTC
Patrick's comment in

http://lists.freedesktop.org/archives/fontconfig/2006-February/002036.html

seems to say that the call to FcStrSetMember() is not necessary.

Nevertheless it is necessary.

Comment 12 Mike Fabian 2006-02-07 18:01:07 UTC
Patrick Lam> The call to FcStrSetMember in FcCacheReadDirs is unneeded (here and
Patrick Lam> elsewhere), because FcStrSetAdd calls _FcStrSetAppend, which starts with:
Patrick Lam> 
Patrick Lam>     if (FcStrSetMember (set, s))
Patrick Lam>     {
Patrick Lam>         FcStrFree (s);
Patrick Lam>         return FcTrue;
Patrick Lam>     }

The problem is that it returns FcTrue here, i.e. _FcStrSetAppend ()
returns FcTrue if the dir is already a member.
Comment 13 Mike Fabian 2006-02-07 18:06:34 UTC
Fixed fontconfig package submitted to STABLE.

lilypond builds again with that fontconfig package.

My test program from comment #3 works as well.
Comment 14 Mike Fabian 2006-02-07 18:16:12 UTC
FcConfigAppFontAddDir () does not check the existence of a directory though,
i.e. when adding a non-existing directory 

   ./a.out bla

it works as well.

I guess FcConfigAppFontAddDir () should refuse to add non-existing
directories and return FcFalse in that case.
Comment 15 Mike Fabian 2006-02-07 18:44:19 UTC
As the behaviour described in comment #14 has been always like
this, changing it might have an effect on applications using it.
There one might have to be careful with returning FcFalse for
non-existing directories.
Comment 16 Mike Fabian 2006-02-07 18:44:43 UTC
Closing as FIXED.
Comment 17 Mike Fabian 2006-02-07 18:45:11 UTC
FIXED.
Comment 18 Mike Fabian 2006-02-10 15:44:56 UTC
Current upstream CVS still runs into an endless loop for the
test case in comment #4.
Comment 19 Mike Fabian 2006-02-10 16:08:28 UTC
Created attachment 67657 [details]
fc-app-dir-fix-new-new.diff

The attached hunks of Takashi's patch are still necessary to make it work.

Actually the very last hunk:

diff -ru fontconfig-2.3.93.20060210.orig/src/fcdir.c fontconfig-2.3.93.20060210/src/fcdir.c
--- fontconfig-2.3.93.20060210.orig/src/fcdir.c	2006-02-10 13:06:08.000000000 +0100
+++ fontconfig-2.3.93.20060210/src/fcdir.c	2006-02-10 16:35:30.000000000 +0100
@@ -133,6 +133,8 @@
 	d_can = FcConfigNormalizeFontDir (config, dir);
     if (d_can)
 	dir = d_can;
+    else
+	FcConfigAddFontDir (config, dir);
 
     if (!force)
     {


is not necessary, it works without this hunk.

But this hunk seems logical to me, probably it is better to include
this as well.
Comment 20 Mike Fabian 2006-02-10 16:09:06 UTC
FIXED again.