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
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);
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)
_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
}
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;
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);
g_base_info_unref (info);
}
+static void
+test_hash_with_cairo_typelib (GIRepository *repo)
+{
+ GIBaseInfo *info;
+
+ g_assert (g_irepository_require (repo, "cairo", NULL, 0, NULL));
+ info = g_irepository_find_by_name (repo, "cairo", "region");
+ g_assert (info == NULL);
+}
+
int
main(int argc, char **argv)
{
test_size_of_gvalue (repo);
test_is_pointer_for_struct_arg (repo);
test_fundamental_get_ref_function_pointer (repo);
+ test_hash_with_cairo_typelib (repo);
exit(0);
}