Fix bug when clients use FcNameRegisterObjectTypes; fontconfig was
returning bogus (i.e. duplicate) FcObjectPtr values. Now use negative values for dynamic object strings and positive values for built-in and FcNameRegisterObjectType strings. Thanks to Matthias Clasen for pinpointing this bus!
This commit is contained in:
parent
9fe2bd7ab0
commit
141432505a
37
src/fcname.c
37
src/fcname.c
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
/* Please do not revoke any of these bindings. */
|
/* Please do not revoke any of these bindings. */
|
||||||
static const FcObjectType _FcBaseObjectTypes[] = {
|
static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
|
{ "__DUMMY__", FcTypeVoid, },
|
||||||
{ FC_FAMILY, FcTypeString, },
|
{ FC_FAMILY, FcTypeString, },
|
||||||
{ FC_FAMILYLANG, FcTypeString, },
|
{ FC_FAMILYLANG, FcTypeString, },
|
||||||
{ FC_STYLE, FcTypeString, },
|
{ FC_STYLE, FcTypeString, },
|
||||||
|
@ -77,6 +78,7 @@ static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
|
|
||||||
static FcObjectType * _FcUserObjectNames = 0;
|
static FcObjectType * _FcUserObjectNames = 0;
|
||||||
static int user_obj_alloc = 0;
|
static int user_obj_alloc = 0;
|
||||||
|
static int next_basic_offset = NUM_OBJECT_TYPES;
|
||||||
|
|
||||||
typedef struct _FcObjectTypeList FcObjectTypeList;
|
typedef struct _FcObjectTypeList FcObjectTypeList;
|
||||||
|
|
||||||
|
@ -84,6 +86,7 @@ struct _FcObjectTypeList {
|
||||||
const FcObjectTypeList *next;
|
const FcObjectTypeList *next;
|
||||||
const FcObjectType *types;
|
const FcObjectType *types;
|
||||||
int ntypes;
|
int ntypes;
|
||||||
|
int basic_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FcObjectTypeList _FcBaseObjectTypesList = {
|
static const FcObjectTypeList _FcBaseObjectTypesList = {
|
||||||
|
@ -106,6 +109,8 @@ FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
|
||||||
l->types = types;
|
l->types = types;
|
||||||
l->ntypes = ntypes;
|
l->ntypes = ntypes;
|
||||||
l->next = _FcObjectTypes;
|
l->next = _FcObjectTypes;
|
||||||
|
l->basic_offset = next_basic_offset;
|
||||||
|
next_basic_offset += ntypes;
|
||||||
_FcObjectTypes = l;
|
_FcObjectTypes = l;
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
@ -166,6 +171,8 @@ struct objectBucket {
|
||||||
};
|
};
|
||||||
static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
|
static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
|
||||||
|
|
||||||
|
/* Design constraint: biggest_known_ntypes must never change
|
||||||
|
* after any call to FcNameRegisterObjectTypes. */
|
||||||
static const FcObjectType *biggest_known_types = _FcBaseObjectTypes;
|
static const FcObjectType *biggest_known_types = _FcBaseObjectTypes;
|
||||||
static FcBool allocated_biggest_known_types;
|
static FcBool allocated_biggest_known_types;
|
||||||
static int biggest_known_ntypes = NUM_OBJECT_TYPES;
|
static int biggest_known_ntypes = NUM_OBJECT_TYPES;
|
||||||
|
@ -188,9 +195,9 @@ FcObjectToPtrLookup (const char * object)
|
||||||
if (!strcmp (object, t->object))
|
if (!strcmp (object, t->object))
|
||||||
{
|
{
|
||||||
if (l == (FcObjectTypeList*)_FcUserObjectNames)
|
if (l == (FcObjectTypeList*)_FcUserObjectNames)
|
||||||
return i + biggest_known_ntypes;
|
return -i;
|
||||||
else
|
else
|
||||||
return i;
|
return l->basic_offset + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +217,7 @@ FcObjectToPtrLookup (const char * object)
|
||||||
FcObjectType * t = realloc (_FcUserObjectNames,
|
FcObjectType * t = realloc (_FcUserObjectNames,
|
||||||
nt * sizeof (FcObjectType));
|
nt * sizeof (FcObjectType));
|
||||||
if (!t)
|
if (!t)
|
||||||
return -1;
|
return 0;
|
||||||
_FcUserObjectNames = t;
|
_FcUserObjectNames = t;
|
||||||
user_obj_alloc = nt;
|
user_obj_alloc = nt;
|
||||||
}
|
}
|
||||||
|
@ -240,7 +247,7 @@ FcObjectToPtrLookup (const char * object)
|
||||||
t[n].object = object;
|
t[n].object = object;
|
||||||
t[n].type = FcTypeVoid;
|
t[n].type = FcTypeVoid;
|
||||||
|
|
||||||
return n+biggest_known_ntypes;
|
return -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcObjectPtr
|
FcObjectPtr
|
||||||
|
@ -259,7 +266,7 @@ FcObjectToPtr (const char * name)
|
||||||
b = malloc (size);
|
b = malloc (size);
|
||||||
FcMemAlloc (FC_MEM_STATICSTR, size);
|
FcMemAlloc (FC_MEM_STATICSTR, size);
|
||||||
if (!b)
|
if (!b)
|
||||||
return -1;
|
return 0;
|
||||||
b->next = 0;
|
b->next = 0;
|
||||||
b->hash = hash;
|
b->hash = hash;
|
||||||
b->id = FcObjectToPtrLookup (name);
|
b->id = FcObjectToPtrLookup (name);
|
||||||
|
@ -292,10 +299,22 @@ FcObjectStaticNameFini (void)
|
||||||
const char *
|
const char *
|
||||||
FcObjectPtrU (FcObjectPtr si)
|
FcObjectPtrU (FcObjectPtr si)
|
||||||
{
|
{
|
||||||
if (si < biggest_known_ntypes)
|
const FcObjectTypeList *l;
|
||||||
return biggest_known_types[si].object;
|
int i, j;
|
||||||
else
|
|
||||||
return _FcUserObjectNames[si-biggest_known_ntypes].object;
|
if (si > 0)
|
||||||
|
{
|
||||||
|
if (si < biggest_known_ntypes)
|
||||||
|
return biggest_known_types[si].object;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for (l = _FcObjectTypes; l; l = l->next)
|
||||||
|
for (i = 0; i < l->ntypes; i++, j++)
|
||||||
|
if (j == si)
|
||||||
|
return l->types[i].object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _FcUserObjectNames[-si].object;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue