]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccfg.c
677. Fix a segfault in fontconfig (#A.1450, Keith Packard).
[fontconfig.git] / src / fccfg.c
index 328b1ac5f52cae9d3edd45df1c30e21a8fa2605c..446004f23530c01cf2c3456c02f4c2ae12cfae71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.18 2002/07/31 01:36:37 keithp Exp $
+ * $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.23 2002/08/31 22:17:32 keithp Exp $
  *
  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  *
@@ -429,6 +429,7 @@ FcConfigAddEdit (FcConfig   *config,
     subst = (FcSubst *) malloc (sizeof (FcSubst));
     if (!subst)
        return FcFalse;
+    FcMemAlloc (FC_MEM_SUBST, sizeof (FcSubst));
     if (kind == FcMatchPattern)
        prev = &config->substPattern;
     else
@@ -473,6 +474,11 @@ FcConfigPromote (FcValue v, FcValue u)
        v.u.m = &FcIdentityMatrix;
        v.type = FcTypeMatrix;
     }
+    else if (v.type == FcTypeString && u.type == FcTypeLangSet)
+    {
+       v.u.l = FcLangSetPromote (v.u.s);
+       v.type = FcTypeLangSet;
+    }
     return v;
 }
 
@@ -496,7 +502,8 @@ FcConfigCompareValue (FcValue       m,
            case FcOpContains:
                ret = m.u.d == v.u.d;
                break;
-           case FcOpNotEqual:    
+           case FcOpNotEqual:
+           case FcOpNotContains:
                ret = m.u.d != v.u.d;
                break;
            case FcOpLess:    
@@ -521,7 +528,8 @@ FcConfigCompareValue (FcValue       m,
            case FcOpContains:
                ret = m.u.b == v.u.b;
                break;
-           case FcOpNotEqual:    
+           case FcOpNotEqual:
+           case FcOpNotContains:
                ret = m.u.b != v.u.b;
                break;
            default:
@@ -534,7 +542,8 @@ FcConfigCompareValue (FcValue       m,
            case FcOpContains:
                ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) == 0;
                break;
-           case FcOpNotEqual:    
+           case FcOpNotEqual:
+           case FcOpNotContains:
                ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) != 0;
                break;
            default:
@@ -548,6 +557,7 @@ FcConfigCompareValue (FcValue       m,
                ret = FcMatrixEqual (m.u.m, v.u.m);
                break;
            case FcOpNotEqual:
+           case FcOpNotContains:
                ret = !FcMatrixEqual (m.u.m, v.u.m);
                break;
            default:
@@ -560,6 +570,10 @@ FcConfigCompareValue (FcValue      m,
                /* m contains v if v is a subset of m */
                ret = FcCharSetIsSubset (v.u.c, m.u.c);
                break;
+           case FcOpNotContains:
+               /* m contains v if v is a subset of m */
+               ret = !FcCharSetIsSubset (v.u.c, m.u.c);
+               break;
            case FcOpEqual:
                ret = FcCharSetEqual (m.u.c, v.u.c);
                break;
@@ -570,35 +584,43 @@ FcConfigCompareValue (FcValue     m,
                break;
            }
            break;
-       case FcTypeVoid:
+       case FcTypeLangSet:
            switch (op) {
-           case FcOpEqual:
            case FcOpContains:
-               ret = FcTrue;
+               ret = FcLangSetCompare (v.u.l, m.u.l) != FcLangDifferentLang;
+               break;
+           case FcOpNotContains:
+               ret = FcLangSetCompare (v.u.l, m.u.l) == FcLangDifferentLang;
+               break;
+           case FcOpEqual:
+               ret = FcLangSetEqual (v.u.l, m.u.l);
+               break;
+           case FcOpNotEqual:
+               ret = !FcLangSetEqual (v.u.l, m.u.l);
                break;
            default:
                break;
            }
            break;
-       case FcTypeFTFace:
+       case FcTypeVoid:
            switch (op) {
            case FcOpEqual:
-               ret = m.u.f == v.u.f;
-               break;
-           case FcOpNotEqual:
-               ret = m.u.f != v.u.f;
+           case FcOpContains:
+               ret = FcTrue;
                break;
            default:
                break;
            }
            break;
-       case FcTypePattern:
+       case FcTypeFTFace:
            switch (op) {
            case FcOpEqual:
-               ret = FcPatternEqual (m.u.p, v.u.p);
+           case FcOpContains:
+               ret = m.u.f == v.u.f;
                break;
            case FcOpNotEqual:
-               ret = !FcPatternEqual (m.u.p, v.u.p);
+           case FcOpNotContains:
+               ret = m.u.f != v.u.f;
                break;
            default:
                break;
@@ -608,7 +630,7 @@ FcConfigCompareValue (FcValue       m,
     }
     else
     {
-       if (op == FcOpNotEqual)
+       if (op == FcOpNotEqual || op == FcOpNotContains)
            ret = FcTrue;
     }
     return ret;
@@ -674,12 +696,14 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
            v.type = FcTypeVoid;
        FcValueDestroy (vl);
        break;
-    case FcOpContains:
+    case FcOpEqual:
     case FcOpNotEqual:
     case FcOpLess:
     case FcOpLessEqual:
     case FcOpMore:
     case FcOpMoreEqual:
+    case FcOpContains:
+    case FcOpNotContains:
        vl = FcConfigEvaluate (p, e->u.tree.left);
        vr = FcConfigEvaluate (p, e->u.tree.right);
        v.type = FcTypeBool;
@@ -689,7 +713,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
        break;  
     case FcOpOr:
     case FcOpAnd:
-    case FcOpEqual:
     case FcOpPlus:
     case FcOpMinus:
     case FcOpTimes:
@@ -1009,9 +1032,10 @@ FcConfigPatternCanon (FcPattern      *p,
 }
 
 FcBool
-FcConfigSubstitute (FcConfig   *config,
-                   FcPattern   *p,
-                   FcMatchKind kind)
+FcConfigSubstituteWithPat (FcConfig    *config,
+                          FcPattern   *p,
+                          FcPattern   *p_pat,
+                          FcMatchKind kind)
 {
     FcSubst        *s;
     FcSubState     *st;
@@ -1019,7 +1043,6 @@ FcConfigSubstitute (FcConfig      *config,
     FcTest         *t;
     FcEdit         *e;
     FcValueList            *l;
-    FcPattern      *p_pat = 0;
     FcPattern      *m;
 
     if (!config)
@@ -1042,10 +1065,7 @@ FcConfigSubstitute (FcConfig     *config,
     if (kind == FcMatchPattern)
        s = config->substPattern;
     else
-    {
        s = config->substFont;
-       (void) FcPatternGetPattern (p, FC_PATTERN, 0, &p_pat);
-    }
     for (; s; s = s->next)
     {
        /*
@@ -1121,7 +1141,11 @@ FcConfigSubstitute (FcConfig     *config,
                if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
                    !FcStrCmpIgnoreCase ((FcChar8 *) t->field, 
                                         (FcChar8 *) e->field))
+               {
+                   if (!st[i].elt)
+                       t = 0;
                    break;
+               }
            }
            switch (e->op) {
            case FcOpAssign:
@@ -1222,6 +1246,14 @@ FcConfigSubstitute (FcConfig     *config,
     return FcTrue;
 }
 
+FcBool
+FcConfigSubstitute (FcConfig   *config,
+                   FcPattern   *p,
+                   FcMatchKind kind)
+{
+    return FcConfigSubstituteWithPat (config, p, 0, kind);
+}
+
 #ifndef FONTCONFIG_PATH
 #define FONTCONFIG_PATH        "/etc/fonts"
 #endif
@@ -1247,10 +1279,11 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file)
        strcat ((char *) path, "/");
     strcat ((char *) path, (char *) file);
 
+    FcMemAlloc (FC_MEM_STRING, strlen ((char *) path) + 1);
     if (access ((char *) path, R_OK) == 0)
        return path;
     
-    free (path);
+    FcStrFree (path);
     return 0;
 }