]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccfg.c
Fix string memory leak (Coverity defect #1823).
[fontconfig.git] / src / fccfg.c
index 0e17edb2614aece4d40238ff8e032e75d47c6a97..fc70fefd09af5fcefbd0e1408d61a0857e6df930 100644 (file)
@@ -335,6 +335,7 @@ FcConfigBuildFonts (FcConfig *config)
     
     return FcTrue;
 bail2:
+    FcGlobalCacheDestroy (cache);
     FcStrSetDestroy (oldDirs);
 bail1:
     FcFontSetDestroy (fonts);
@@ -383,10 +384,45 @@ FcConfigGetConfigDirs (FcConfig   *config)
     return FcStrListCreate (config->configDirs);
 }
 
+static FcChar8 *
+FcConfigInodeMatchFontDir (FcConfig *config, const FcChar8 *d)
+{
+    int                n;
+    ino_t      di;
+    dev_t      dd;
+    struct stat s;
+
+    /* first we do string matches rather than file accesses */
+    /* FcStrSetMember doesn't tell us the index so that we can return
+     * the config-owned copy. */
+    for (n = 0; n < config->fontDirs->num; n++)
+    {
+       if (!FcStrCmp (config->fontDirs->strs[n], d))
+           return config->fontDirs->strs[n];
+    }
+
+    /* If this is a bottleneck, we can cache the fontDir inodes. */
+    if (stat ((char *)d, &s) == -1)
+       return 0;
+    di = s.st_ino; dd = s.st_dev;
+
+    for (n = 0; n < config->fontDirs->num; n++)
+    {
+       if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
+           continue;
+       if (di == s.st_ino && dd == s.st_dev)
+           return config->fontDirs->strs[n];
+    }
+    return 0;
+}
+
 FcBool
 FcConfigAddFontDir (FcConfig       *config,
                    const FcChar8   *d)
 {
+    /* Avoid adding d if it's an alias of something else, too. */
+    if (FcConfigInodeMatchFontDir(config, d))
+       return FcTrue;
     return FcStrSetAddFilename (config->fontDirs, d);
 }
 
@@ -397,6 +433,7 @@ FcConfigAddFontDirSubdirs (FcConfig        *config,
     DIR *dir;
     struct dirent *e;
     FcChar8 *subdir;
+    FcBool added = FcFalse;
     
     if (!(dir = opendir ((char *) d)))
        return FcFalse;
@@ -415,52 +452,42 @@ FcConfigAddFontDirSubdirs (FcConfig        *config,
            strcat ((char *)subdir, e->d_name);
            if (FcFileIsDir (subdir))
            {
-               FcConfigAddFontDir (config, subdir);
+               if (FcConfigInodeMatchFontDir(config, subdir))
+                   continue; /* already added */
+               FcStrSetAddFilename (config->fontDirs, subdir);
                FcConfigAddFontDirSubdirs (config, subdir);
+               added = FcTrue;
            }
        }
     }
     free (subdir);
     closedir (dir);
-    return FcTrue;
+    return added;
 }
 
 const FcChar8 *
 FcConfigNormalizeFontDir (FcConfig     *config, 
                          const FcChar8 *d)
 {
-    /* If this is a bottleneck, we can cache the fontDir inodes. */
-    ino_t      di;
-    dev_t      dd;
+    FcChar8    *d0;
     int                n, n0;
-    struct stat s;
+    FcBool     added = FcFalse;
 
-    if (stat ((char *)d, &s) == -1)
-       return 0;
-    di = s.st_ino; dd = s.st_dev;
+    d0 = FcConfigInodeMatchFontDir(config, d);
+    if (d0)
+       return d0;
 
-    for (n = 0; n < config->fontDirs->num; n++)
+    /* Ok, we didn't find it in fontDirs; let's add subdirs.... */
+    for (n = 0, n0 = config->fontDirs->num; n < n0; n++) 
     {
-       if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
-           continue;
-       if (di == s.st_ino && dd == s.st_dev)
-           return config->fontDirs->strs[n];
+       if (FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]))
+           added = FcTrue;
     }
 
-    /* Ok, we didn't find it in fontDirs; let's add subdirs.... */
-    for (n = 0, n0 = config->fontDirs->num; n < n0; n++)
-       FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]);
-
     /* ... and try again. */
-    for (n = 0; n < config->fontDirs->num; n++)
-    {
-       if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
-           continue;
-       if (di == s.st_ino && dd == s.st_dev)
-           return config->fontDirs->strs[n];
-    }
+    if (added)
+       return FcConfigInodeMatchFontDir(config, d);
 
-    /* if it fails, then really give up. */
     return 0;
 }
 
@@ -866,6 +893,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
     FcValue    v, vl, vr;
     FcResult   r;
     FcMatrix   *m;
+    FcChar8     *str;
     
     switch (e->op) {
     case FcOpInteger:
@@ -996,7 +1024,9 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
                switch (e->op) {
                case FcOpPlus:
                    v.type = FcTypeString;
-                   v.u.s = FcStrStaticName (FcStrPlus (vl.u.s, vr.u.s));
+                   str = FcStrPlus (vl.u.s, vr.u.s);
+                   v.u.s = FcStrStaticName (str);
+                   FcStrFree (str);
                         
                    if (!v.u.s)
                        v.type = FcTypeVoid;