mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 07:56:17 +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);
|
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
|
G_END_DECLS
|
||||||
|
@ -165,15 +165,15 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Section *dirindex;
|
Section *dirindex;
|
||||||
gint i;
|
gint i, n_entries;
|
||||||
const char *entry_name;
|
const char *entry_name;
|
||||||
DirEntry *entry;
|
DirEntry *entry;
|
||||||
|
|
||||||
dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
|
dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
|
||||||
|
n_entries = ((Header *)typelib->data)->n_local_entries;
|
||||||
|
|
||||||
if (dirindex == NULL)
|
if (dirindex == NULL)
|
||||||
{
|
{
|
||||||
gint n_entries = ((Header *)typelib->data)->n_local_entries;
|
|
||||||
for (i = 1; i <= n_entries; i++)
|
for (i = 1; i <= n_entries; i++)
|
||||||
{
|
{
|
||||||
entry = g_typelib_get_dir_entry (typelib, 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];
|
guint8 *hash = (guint8*) &typelib->data[dirindex->offset];
|
||||||
guint16 index;
|
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 = g_typelib_get_dir_entry (typelib, index + 1);
|
||||||
entry_name = g_typelib_get_string (typelib, entry->name);
|
entry_name = g_typelib_get_string (typelib, entry->name);
|
||||||
if (strcmp (name, entry_name) == 0)
|
if (strcmp (name, entry_name) == 0)
|
||||||
|
@ -47,10 +47,10 @@ test_build_retrieve (void)
|
|||||||
|
|
||||||
_gi_typelib_hash_builder_destroy (builder);
|
_gi_typelib_hash_builder_destroy (builder);
|
||||||
|
|
||||||
g_assert (_gi_typelib_hash_search (buf, "Action") == 0);
|
g_assert (_gi_typelib_hash_search (buf, "Action", 4) == 0);
|
||||||
g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor") == 42);
|
g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor", 4) == 42);
|
||||||
g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor") == 9);
|
g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor", 4) == 9);
|
||||||
g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags") == 31);
|
g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags", 4) == 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
10
gthash.c
10
gthash.c
@ -191,7 +191,7 @@ _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
guint16
|
guint16
|
||||||
_gi_typelib_hash_search (guint8* memory, const char *str)
|
_gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries)
|
||||||
{
|
{
|
||||||
guint32 *mph;
|
guint32 *mph;
|
||||||
guint16 *table;
|
guint16 *table;
|
||||||
@ -203,6 +203,14 @@ _gi_typelib_hash_search (guint8* memory, const char *str)
|
|||||||
|
|
||||||
offset = cmph_search_packed (mph, str, strlen (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);
|
dirmap_offset = *((guint32*)memory);
|
||||||
table = (guint16*) (memory + dirmap_offset);
|
table = (guint16*) (memory + dirmap_offset);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user