summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fccfg.c2
-rw-r--r--test/test-45-generic.json9
-rw-r--r--test/test-conf.c124
3 files changed, 134 insertions, 1 deletions
diff --git a/src/fccfg.c b/src/fccfg.c
index 91af959..462c423 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -989,12 +989,12 @@ FcConfigCompareValue (const FcValue *left_o,
FcBool ret = FcFalse;
FcOp op = FC_OP_GET_OP (op_);
int flags = FC_OP_GET_FLAGS (op_);
+ FcValuePromotionBuffer buf1, buf2;
if (left_o->type != right_o->type)
{
left = FcValueCanonicalize(left_o);
right = FcValueCanonicalize(right_o);
- FcValuePromotionBuffer buf1, buf2;
left = FcConfigPromote (left, right, &buf1);
right = FcConfigPromote (right, left, &buf2);
left_o = &left;
diff --git a/test/test-45-generic.json b/test/test-45-generic.json
index 665d7c3..fe2374a 100644
--- a/test/test-45-generic.json
+++ b/test/test-45-generic.json
@@ -21,6 +21,15 @@
"family": "math",
"lang": "und-zmth"
}
+ },
+ {
+ "method": "match",
+ "query": {
+ "lang": [ "en", "fr" ]
+ },
+ "result": {
+ // Exercise complex value promotion. No ASAN issues.
+ }
}
]
}
diff --git a/test/test-conf.c b/test/test-conf.c
index 288bb5b..4959f76 100644
--- a/test/test-conf.c
+++ b/test/test-conf.c
@@ -51,6 +51,8 @@ build_pattern (json_object *obj)
json_object_object_foreachC (obj, iter)
{
FcValue v;
+ FcBool destroy_v = FcFalse;
+ FcMatrix matrix;
if (json_object_get_type (iter.val) == json_type_boolean)
{
@@ -105,12 +107,134 @@ build_pattern (json_object *obj)
{
v.type = FcTypeVoid;
}
+ else if (json_object_get_type (iter.val) == json_type_array)
+ {
+ json_object *o;
+ json_type type;
+ int i, n;
+
+ n = json_object_array_length (iter.val);
+ if (n == 0) {
+ fprintf (stderr, "E: value is an empty array\n");
+ continue;
+ }
+
+ o = json_object_array_get_idx (iter.val, 0);
+ type = json_object_get_type (o);
+ if (type == json_type_string) {
+ const FcObjectType *fc_o = FcNameGetObjectType (iter.key);
+ if (fc_o && fc_o->type == FcTypeCharSet) {
+ FcCharSet* cs = FcCharSetCreate ();
+ if (!cs) {
+ fprintf (stderr, "E: failed to create charset\n");
+ continue;
+ }
+ v.type = FcTypeCharSet;
+ v.u.c = cs;
+ destroy_v = FcTrue;
+ for (i = 0; i < n; i++)
+ {
+ const FcChar8 *src;
+ int len, nchar, wchar;
+ FcBool valid;
+ FcChar32 dst;
+
+ o = json_object_array_get_idx (iter.val, i);
+ type = json_object_get_type (o);
+ if (type != json_type_string) {
+ fprintf (stderr, "E: charset value not string\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ src = (const FcChar8 *) json_object_get_string (o);
+ len = json_object_get_string_len (o);
+ valid = FcUtf8Len (src, len, &nchar, &wchar);
+ if (valid == FcFalse) {
+ fprintf (stderr, "E: charset entry not well formed\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ if (nchar != 1) {
+ fprintf (stderr, "E: charset entry not not one codepoint\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ FcUtf8ToUcs4 (src, &dst, len);
+ if (FcCharSetAddChar (cs, dst) == FcFalse) {
+ fprintf (stderr, "E: failed to add to charset\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ }
+ } else {
+ FcLangSet* ls = FcLangSetCreate ();
+ if (!ls) {
+ fprintf (stderr, "E: failed to create langset\n");
+ continue;
+ }
+ v.type = FcTypeLangSet;
+ v.u.l = ls;
+ destroy_v = FcTrue;
+ for (i = 0; i < n; i++)
+ {
+ o = json_object_array_get_idx (iter.val, i);
+ type = json_object_get_type (o);
+ if (type != json_type_string) {
+ fprintf (stderr, "E: langset value not string\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ if (FcLangSetAdd (ls, (const FcChar8 *)json_object_get_string (o)) == FcFalse) {
+ fprintf (stderr, "E: failed to add to langset\n");
+ FcValueDestroy (v);
+ continue;
+ }
+ }
+ }
+ } else if (type == json_type_double || type == json_type_int) {
+ double values[4];
+ if (n != 2 && n != 4) {
+ fprintf (stderr, "E: array starting with number not range or matrix\n");
+ continue;
+ }
+ for (i = 0; i < n; i++) {
+ o = json_object_array_get_idx (iter.val, i);
+ type = json_object_get_type (o);
+ if (type != json_type_double && type != json_type_int) {
+ fprintf (stderr, "E: numeric array entry not a number\n");
+ continue;
+ }
+ values[i] = json_object_get_double (o);
+ }
+ if (n == 2) {
+ v.type = FcTypeRange;
+ v.u.r = FcRangeCreateDouble (values[0], values[1]);
+ if (!v.u.r) {
+ fprintf (stderr, "E: failed to create range\n");
+ continue;
+ }
+ destroy_v = FcTrue;
+ } else {
+ v.type = FcTypeMatrix;
+ v.u.m = &matrix;
+ matrix.xx = values[0];
+ matrix.xy = values[1];
+ matrix.yx = values[2];
+ matrix.yy = values[3];
+ }
+ } else {
+ fprintf (stderr, "E: array format not recognized\n");
+ continue;
+ }
+ }
else
{
fprintf (stderr, "W: unexpected object to build a pattern: (%s %s)", iter.key, json_type_to_name (json_object_get_type (iter.val)));
continue;
}
FcPatternAdd (pat, iter.key, v, FcTrue);
+ if (destroy_v)
+ FcValueDestroy (v);
}
return pat;
}