mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
girepository: avoid crash when querying nonexistent info
It appears that cmph library can return (n+1) when querying item not present in its original n-item-sized set. Adjust code so that it detects this condition and do not chase stray pointers resulting from this bogus(?) hash result. https://bugzilla.gnome.org/show_bug.cgi?id=675939
This commit is contained in:
parent
0a96da9284
commit
8af8aaa4a8
@ -1183,7 +1183,7 @@ void _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem,
|
||||
|
||||
void _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder);
|
||||
|
||||
guint16 _gi_typelib_hash_search (guint8* memory, const char *str);
|
||||
guint16 _gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -165,15 +165,15 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib,
|
||||
const char *name)
|
||||
{
|
||||
Section *dirindex;
|
||||
gint i;
|
||||
gint i, n_entries;
|
||||
const char *entry_name;
|
||||
DirEntry *entry;
|
||||
|
||||
dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
|
||||
n_entries = ((Header *)typelib->data)->n_local_entries;
|
||||
|
||||
if (dirindex == NULL)
|
||||
{
|
||||
gint n_entries = ((Header *)typelib->data)->n_local_entries;
|
||||
for (i = 1; i <= n_entries; i++)
|
||||
{
|
||||
entry = g_typelib_get_dir_entry (typelib, i);
|
||||
@ -188,7 +188,7 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib,
|
||||
guint8 *hash = (guint8*) &typelib->data[dirindex->offset];
|
||||
guint16 index;
|
||||
|
||||
index = _gi_typelib_hash_search (hash, name);
|
||||
index = _gi_typelib_hash_search (hash, name, n_entries);
|
||||
entry = g_typelib_get_dir_entry (typelib, index + 1);
|
||||
entry_name = g_typelib_get_string (typelib, entry->name);
|
||||
if (strcmp (name, entry_name) == 0)
|
||||
|
@ -47,10 +47,10 @@ test_build_retrieve (void)
|
||||
|
||||
_gi_typelib_hash_builder_destroy (builder);
|
||||
|
||||
g_assert (_gi_typelib_hash_search (buf, "Action") == 0);
|
||||
g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor") == 42);
|
||||
g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor") == 9);
|
||||
g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags") == 31);
|
||||
g_assert (_gi_typelib_hash_search (buf, "Action", 4) == 0);
|
||||
g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor", 4) == 42);
|
||||
g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor", 4) == 9);
|
||||
g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags", 4) == 31);
|
||||
}
|
||||
|
||||
int
|
||||
|
10
gthash.c
10
gthash.c
@ -191,7 +191,7 @@ _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder)
|
||||
}
|
||||
|
||||
guint16
|
||||
_gi_typelib_hash_search (guint8* memory, const char *str)
|
||||
_gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries)
|
||||
{
|
||||
guint32 *mph;
|
||||
guint16 *table;
|
||||
@ -203,6 +203,14 @@ _gi_typelib_hash_search (guint8* memory, const char *str)
|
||||
|
||||
offset = cmph_search_packed (mph, str, strlen (str));
|
||||
|
||||
/* Make sure that offset always lies in the entries array. cmph
|
||||
cometimes generates offset larger than number of entries (for
|
||||
'str' argument which is not in the hashed list). In this case,
|
||||
fake the correct result and depend on caller's final check that
|
||||
the entry is really the one that the caller wanted. */
|
||||
if (offset >= n_entries)
|
||||
offset = 0;
|
||||
|
||||
dirmap_offset = *((guint32*)memory);
|
||||
table = (guint16*) (memory + dirmap_offset);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user