2012-02-03 19:42:56 +01:00
|
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
|
|
|
* GObject introspection: typelib validation, auxiliary functions
|
2008-08-09 14:55:32 +02:00
|
|
|
|
* related to the binary typelib format
|
2008-02-08 16:31:03 +01:00
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2005 Matthias Clasen
|
|
|
|
|
*
|
2023-10-25 18:10:10 +02:00
|
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
*
|
2008-02-08 16:31:03 +01:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-07-04 12:27:41 +02:00
|
|
|
|
#include "config.h"
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
2010-05-31 22:44:46 +02:00
|
|
|
|
#include "gitypelib-internal.h"
|
2023-10-25 19:11:38 +02:00
|
|
|
|
#include "gitypelib.h"
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2023-11-09 01:06:57 +01:00
|
|
|
|
/**
|
|
|
|
|
* GITypelib:
|
|
|
|
|
*
|
|
|
|
|
* `GITypelib` represents a loaded `.typelib` file, which contains a description
|
|
|
|
|
* of a single module’s API.
|
|
|
|
|
*
|
|
|
|
|
* Since: 2.80
|
|
|
|
|
*/
|
|
|
|
|
|
2024-02-07 15:39:54 +01:00
|
|
|
|
G_DEFINE_BOXED_TYPE (GITypelib, gi_typelib, gi_typelib_ref, gi_typelib_unref)
|
|
|
|
|
|
2024-02-08 12:40:10 +01:00
|
|
|
|
GIInfoType
|
|
|
|
|
gi_typelib_blob_type_to_info_type (GITypelibBlobType blob_type)
|
|
|
|
|
{
|
|
|
|
|
switch (blob_type)
|
|
|
|
|
{
|
gibaseinfo: Stop building GIBoxedInfo instances
Instead, add a method on `GIRegisteredTypeInfo` which indicates whether
the registered type is a boxed type. This will return true for
`GIStructInfo` and `GIUnionInfo` instances which are boxed (not all
structs and unions are).
This makes `GIBoxedInfo` redundant, and it’ll be dropped in a following
commit.
---
There are several different things which typelibs need to be able to
represent:
1. Plain old datatype (POD) structs
2. POD unions
3. Structs with a copy func and/or free func
4. Unions with a copy func and/or free func
5. Structs which are the ‘GType struct’ for an object or interface (i.e.
the class or instance or interface struct)
6. Structs with a copy func and free func *and* boxed GType
7. Unions with a copy func and free func *and* boxed GType
8. Boxed GTypes which represent something other than a struct or union
So there’s a lot going on here. In commit
e28078c70cbf4a57c7dbd39626f43f9bd2674145, a lot of this was reworked,
and support was added for boxed unions and boxed ‘others’ (the last item
on the list above).
Since then, support for boxed types other than structs seems to have
atrophied a bit, and the whole lot has got a bit confusing.
It was perhaps less confusing when all the `GIBaseInfo` subclasses were
actually aliases of each other, but now they have subtype relationships,
the position of `GIBoxedInfo` in that type hierarchy has become unclear.
How is it related to `GIStructInfo`, `GIUnionInfo` and
`GIRegisteredTypeInfo`?
Since a boxed type is necessarily a `GIRegisteredTypeInfo`, and the
methods of `GIRegisteredTypeInfo` are all written to allow a `GType` to
be optional, so that `GIStructInfo` and `GIUnionInfo` can safely derive
from it and still be used to represent plain old datatypes without
`GType`s, it makes sense to add a method to `GIRegisteredTypeInfo` to
indicate that the registered type is derived from `G_TYPE_BOXED`.
Accordingly, the things above are now represented in libgirepository’s
type system as:
1. `GIStructInfo` instance, `GIRegisteredTypeInfo` methods return no
`GType` info
2. `GIUnionInfo` instance similarly
3. `GIStructInfo` instance, `GIRegisteredTypeInfo` methods return no
`GType` info, `gi_struct_info_get_{copy,free}_function_name()` return
non-`NULL` values
4. `GIUnionInfo` instance similarly
5. `GIStructInfo` instance, `GIRegisteredTypeInfo` methods return no
`GType` info, `gi_struct_info_is_gtype_struct()` returns true
6. `GIStructInfo` instance, `GIRegisteredTypeInfo` methods return valid
`GType` information, `gi_registered_type_info_is_boxed()` returns
true, `gi_struct_info_get_{copy,free}_function_name()` return
`NULL` values (because the copy/free functions are hidden inside the
boxed type registration at runtime)
7. `GIUnionInfo` instance similarly
8. Not representable, but could be represented in future by re-adding a
`GIBoxedInfo` type which derives from `GIRegisteredTypeInfo` and is
used solely for boxed ‘other’ types, *not* boxed structs or unions
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3245
2024-02-08 12:44:17 +01:00
|
|
|
|
case BLOB_TYPE_BOXED:
|
|
|
|
|
/* `BLOB_TYPE_BOXED` now always refers to a `StructBlob`, and
|
|
|
|
|
* `GIRegisteredTypeInfo` (the parent type of `GIStructInfo`) has a method
|
|
|
|
|
* for distinguishing whether the struct is a boxed type. So presenting
|
|
|
|
|
* `BLOB_TYPE_BOXED` as its own `GIBaseInfo` subclass is not helpful.
|
|
|
|
|
* See commit e28078c70cbf4a57c7dbd39626f43f9bd2674145 and
|
|
|
|
|
* https://gitlab.gnome.org/GNOME/glib/-/issues/3245. */
|
|
|
|
|
return GI_INFO_TYPE_STRUCT;
|
2024-02-08 12:40:10 +01:00
|
|
|
|
default:
|
|
|
|
|
return (GIInfoType) blob_type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
typedef struct {
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
GSList *context_stack;
|
|
|
|
|
} ValidateContext;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
#define ALIGN_VALUE(this, boundary) \
|
|
|
|
|
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
static void
|
|
|
|
|
push_context (ValidateContext *ctx, const char *name)
|
|
|
|
|
{
|
|
|
|
|
ctx->context_stack = g_slist_prepend (ctx->context_stack, (char*)name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
pop_context (ValidateContext *ctx)
|
|
|
|
|
{
|
|
|
|
|
g_assert (ctx->context_stack != NULL);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
ctx->context_stack = g_slist_delete_link (ctx->context_stack,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
ctx->context_stack);
|
2008-08-24 18:51:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_interface_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error);
|
2008-08-23 23:30:09 +02:00
|
|
|
|
|
2008-10-22 16:31:58 +02:00
|
|
|
|
static DirEntry *
|
2010-08-31 22:36:06 +02:00
|
|
|
|
get_dir_entry_checked (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint16_t index,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-08-24 18:51:43 +02:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header *)typelib->data;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
|
|
|
|
|
if (index == 0 || index > header->n_entries)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid directory index %d", index);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset = header->directory + (index - 1) * header->entry_blob_size;
|
|
|
|
|
|
|
|
|
|
if (typelib->len < offset + sizeof (DirEntry))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-08-24 18:51:43 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (DirEntry *)&typelib->data[offset];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static CommonBlob *
|
2010-08-31 22:36:06 +02:00
|
|
|
|
get_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-08-24 18:51:43 +02:00
|
|
|
|
{
|
|
|
|
|
if (typelib->len < offset + sizeof (CommonBlob))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-08-24 18:51:43 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return (CommonBlob *)&typelib->data[offset];
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
static InterfaceTypeBlob *
|
2010-08-31 22:36:06 +02:00
|
|
|
|
get_type_blob (GITypelib *typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
SimpleTypeBlob *simple,
|
|
|
|
|
GError **error)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
if (simple->offset == 0)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"Expected blob for type");
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-24 23:52:05 +02:00
|
|
|
|
if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"Expected non-basic type but got %d",
|
|
|
|
|
simple->flags.tag);
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
return (InterfaceTypeBlob*) get_blob (typelib, simple->offset, error);
|
2008-08-23 23:30:09 +02:00
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_get_dir_entry:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @index: index to retrieve
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Get the typelib directory entry at the given @index.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: (transfer none): a `DirEntry`
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2008-02-08 16:31:03 +01:00
|
|
|
|
DirEntry *
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_get_dir_entry (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint16_t index)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
Header *header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size];
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-10-25 19:33:01 +02:00
|
|
|
|
static Section *
|
|
|
|
|
get_section_by_id (GITypelib *typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
SectionType section_type)
|
2010-10-25 19:33:01 +02:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header *)typelib->data;
|
|
|
|
|
Section *section;
|
|
|
|
|
|
|
|
|
|
if (header->sections == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (section = (Section*)&typelib->data[header->sections];
|
|
|
|
|
section->id != GI_SECTION_END;
|
|
|
|
|
section++)
|
|
|
|
|
{
|
|
|
|
|
if (section->id == section_type)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return section;
|
2010-10-25 19:33:01 +02:00
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_get_dir_entry_by_name:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @name: name to look up
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Get the typelib directory entry which has @name.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: (transfer none) (nullable): entry corresponding to @name, or `NULL`
|
|
|
|
|
* if none was found
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2010-10-18 18:04:08 +02:00
|
|
|
|
DirEntry *
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_get_dir_entry_by_name (GITypelib *typelib,
|
|
|
|
|
const char *name)
|
2010-10-18 18:04:08 +02:00
|
|
|
|
{
|
2010-10-25 19:33:01 +02:00
|
|
|
|
Section *dirindex;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t i, n_entries;
|
2010-10-25 19:33:01 +02:00
|
|
|
|
const char *entry_name;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
DirEntry *entry;
|
|
|
|
|
|
2010-10-25 19:33:01 +02:00
|
|
|
|
dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
|
2012-05-12 07:44:57 +02:00
|
|
|
|
n_entries = ((Header *)typelib->data)->n_local_entries;
|
2010-10-25 19:33:01 +02:00
|
|
|
|
|
|
|
|
|
if (dirindex == NULL)
|
|
|
|
|
{
|
|
|
|
|
for (i = 1; i <= n_entries; i++)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
entry = gi_typelib_get_dir_entry (typelib, i);
|
|
|
|
|
entry_name = gi_typelib_get_string (typelib, entry->name);
|
|
|
|
|
if (strcmp (name, entry_name) == 0)
|
|
|
|
|
return entry;
|
|
|
|
|
}
|
2010-10-25 19:33:01 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
2010-10-18 18:04:08 +02:00
|
|
|
|
{
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint8_t *hash = (uint8_t *) &typelib->data[dirindex->offset];
|
|
|
|
|
uint16_t index;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
|
index = gi_typelib_hash_search (hash, name, n_entries);
|
2023-11-08 15:17:52 +01:00
|
|
|
|
entry = gi_typelib_get_dir_entry (typelib, index + 1);
|
|
|
|
|
entry_name = gi_typelib_get_string (typelib, entry->name);
|
2010-10-18 18:04:08 +02:00
|
|
|
|
if (strcmp (name, entry_name) == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return entry;
|
2010-10-25 19:33:01 +02:00
|
|
|
|
return NULL;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_get_dir_entry_by_gtype_name:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @gtype_name: name of a [type@GObject.Type] to look up
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Get the typelib directory entry for the [type@GObject.Type] with the given
|
|
|
|
|
* @gtype_name.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: (transfer none) (nullable): entry corresponding to @gtype_name, or
|
|
|
|
|
* `NULL` if none was found
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2010-10-18 18:04:08 +02:00
|
|
|
|
DirEntry *
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib,
|
2024-01-15 20:20:47 +01:00
|
|
|
|
const char *gtype_name)
|
2010-10-18 18:04:08 +02:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header *)typelib->data;
|
|
|
|
|
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 1; i <= header->n_local_entries; i++)
|
2010-10-18 18:04:08 +02:00
|
|
|
|
{
|
|
|
|
|
RegisteredTypeBlob *blob;
|
|
|
|
|
const char *type;
|
2023-11-08 15:17:52 +01:00
|
|
|
|
DirEntry *entry = gi_typelib_get_dir_entry (typelib, i);
|
2010-10-18 18:04:08 +02:00
|
|
|
|
if (!BLOB_IS_REGISTERED_TYPE (entry))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
continue;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
|
|
|
|
|
blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]);
|
|
|
|
|
if (!blob->gtype_name)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
continue;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
type = gi_typelib_get_string (typelib, blob->gtype_name);
|
2010-10-18 18:04:08 +02:00
|
|
|
|
if (strcmp (type, gtype_name) == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return entry;
|
2010-10-18 18:04:08 +02:00
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-07 19:18:29 +02:00
|
|
|
|
typedef struct {
|
|
|
|
|
const char *s;
|
|
|
|
|
const char *separator;
|
2024-01-16 00:35:23 +01:00
|
|
|
|
size_t sep_len;
|
2013-04-07 19:18:29 +02:00
|
|
|
|
GString buf;
|
|
|
|
|
} StrSplitIter;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
strsplit_iter_init (StrSplitIter *iter,
|
|
|
|
|
const char *s,
|
|
|
|
|
const char *separator)
|
|
|
|
|
{
|
|
|
|
|
iter->s = s;
|
|
|
|
|
iter->separator = separator;
|
2013-04-08 21:32:15 +02:00
|
|
|
|
iter->sep_len = strlen (separator);
|
2013-04-07 19:18:29 +02:00
|
|
|
|
iter->buf.str = NULL;
|
|
|
|
|
iter->buf.len = 0;
|
|
|
|
|
iter->buf.allocated_len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
strsplit_iter_next (StrSplitIter *iter,
|
2018-07-29 14:26:44 +02:00
|
|
|
|
const char **out_val)
|
2013-04-07 19:18:29 +02:00
|
|
|
|
{
|
|
|
|
|
const char *s = iter->s;
|
|
|
|
|
const char *next;
|
2024-01-16 00:35:23 +01:00
|
|
|
|
size_t len;
|
2013-04-07 19:18:29 +02:00
|
|
|
|
|
|
|
|
|
if (!s)
|
|
|
|
|
return FALSE;
|
|
|
|
|
next = strstr (s, iter->separator);
|
|
|
|
|
if (next)
|
2013-04-08 20:44:32 +02:00
|
|
|
|
{
|
2013-04-08 21:32:15 +02:00
|
|
|
|
iter->s = next + iter->sep_len;
|
2013-04-08 20:44:32 +02:00
|
|
|
|
len = next - s;
|
|
|
|
|
}
|
2013-04-07 19:18:29 +02:00
|
|
|
|
else
|
2013-04-08 20:44:32 +02:00
|
|
|
|
{
|
|
|
|
|
iter->s = NULL;
|
|
|
|
|
len = strlen (s);
|
|
|
|
|
}
|
2013-04-08 21:32:15 +02:00
|
|
|
|
if (len == 0)
|
|
|
|
|
{
|
|
|
|
|
*out_val = "";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_string_overwrite_len (&iter->buf, 0, s, (gssize)len);
|
|
|
|
|
*out_val = iter->buf.str;
|
|
|
|
|
}
|
2013-04-07 19:18:29 +02:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
strsplit_iter_clear (StrSplitIter *iter)
|
|
|
|
|
{
|
|
|
|
|
g_free (iter->buf.str);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_matches_gtype_name_prefix:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @gtype_name: name of a [type@GObject.Type]
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Check whether the symbol prefix for @typelib is a prefix of the given
|
|
|
|
|
* @gtype_name.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: `TRUE` if the prefix for @typelib prefixes @gtype_name
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
gboolean
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_matches_gtype_name_prefix (GITypelib *typelib,
|
2024-01-15 20:20:47 +01:00
|
|
|
|
const char *gtype_name)
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header *)typelib->data;
|
|
|
|
|
const char *c_prefix;
|
2024-01-15 20:20:47 +01:00
|
|
|
|
const char *prefix;
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
gboolean ret = FALSE;
|
2013-04-07 19:18:29 +02:00
|
|
|
|
StrSplitIter split_iter;
|
2024-01-16 00:35:23 +01:00
|
|
|
|
size_t gtype_name_len;
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
c_prefix = gi_typelib_get_string (typelib, header->c_prefix);
|
2013-04-12 19:39:21 +02:00
|
|
|
|
if (c_prefix == NULL || strlen (c_prefix) == 0)
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2013-04-07 19:18:29 +02:00
|
|
|
|
gtype_name_len = strlen (gtype_name);
|
|
|
|
|
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
/* c_prefix is a comma separated string of supported prefixes
|
|
|
|
|
* in the typelib.
|
|
|
|
|
* We match the specified gtype_name if the gtype_name starts
|
|
|
|
|
* with the prefix, and is followed by a capital letter.
|
|
|
|
|
* For example, a typelib offering the 'Gdk' prefix does match
|
|
|
|
|
* GdkX11Cursor, however a typelib offering the 'G' prefix does not.
|
|
|
|
|
*/
|
2013-04-07 19:18:29 +02:00
|
|
|
|
strsplit_iter_init (&split_iter, c_prefix, ",");
|
|
|
|
|
while (strsplit_iter_next (&split_iter, &prefix))
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
{
|
2013-04-07 19:18:29 +02:00
|
|
|
|
size_t len = strlen (prefix);
|
|
|
|
|
|
|
|
|
|
if (gtype_name_len < len)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (strncmp (prefix, gtype_name, len) != 0)
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2013-04-07 19:18:29 +02:00
|
|
|
|
if (g_ascii_isupper (gtype_name[len]))
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
{
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-07 19:18:29 +02:00
|
|
|
|
strsplit_iter_clear (&split_iter);
|
Optimize g_irepository_find_by_gtype
When g_irepository_find_by_gtype() doesn't succeed on a simple prefix
match (the current 'fastpass' mechanism), it ends up taking a
considerable amount of CPU time, traversing the contents of all typelibs.
I imagine that the reasons to have the exhaustive search fallback are
not as strong as they used to be. For example, the case mentioned
(Clutter including Cogl) no longer seems to be true.
Also, typelibs (as generated by g-ir-scanner) now provide
comma-separated C prefix info for cases when the typelib includes
introspection info for multiple prefixes. For example, the Sugar typelib
has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are
not many remaining justified cases where the exhaustive search is needed.
With that in mind, I found two ways to optimize this function:
1. Support comma-separated C prefixes
2. Don't bother with an exhaustive search if we did find a typelib
claiming support for the prefix. For example, if we're looking for
GdkDeviceManagerXI2 (currently non-introspectable) and we already found
typelib files providing the 'Gdk' prefix that didn't offer this, lets
not bother with the exhaustive search, we aren't going to find anything.
2013-03-19 18:04:42 +01:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_get_dir_entry_by_error_domain:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @error_domain: name of a [type@GLib.Error] domain to look up
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Get the typelib directory entry for the [type@GLib.Error] domain with the
|
|
|
|
|
* given @error_domain name.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: (transfer none) (nullable): entry corresponding to @error_domain, or
|
|
|
|
|
* `NULL` if none was found
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2011-05-19 23:46:36 +02:00
|
|
|
|
DirEntry *
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_get_dir_entry_by_error_domain (GITypelib *typelib,
|
|
|
|
|
GQuark error_domain)
|
2011-05-19 23:46:36 +02:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header *)typelib->data;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t n_entries = header->n_local_entries;
|
2011-05-19 23:46:36 +02:00
|
|
|
|
const char *domain_string = g_quark_to_string (error_domain);
|
|
|
|
|
DirEntry *entry;
|
|
|
|
|
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 1; i <= n_entries; i++)
|
2011-05-19 23:46:36 +02:00
|
|
|
|
{
|
|
|
|
|
EnumBlob *blob;
|
|
|
|
|
const char *enum_domain_string;
|
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
entry = gi_typelib_get_dir_entry (typelib, i);
|
2011-05-19 23:46:36 +02:00
|
|
|
|
if (entry->blob_type != BLOB_TYPE_ENUM)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
continue;
|
2011-05-19 23:46:36 +02:00
|
|
|
|
|
|
|
|
|
blob = (EnumBlob *)(&typelib->data[entry->offset]);
|
|
|
|
|
if (!blob->error_domain)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
continue;
|
2011-05-19 23:46:36 +02:00
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
enum_domain_string = gi_typelib_get_string (typelib, blob->error_domain);
|
2011-05-19 23:46:36 +02:00
|
|
|
|
if (strcmp (domain_string, enum_domain_string) == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return entry;
|
2011-05-19 23:46:36 +02:00
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-16 02:29:53 +01:00
|
|
|
|
/* When changing the size of a typelib structure, you are required to update
|
|
|
|
|
* the hardcoded size here. Do NOT change these to use sizeof(); these
|
|
|
|
|
* should match whatever is defined in the text specification and serve as
|
|
|
|
|
* a sanity check on structure modifications.
|
2023-12-14 02:02:42 +01:00
|
|
|
|
*
|
2024-01-16 02:29:53 +01:00
|
|
|
|
* Everything else in the code however should be using sizeof().
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2024-01-16 02:29:53 +01:00
|
|
|
|
G_STATIC_ASSERT (sizeof (Header) == 112);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (DirEntry) == 12);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (SimpleTypeBlob) == 4);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ArgBlob) == 16);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (SignatureBlob) == 8);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (CommonBlob) == 8);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (FunctionBlob) == 20);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (CallbackBlob) == 12);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (InterfaceTypeBlob) == 4);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ArrayTypeBlob) == 8);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ParamTypeBlob) == 4);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ErrorTypeBlob) == 4);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ValueBlob) == 12);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (FieldBlob) == 16);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (RegisteredTypeBlob) == 16);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (StructBlob) == 32);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (EnumBlob) == 24);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (PropertyBlob) == 16);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (SignalBlob) == 16);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (VFuncBlob) == 20);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ObjectBlob) == 60);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (InterfaceBlob) == 40);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (ConstantBlob) == 24);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (AttributeBlob) == 12);
|
|
|
|
|
G_STATIC_ASSERT (sizeof (UnionBlob) == 40);
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
static gboolean
|
2024-01-15 22:20:02 +01:00
|
|
|
|
is_aligned (uint32_t offset)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
return offset == ALIGN_VALUE (offset, 4);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 18:51:20 +01:00
|
|
|
|
#define MAX_NAME_LEN 2048
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
static const char *
|
2024-01-15 22:20:02 +01:00
|
|
|
|
get_string (GITypelib *typelib, uint32_t offset, GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (typelib->len < offset)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"Buffer is too short while looking up name");
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return NULL;
|
2008-08-21 18:15:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return (const char*)&typelib->data[offset];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
2024-01-15 22:20:02 +01:00
|
|
|
|
get_string_nofail (GITypelib *typelib, uint32_t offset)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
const char *ret = get_string (typelib, offset, NULL);
|
|
|
|
|
g_assert (ret);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_name (GITypelib *typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
const char *msg,
|
2024-01-16 00:10:43 +01:00
|
|
|
|
const uint8_t *data,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
|
|
name = get_string (typelib, offset, error);
|
|
|
|
|
if (!name)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!memchr (name, '\0', MAX_NAME_LEN))
|
2008-08-21 18:15:55 +02:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The %s is too long: %s",
|
|
|
|
|
msg, name);
|
2008-08-21 18:15:55 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
|
|
|
|
if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
|
2008-08-21 18:15:55 +02:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The %s contains invalid characters: '%s'",
|
|
|
|
|
msg, name);
|
2008-08-21 18:15:55 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 17:59:11 +02:00
|
|
|
|
/* Fast path sanity check, operates on a memory blob */
|
2010-03-24 19:00:06 +01:00
|
|
|
|
static gboolean
|
2024-01-15 22:20:02 +01:00
|
|
|
|
validate_header_basic (const uint8_t *memory,
|
2024-01-16 00:35:23 +01:00
|
|
|
|
size_t len,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-07-14 17:59:11 +02:00
|
|
|
|
Header *header = (Header *)memory;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2010-07-14 17:59:11 +02:00
|
|
|
|
if (len < sizeof (Header))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
2024-01-16 00:35:23 +01:00
|
|
|
|
"The specified typelib length %zu is too short", len);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
if (strncmp (header->magic, GI_IR_MAGIC, 16) != 0)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Invalid magic header");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-10-11 18:40:15 +02:00
|
|
|
|
if (header->major_version != 4)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Typelib version mismatch; expected 4, found %d",
|
|
|
|
|
header->major_version);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (header->n_entries < header->n_local_entries)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Inconsistent entry counts");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 17:59:11 +02:00
|
|
|
|
if (header->size != len)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
2024-01-16 00:35:23 +01:00
|
|
|
|
"Typelib size %zu does not match %zu",
|
|
|
|
|
(size_t) header->size, len);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2009-02-06 19:37:13 +01:00
|
|
|
|
/* This is a sanity check for a specific typelib; it
|
2009-02-12 05:36:31 +01:00
|
|
|
|
* prevents us from loading an incompatible typelib.
|
2010-03-24 19:00:06 +01:00
|
|
|
|
*
|
2024-01-16 02:29:53 +01:00
|
|
|
|
* The hardcoded static checks to protect against inadvertent
|
|
|
|
|
* or buggy changes to the typelib format itself.
|
2009-02-06 19:37:13 +01:00
|
|
|
|
*/
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2009-02-12 05:36:31 +01:00
|
|
|
|
if (header->entry_blob_size != sizeof (DirEntry) ||
|
|
|
|
|
header->function_blob_size != sizeof (FunctionBlob) ||
|
|
|
|
|
header->callback_blob_size != sizeof (CallbackBlob) ||
|
|
|
|
|
header->signal_blob_size != sizeof (SignalBlob) ||
|
|
|
|
|
header->vfunc_blob_size != sizeof (VFuncBlob) ||
|
|
|
|
|
header->arg_blob_size != sizeof (ArgBlob) ||
|
|
|
|
|
header->property_blob_size != sizeof (PropertyBlob) ||
|
|
|
|
|
header->field_blob_size != sizeof (FieldBlob) ||
|
|
|
|
|
header->value_blob_size != sizeof (ValueBlob) ||
|
|
|
|
|
header->constant_blob_size != sizeof (ConstantBlob) ||
|
2009-02-20 03:48:51 +01:00
|
|
|
|
header->attribute_blob_size != sizeof (AttributeBlob) ||
|
2009-02-12 05:36:31 +01:00
|
|
|
|
header->signature_blob_size != sizeof (SignatureBlob) ||
|
|
|
|
|
header->enum_blob_size != sizeof (EnumBlob) ||
|
|
|
|
|
header->struct_blob_size != sizeof (StructBlob) ||
|
2009-02-06 19:37:13 +01:00
|
|
|
|
header->object_blob_size != sizeof(ObjectBlob) ||
|
2009-02-12 05:36:31 +01:00
|
|
|
|
header->interface_blob_size != sizeof (InterfaceBlob) ||
|
|
|
|
|
header->union_blob_size != sizeof (UnionBlob))
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Blob size mismatch");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (!is_aligned (header->directory))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Misaligned directory");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
|
if (!is_aligned (header->attributes))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Misaligned attributes");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
|
if (header->attributes == 0 && header->n_attributes > 0)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_HEADER,
|
|
|
|
|
"Wrong number of attributes");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 17:59:11 +02:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
validate_header (ValidateContext *ctx,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2010-07-14 17:59:11 +02:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2010-07-14 17:59:11 +02:00
|
|
|
|
|
|
|
|
|
if (!validate_header_basic (typelib->data, typelib->len, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2010-07-14 17:59:11 +02:00
|
|
|
|
{
|
|
|
|
|
Header *header = (Header*)typelib->data;
|
|
|
|
|
if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-31 22:36:06 +02:00
|
|
|
|
static gboolean validate_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
|
|
|
|
GError **error);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_array_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
/* FIXME validate length */
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + G_STRUCT_OFFSET (ArrayTypeBlob, type),
|
|
|
|
|
0, FALSE, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_iface_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
|
|
|
|
GError **error)
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
{
|
|
|
|
|
InterfaceTypeBlob *blob;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
InterfaceBlob *target;
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (InterfaceTypeBlob*)&typelib->data[offset];
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
target = (InterfaceBlob*) get_dir_entry_checked (typelib, blob->interface, error);
|
|
|
|
|
|
|
|
|
|
if (!target)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (target->blob_type == 0) /* non-local */
|
|
|
|
|
return TRUE;
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_param_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
2024-01-16 02:09:10 +01:00
|
|
|
|
size_t n_params,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
ParamTypeBlob *blob;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ParamTypeBlob*)&typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
if (!blob->pointer)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Pointer type exected for tag %d", blob->tag);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (blob->n_types != n_params)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Parameter type number mismatch");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 02:09:10 +01:00
|
|
|
|
for (size_t i = 0; i < n_params; i++)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + sizeof (ParamTypeBlob) +
|
|
|
|
|
i * sizeof (SimpleTypeBlob),
|
|
|
|
|
0, FALSE, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_error_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
ErrorTypeBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ErrorTypeBlob*)&typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
if (!blob->pointer)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Pointer type exected for tag %d", blob->tag);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_type_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
gboolean return_type,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
SimpleTypeBlob *simple;
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
InterfaceTypeBlob *iface;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
simple = (SimpleTypeBlob *)&typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (simple->flags.reserved == 0 &&
|
2009-06-24 23:52:05 +02:00
|
|
|
|
simple->flags.reserved2 == 0)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2022-02-13 15:35:53 +01:00
|
|
|
|
if (!GI_TYPE_TAG_IS_BASIC(simple->flags.tag))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid non-basic tag %d in simple type", simple->flags.tag);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2009-06-24 23:52:05 +02:00
|
|
|
|
if (simple->flags.tag >= GI_TYPE_TAG_UTF8 &&
|
2024-01-16 17:30:37 +01:00
|
|
|
|
simple->flags.tag != GI_TYPE_TAG_UNICHAR &&
|
|
|
|
|
!simple->flags.pointer)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Pointer type exected for tag %d", simple->flags.tag);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
iface = (InterfaceTypeBlob*)&typelib->data[simple->offset];
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
|
|
|
|
|
switch (iface->tag)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-12 17:34:27 +02:00
|
|
|
|
case GI_TYPE_TAG_ARRAY:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_array_type_blob (typelib, simple->offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
signature_offset, return_type, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
2008-08-12 17:34:27 +02:00
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_iface_type_blob (typelib, simple->offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
signature_offset, return_type, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
2008-08-12 17:34:27 +02:00
|
|
|
|
case GI_TYPE_TAG_GLIST:
|
|
|
|
|
case GI_TYPE_TAG_GSLIST:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_param_type_blob (typelib, simple->offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
signature_offset, return_type, 1, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
2008-08-12 17:34:27 +02:00
|
|
|
|
case GI_TYPE_TAG_GHASH:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_param_type_blob (typelib, simple->offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
signature_offset, return_type, 2, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
2008-08-12 17:34:27 +02:00
|
|
|
|
case GI_TYPE_TAG_ERROR:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_error_type_blob (typelib, simple->offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
signature_offset, return_type, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong tag in complex type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_arg_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t signature_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
ArgBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (ArgBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ArgBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "argument", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + G_STRUCT_OFFSET (ArgBlob, arg_type),
|
|
|
|
|
signature_offset, FALSE, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
static SimpleTypeBlob *
|
2010-08-31 22:36:06 +02:00
|
|
|
|
return_type_from_signature (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
SignatureBlob *blob;
|
|
|
|
|
if (typelib->len < offset + sizeof (SignatureBlob))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blob = (SignatureBlob*) &typelib->data[offset];
|
|
|
|
|
if (blob->return_type.offset == 0)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"No return type found in signature");
|
2008-08-23 23:30:09 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (SignatureBlob, return_type)];
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_signature_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
SignatureBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (SignatureBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (SignatureBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->return_type.offset != 0)
|
|
|
|
|
{
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + G_STRUCT_OFFSET (SignatureBlob, return_type),
|
|
|
|
|
offset, TRUE, error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 0; i < blob->n_arguments; i++)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_arg_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + sizeof (SignatureBlob) +
|
|
|
|
|
i * sizeof (ArgBlob),
|
|
|
|
|
offset,
|
|
|
|
|
error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME check constraints on return_value */
|
|
|
|
|
/* FIXME check array-length pairs */
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_function_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint16_t container_type,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
FunctionBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (FunctionBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (FunctionBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != BLOB_TYPE_FUNCTION)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type %d, expected function", blob->blob_type);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "function", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-08-23 23:30:09 +02:00
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-09-19 16:55:20 +02:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (blob->constructor)
|
|
|
|
|
{
|
|
|
|
|
switch (container_type)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
case BLOB_TYPE_BOXED:
|
|
|
|
|
case BLOB_TYPE_STRUCT:
|
|
|
|
|
case BLOB_TYPE_UNION:
|
|
|
|
|
case BLOB_TYPE_OBJECT:
|
|
|
|
|
case BLOB_TYPE_INTERFACE:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Constructor not allowed");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blob->setter || blob->getter || blob->wraps_vfunc)
|
|
|
|
|
{
|
|
|
|
|
switch (container_type)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
case BLOB_TYPE_OBJECT:
|
|
|
|
|
case BLOB_TYPE_INTERFACE:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Setter, getter or wrapper not allowed");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blob->index)
|
|
|
|
|
{
|
|
|
|
|
if (!(blob->setter || blob->getter || blob->wraps_vfunc))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Must be setter, getter or wrapper");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME: validate index range */
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signature_blob (typelib, blob->signature, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2008-08-23 23:30:09 +02:00
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (blob->constructor)
|
2008-08-23 23:30:09 +02:00
|
|
|
|
{
|
|
|
|
|
SimpleTypeBlob *simple = return_type_from_signature (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
blob->signature,
|
|
|
|
|
error);
|
2008-08-24 18:51:43 +02:00
|
|
|
|
InterfaceTypeBlob *iface_type;
|
|
|
|
|
|
2008-08-23 23:30:09 +02:00
|
|
|
|
if (!simple)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
iface_type = get_type_blob (typelib, simple, error);
|
|
|
|
|
if (!iface_type)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2010-06-09 10:26:26 +02:00
|
|
|
|
if (iface_type->tag != GI_TYPE_TAG_INTERFACE &&
|
|
|
|
|
(container_type == BLOB_TYPE_OBJECT ||
|
|
|
|
|
container_type == BLOB_TYPE_INTERFACE))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"Invalid return type '%s' for constructor '%s'",
|
|
|
|
|
gi_type_tag_to_string (iface_type->tag),
|
|
|
|
|
get_string_nofail (typelib, blob->symbol));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-08-23 23:30:09 +02:00
|
|
|
|
}
|
2008-08-24 18:51:43 +02:00
|
|
|
|
|
|
|
|
|
pop_context (ctx);
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_callback_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
CallbackBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (CallbackBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (CallbackBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != BLOB_TYPE_CALLBACK)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "callback", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
|
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signature_blob (typelib, blob->signature, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
|
|
|
|
|
pop_context (ctx);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_constant_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2024-01-16 02:09:10 +01:00
|
|
|
|
size_t value_size[] = {
|
2008-10-12 01:19:59 +02:00
|
|
|
|
0, /* VOID */
|
|
|
|
|
4, /* BOOLEAN */
|
|
|
|
|
1, /* INT8 */
|
|
|
|
|
1, /* UINT8 */
|
|
|
|
|
2, /* INT16 */
|
|
|
|
|
2, /* UINT16 */
|
|
|
|
|
4, /* INT32 */
|
|
|
|
|
4, /* UINT32 */
|
|
|
|
|
8, /* INT64 */
|
|
|
|
|
8, /* UINT64 */
|
2024-01-15 22:20:02 +01:00
|
|
|
|
sizeof (float),
|
|
|
|
|
sizeof (double),
|
2008-10-12 01:19:59 +02:00
|
|
|
|
0, /* GTYPE */
|
|
|
|
|
0, /* UTF8 */
|
|
|
|
|
0, /* FILENAME */
|
|
|
|
|
0, /* ARRAY */
|
|
|
|
|
0, /* INTERFACE */
|
|
|
|
|
0, /* GLIST */
|
|
|
|
|
0, /* GSLIST */
|
|
|
|
|
0, /* GHASH */
|
|
|
|
|
0, /* ERROR */
|
2010-10-26 17:12:26 +02:00
|
|
|
|
4 /* UNICHAR */
|
2008-10-12 01:19:59 +02:00
|
|
|
|
};
|
2008-02-08 16:31:03 +01:00
|
|
|
|
ConstantBlob *blob;
|
|
|
|
|
SimpleTypeBlob *type;
|
|
|
|
|
|
2010-10-26 17:12:26 +02:00
|
|
|
|
g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_N_TYPES);
|
2010-07-07 20:07:17 +02:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (ConstantBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ConstantBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != BLOB_TYPE_CONSTANT)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "constant", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type),
|
2024-01-16 17:30:37 +01:00
|
|
|
|
0, FALSE, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!is_aligned (blob->offset))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Misaligned constant value");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
|
2009-06-24 23:52:05 +02:00
|
|
|
|
if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2009-06-24 23:52:05 +02:00
|
|
|
|
if (type->flags.tag == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Constant value type void");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2009-06-24 23:52:05 +02:00
|
|
|
|
if (value_size[type->flags.tag] != 0 &&
|
2024-01-16 17:30:37 +01:00
|
|
|
|
blob->size != value_size[type->flags.tag])
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Constant value size mismatch");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
/* FIXME check string values */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_value_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
ValueBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (ValueBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ValueBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "value", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2009-11-09 19:17:23 +01:00
|
|
|
|
validate_field_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2009-11-09 19:17:23 +01:00
|
|
|
|
Header *header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
FieldBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (FieldBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (FieldBlob*) &typelib->data[offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "field", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2009-11-09 19:17:23 +01:00
|
|
|
|
|
|
|
|
|
if (blob->has_embedded_type)
|
|
|
|
|
{
|
|
|
|
|
if (!validate_callback_blob (ctx, offset + header->field_blob_size, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
else if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + G_STRUCT_OFFSET (FieldBlob, type),
|
|
|
|
|
0, FALSE, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_property_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
PropertyBlob *blob;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (PropertyBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (PropertyBlob*) &typelib->data[offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "property", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_type_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset + G_STRUCT_OFFSET (PropertyBlob, type),
|
|
|
|
|
0, FALSE, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_signal_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t container_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
SignalBlob *blob;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t n_signals;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (SignalBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (SignalBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "signal", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if ((blob->run_first != 0) +
|
|
|
|
|
(blob->run_last != 0) +
|
2008-02-08 16:31:03 +01:00
|
|
|
|
(blob->run_cleanup != 0) != 1)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid signal run flags");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blob->has_class_closure)
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
ObjectBlob *object;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
object = (ObjectBlob*)&typelib->data[container_offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
n_signals = object->n_signals;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
InterfaceBlob *iface;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
iface = (InterfaceBlob*)&typelib->data[container_offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
n_signals = iface->n_signals;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->class_closure >= n_signals)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid class closure index");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signature_blob (typelib, blob->signature, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_vfunc_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint32_t container_offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
VFuncBlob *blob;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t n_vfuncs;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (VFuncBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (VFuncBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (blob->class_closure)
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
ObjectBlob *object;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
object = (ObjectBlob*)&typelib->data[container_offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
n_vfuncs = object->n_vfuncs;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
InterfaceBlob *iface;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
iface = (InterfaceBlob*)&typelib->data[container_offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
n_vfuncs = iface->n_vfuncs;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->class_closure >= n_vfuncs)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid class closure index");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signature_blob (typelib, blob->signature, error))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_struct_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint16_t blob_type,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
StructBlob *blob;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t i;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t field_offset;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (StructBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (StructBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != blob_type)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
|
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-09-06 22:33:51 +02:00
|
|
|
|
if (!blob->unregistered)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (blob->gtype_name || blob->gtype_init)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Gtype data in struct");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (typelib->len < offset + sizeof (StructBlob) +
|
2008-02-08 16:31:03 +01:00
|
|
|
|
blob->n_fields * sizeof (FieldBlob) +
|
|
|
|
|
blob->n_methods * sizeof (FunctionBlob))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-09 19:17:23 +01:00
|
|
|
|
field_offset = offset + sizeof (StructBlob);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
for (i = 0; i < blob->n_fields; i++)
|
|
|
|
|
{
|
2018-07-29 15:56:35 +02:00
|
|
|
|
FieldBlob *field_blob = (FieldBlob*) &typelib->data[field_offset];
|
2009-11-09 19:17:23 +01:00
|
|
|
|
|
|
|
|
|
if (!validate_field_blob (ctx,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
field_offset,
|
|
|
|
|
error))
|
|
|
|
|
return FALSE;
|
2009-11-09 19:17:23 +01:00
|
|
|
|
|
|
|
|
|
field_offset += sizeof (FieldBlob);
|
2018-07-29 15:56:35 +02:00
|
|
|
|
if (field_blob->has_embedded_type)
|
2009-11-09 19:17:23 +01:00
|
|
|
|
field_offset += sizeof (CallbackBlob);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_methods; i++)
|
|
|
|
|
{
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_function_blob (ctx,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
field_offset +
|
|
|
|
|
i * sizeof (FunctionBlob),
|
|
|
|
|
blob_type,
|
|
|
|
|
error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
pop_context (ctx);
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-29 20:49:22 +02:00
|
|
|
|
validate_enum_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
|
|
|
|
uint16_t blob_type,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
EnumBlob *blob;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset2;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (EnumBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (EnumBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != blob_type)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (!blob->unregistered)
|
|
|
|
|
{
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (blob->gtype_name || blob->gtype_init)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Gtype data in unregistered enum");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
2008-04-23 00:48:16 +02:00
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "enum", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (typelib->len < offset + sizeof (EnumBlob) +
|
2011-08-13 17:28:30 +02:00
|
|
|
|
blob->n_values * sizeof (ValueBlob) +
|
|
|
|
|
blob->n_methods * sizeof (FunctionBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-08-29 20:49:22 +02:00
|
|
|
|
|
2011-08-13 17:28:30 +02:00
|
|
|
|
offset2 = offset + sizeof (EnumBlob);
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 0; i < blob->n_values; i++, offset2 += sizeof (ValueBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-03-24 19:00:06 +01:00
|
|
|
|
if (!validate_value_blob (typelib,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
offset2,
|
|
|
|
|
error))
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-17 00:26:55 +02:00
|
|
|
|
#if 0
|
2011-08-13 17:28:30 +02:00
|
|
|
|
v1 = (ValueBlob *)&typelib->data[offset2];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
for (j = 0; j < i; j++)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
v2 = (ValueBlob *)&typelib->data[offset2 +
|
2008-02-08 16:31:03 +01:00
|
|
|
|
j * sizeof (ValueBlob)];
|
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
|
if (v1->value == v2->value)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* FIXME should this be an error ? */
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Duplicate enum value");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
#endif
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2008-08-29 20:49:22 +02:00
|
|
|
|
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
|
2011-08-13 17:28:30 +02:00
|
|
|
|
{
|
|
|
|
|
if (!validate_function_blob (ctx, offset2, BLOB_TYPE_ENUM, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2011-08-13 17:28:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
pop_context (ctx);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_object_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
Header *header;
|
|
|
|
|
ObjectBlob *blob;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t i;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset2;
|
|
|
|
|
uint16_t n_field_callbacks;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (ObjectBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (ObjectBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != BLOB_TYPE_OBJECT)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "object", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-08-29 20:49:22 +02:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (blob->parent > header->n_entries)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid parent index");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blob->parent != 0)
|
|
|
|
|
{
|
|
|
|
|
DirEntry *entry;
|
|
|
|
|
|
2009-02-06 19:37:13 +01:00
|
|
|
|
entry = get_dir_entry_checked (typelib, blob->parent, error);
|
|
|
|
|
if (!entry)
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (entry->blob_type != BLOB_TYPE_OBJECT &&
|
2024-01-16 17:30:37 +01:00
|
|
|
|
(entry->local || entry->blob_type != 0))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Parent not object");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2009-02-20 23:34:20 +01:00
|
|
|
|
if (blob->gtype_struct != 0)
|
2009-02-06 19:37:13 +01:00
|
|
|
|
{
|
|
|
|
|
DirEntry *entry;
|
|
|
|
|
|
2009-02-20 23:34:20 +01:00
|
|
|
|
entry = get_dir_entry_checked (typelib, blob->gtype_struct, error);
|
2009-02-06 19:37:13 +01:00
|
|
|
|
if (!entry)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2023-11-08 15:17:52 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
2009-02-06 19:37:13 +01:00
|
|
|
|
"Class struct invalid type or not local");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2009-02-06 19:37:13 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typelib->len < offset + sizeof (ObjectBlob) +
|
2008-02-08 16:31:03 +01:00
|
|
|
|
(blob->n_interfaces + blob->n_interfaces % 2) * 2 +
|
|
|
|
|
blob->n_fields * sizeof (FieldBlob) +
|
|
|
|
|
blob->n_properties * sizeof (PropertyBlob) +
|
|
|
|
|
blob->n_methods * sizeof (FunctionBlob) +
|
|
|
|
|
blob->n_signals * sizeof (SignalBlob) +
|
|
|
|
|
blob->n_vfuncs * sizeof (VFuncBlob) +
|
|
|
|
|
blob->n_constants * sizeof (ConstantBlob))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset2 = offset + sizeof (ObjectBlob);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_interfaces; i++, offset2 += 2)
|
|
|
|
|
{
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint16_t iface;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
DirEntry *entry;
|
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
|
iface = *(uint16_t *)&typelib->data[offset2];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (iface == 0 || iface > header->n_entries)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid interface index");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2009-02-06 19:37:13 +01:00
|
|
|
|
entry = get_dir_entry_checked (typelib, iface, error);
|
|
|
|
|
if (!entry)
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (entry->blob_type != BLOB_TYPE_INTERFACE &&
|
2024-01-16 17:30:37 +01:00
|
|
|
|
(entry->local || entry->blob_type != 0))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Not an interface");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset2 += 2 * (blob->n_interfaces %2);
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2014-02-28 02:10:19 +01:00
|
|
|
|
n_field_callbacks = 0;
|
2014-02-27 11:05:54 +01:00
|
|
|
|
for (i = 0; i < blob->n_fields; i++)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2018-07-29 15:56:35 +02:00
|
|
|
|
FieldBlob *field_blob = (FieldBlob*) &typelib->data[offset2];
|
2014-02-27 11:05:54 +01:00
|
|
|
|
|
2009-11-09 19:17:23 +01:00
|
|
|
|
if (!validate_field_blob (ctx, offset2, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2014-02-27 11:05:54 +01:00
|
|
|
|
|
|
|
|
|
offset2 += sizeof (FieldBlob);
|
|
|
|
|
/* Special case fields which are callbacks. */
|
2018-07-29 15:56:35 +02:00
|
|
|
|
if (field_blob->has_embedded_type) {
|
2014-02-27 11:05:54 +01:00
|
|
|
|
offset2 += sizeof (CallbackBlob);
|
2014-02-28 02:10:19 +01:00
|
|
|
|
n_field_callbacks++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blob->n_field_callbacks != n_field_callbacks)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2023-11-08 15:17:52 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
2014-02-28 02:10:19 +01:00
|
|
|
|
"Incorrect number of field callbacks; expected "
|
2015-10-12 18:15:36 +02:00
|
|
|
|
"%" G_GUINT16_FORMAT ", got %" G_GUINT16_FORMAT,
|
2014-02-28 02:10:19 +01:00
|
|
|
|
blob->n_field_callbacks, n_field_callbacks);
|
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_property_blob (typelib, offset2, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
|
|
|
|
|
{
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_function_blob (ctx, offset2, BLOB_TYPE_OBJECT, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signal_blob (typelib, offset2, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_vfunc_blob (typelib, offset2, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_constant_blob (typelib, offset2, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
pop_context (ctx);
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_interface_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
Header *header;
|
|
|
|
|
InterfaceBlob *blob;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t i;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset2;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (InterfaceBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
blob = (InterfaceBlob*) &typelib->data[offset];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (blob->blob_type != BLOB_TYPE_INTERFACE)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Wrong blob type; expected interface, got %d", blob->blob_type);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "interface", typelib->data, blob->name, error))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (typelib->len < offset + sizeof (InterfaceBlob) +
|
2008-02-08 16:31:03 +01:00
|
|
|
|
(blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
|
|
|
|
|
blob->n_properties * sizeof (PropertyBlob) +
|
|
|
|
|
blob->n_methods * sizeof (FunctionBlob) +
|
|
|
|
|
blob->n_signals * sizeof (SignalBlob) +
|
|
|
|
|
blob->n_vfuncs * sizeof (VFuncBlob) +
|
|
|
|
|
blob->n_constants * sizeof (ConstantBlob))
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset2 = offset + sizeof (InterfaceBlob);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2)
|
|
|
|
|
{
|
|
|
|
|
DirEntry *entry;
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint16_t req;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
|
req = *(uint16_t *)&typelib->data[offset2];
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (req == 0 || req > header->n_entries)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Invalid prerequisite index");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
|
entry = gi_typelib_get_dir_entry (typelib, req);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (entry->blob_type != BLOB_TYPE_INTERFACE &&
|
2024-01-16 17:30:37 +01:00
|
|
|
|
entry->blob_type != BLOB_TYPE_OBJECT &&
|
|
|
|
|
(entry->local || entry->blob_type != 0))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_BLOB,
|
|
|
|
|
"Not an interface or object");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset2 += 2 * (blob->n_prerequisites % 2);
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
push_context (ctx, get_string_nofail (typelib, blob->name));
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_property_blob (typelib, offset2, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
|
|
|
|
|
{
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_function_blob (ctx, offset2, BLOB_TYPE_INTERFACE, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_signal_blob (typelib, offset2, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_vfunc_blob (typelib, offset2, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
|
|
|
|
|
{
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_constant_blob (typelib, offset2, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-08-29 20:49:22 +02:00
|
|
|
|
pop_context (ctx);
|
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2010-08-31 22:36:06 +02:00
|
|
|
|
validate_union_blob (GITypelib *typelib,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_blob (ValidateContext *ctx,
|
2024-01-15 22:20:02 +01:00
|
|
|
|
uint32_t offset,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
CommonBlob *common;
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < offset + sizeof (CommonBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
common = (CommonBlob*)&typelib->data[offset];
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
switch (common->blob_type)
|
|
|
|
|
{
|
|
|
|
|
case BLOB_TYPE_FUNCTION:
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_function_blob (ctx, offset, 0, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_CALLBACK:
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_callback_blob (ctx, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_STRUCT:
|
|
|
|
|
case BLOB_TYPE_BOXED:
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_struct_blob (ctx, offset, common->blob_type, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_ENUM:
|
|
|
|
|
case BLOB_TYPE_FLAGS:
|
2008-08-29 20:49:22 +02:00
|
|
|
|
if (!validate_enum_blob (ctx, offset, common->blob_type, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_OBJECT:
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_object_blob (ctx, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_INTERFACE:
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_interface_blob (ctx, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_CONSTANT:
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_constant_blob (typelib, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
case BLOB_TYPE_UNION:
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (!validate_union_blob (typelib, offset, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2010-03-24 19:00:06 +01:00
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_ENTRY,
|
|
|
|
|
"Invalid blob type");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
|
static gboolean
|
2008-08-24 18:51:43 +02:00
|
|
|
|
validate_directory (ValidateContext *ctx,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-08-09 14:55:32 +02:00
|
|
|
|
Header *header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
DirEntry *entry;
|
2024-01-16 01:57:09 +01:00
|
|
|
|
size_t i;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
if (typelib->len < header->directory + header->n_entries * sizeof (DirEntry))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < header->n_entries; i++)
|
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
|
entry = gi_typelib_get_dir_entry (typelib, i + 1);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-21 18:15:55 +02:00
|
|
|
|
if (!validate_name (typelib, "entry", typelib->data, entry->name, error))
|
2024-01-16 17:30:37 +01:00
|
|
|
|
return FALSE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
|
2024-01-16 17:30:37 +01:00
|
|
|
|
entry->blob_type > BLOB_TYPE_UNION)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_DIRECTORY,
|
|
|
|
|
"Invalid entry type");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
if (i < header->n_local_entries)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
if (!entry->local)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_DIRECTORY,
|
|
|
|
|
"Too few local directory entries");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_aligned (entry->offset))
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_DIRECTORY,
|
|
|
|
|
"Misaligned entry");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validate_blob (ctx, entry->offset, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
|
{
|
|
|
|
|
if (entry->local)
|
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID_DIRECTORY,
|
|
|
|
|
"Too many local directory entries");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2009-02-20 03:48:51 +01:00
|
|
|
|
validate_attributes (ValidateContext *ctx,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *typelib = ctx->typelib;
|
2008-08-09 14:55:32 +02:00
|
|
|
|
Header *header = (Header *)typelib->data;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
|
if (header->size < header->attributes + header->n_attributes * sizeof (AttributeBlob))
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
g_set_error (error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
GI_TYPELIB_ERROR,
|
|
|
|
|
GI_TYPELIB_ERROR_INVALID,
|
|
|
|
|
"The buffer is too short");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
return FALSE;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
static void
|
|
|
|
|
prefix_with_context (GError **error,
|
2024-01-16 17:30:37 +01:00
|
|
|
|
const char *section,
|
|
|
|
|
ValidateContext *ctx)
|
2008-08-24 18:51:43 +02:00
|
|
|
|
{
|
2021-05-20 13:48:34 +02:00
|
|
|
|
GString *str;
|
2008-08-24 18:51:43 +02:00
|
|
|
|
GSList *link;
|
|
|
|
|
char *buf;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
link = ctx->context_stack;
|
|
|
|
|
if (!link)
|
|
|
|
|
{
|
|
|
|
|
g_prefix_error (error, "In %s:", section);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-20 13:48:34 +02:00
|
|
|
|
str = g_string_new (NULL);
|
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
for (; link; link = link->next)
|
|
|
|
|
{
|
|
|
|
|
g_string_append (str, link->data);
|
|
|
|
|
if (link->next)
|
2024-01-16 17:30:37 +01:00
|
|
|
|
g_string_append_c (str, '/');
|
2008-08-24 18:51:43 +02:00
|
|
|
|
}
|
|
|
|
|
g_string_append_c (str, ')');
|
|
|
|
|
buf = g_string_free (str, FALSE);
|
|
|
|
|
g_prefix_error (error, "In %s (Context: %s): ", section, buf);
|
|
|
|
|
g_free (buf);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_validate:
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
|
|
|
|
* @error: return location for a [type@GLib.Error], or `NULL`
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Check whether @typelib is well-formed, i.e. that the file is not corrupt or
|
|
|
|
|
* truncated.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: `TRUE` if @typelib is well-formed, `FALSE` otherwise
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2010-03-24 19:00:06 +01:00
|
|
|
|
gboolean
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_validate (GITypelib *typelib,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2008-08-24 18:51:43 +02:00
|
|
|
|
ValidateContext ctx;
|
|
|
|
|
ctx.typelib = typelib;
|
|
|
|
|
ctx.context_stack = NULL;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_header (&ctx, error))
|
|
|
|
|
{
|
|
|
|
|
prefix_with_context (error, "In header", &ctx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2008-08-24 18:51:43 +02:00
|
|
|
|
if (!validate_directory (&ctx, error))
|
|
|
|
|
{
|
|
|
|
|
prefix_with_context (error, "directory", &ctx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
|
if (!validate_attributes (&ctx, error))
|
2008-08-24 18:51:43 +02:00
|
|
|
|
{
|
2009-02-20 03:48:51 +01:00
|
|
|
|
prefix_with_context (error, "attributes", &ctx);
|
2008-08-24 18:51:43 +02:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_error_quark:
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Get the quark representing the [type@GIRepository.TypelibError] error domain.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: quark representing the error domain
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2008-02-08 16:31:03 +01:00
|
|
|
|
GQuark
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_error_quark (void)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
static GQuark quark = 0;
|
|
|
|
|
if (quark == 0)
|
2023-11-08 15:17:52 +01:00
|
|
|
|
quark = g_quark_from_static_string ("gi-typelib-error-quark");
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return quark;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-22 01:50:48 +01:00
|
|
|
|
/* Note on the GModule flags used by this function:
|
|
|
|
|
|
|
|
|
|
* Glade's autoconnect feature and OpenGL's extension mechanism
|
|
|
|
|
* as used by Clutter rely on g_module_open(NULL) to work as a means of
|
|
|
|
|
* accessing the app's symbols. This keeps us from using
|
|
|
|
|
* G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
|
|
|
|
|
* in general libraries are not expecting multiple copies of
|
|
|
|
|
* themselves and are not expecting to be unloaded. So we just
|
|
|
|
|
* load modules globally for now.
|
|
|
|
|
*/
|
|
|
|
|
static GModule *
|
2024-01-26 11:21:23 +01:00
|
|
|
|
load_one_shared_library (GITypelib *typelib,
|
|
|
|
|
const char *shlib)
|
2013-02-22 01:50:48 +01:00
|
|
|
|
{
|
|
|
|
|
GModule *m;
|
|
|
|
|
|
2021-11-27 20:05:32 +01:00
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
/* On macOS, @-prefixed shlib paths (@rpath, @executable_path, @loader_path)
|
|
|
|
|
need to be treated as absolute; trying to combine them with a
|
|
|
|
|
configured library path produces a mangled path that is unresolvable
|
|
|
|
|
and may cause unintended side effects (such as loading the library
|
|
|
|
|
from a fall-back location on macOS 12.0.1).
|
|
|
|
|
*/
|
|
|
|
|
if (!g_path_is_absolute (shlib) && !g_str_has_prefix (shlib, "@"))
|
|
|
|
|
#else
|
2013-02-22 01:50:48 +01:00
|
|
|
|
if (!g_path_is_absolute (shlib))
|
2021-11-27 20:05:32 +01:00
|
|
|
|
#endif
|
2013-02-22 01:50:48 +01:00
|
|
|
|
{
|
|
|
|
|
/* First try in configured library paths */
|
2024-01-26 11:21:23 +01:00
|
|
|
|
for (unsigned int i = 0; typelib->library_paths != NULL && i < typelib->library_paths->len; i++)
|
2013-02-22 01:50:48 +01:00
|
|
|
|
{
|
2024-01-26 11:21:23 +01:00
|
|
|
|
char *path = g_build_filename (typelib->library_paths->pdata[i], shlib, NULL);
|
2013-02-22 01:50:48 +01:00
|
|
|
|
|
|
|
|
|
m = g_module_open (path, G_MODULE_BIND_LAZY);
|
|
|
|
|
|
|
|
|
|
g_free (path);
|
|
|
|
|
if (m != NULL)
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Then try loading from standard paths */
|
|
|
|
|
/* Do not attempt to fix up shlib to replace .la with .so:
|
|
|
|
|
it's done by GModule anyway.
|
|
|
|
|
*/
|
|
|
|
|
return g_module_open (shlib, G_MODULE_BIND_LAZY);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-18 16:23:09 +02:00
|
|
|
|
static void
|
2023-11-08 16:23:31 +01:00
|
|
|
|
gi_typelib_do_dlopen (GITypelib *typelib)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
|
|
|
|
Header *header;
|
2009-08-18 16:23:09 +02:00
|
|
|
|
const char *shlib_str;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2008-08-09 14:55:32 +02:00
|
|
|
|
header = (Header *) typelib->data;
|
2009-08-18 16:23:09 +02:00
|
|
|
|
/* note that NULL shlib means to open the main app, which is allowed */
|
2008-02-08 16:31:03 +01:00
|
|
|
|
if (header->shared_library)
|
2023-11-08 15:17:52 +01:00
|
|
|
|
shlib_str = gi_typelib_get_string (typelib, header->shared_library);
|
2009-08-18 16:23:09 +02:00
|
|
|
|
else
|
|
|
|
|
shlib_str = NULL;
|
|
|
|
|
|
|
|
|
|
if (shlib_str != NULL && shlib_str[0] != '\0')
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2024-01-15 20:20:47 +01:00
|
|
|
|
char **shlibs;
|
2008-04-23 03:04:43 +02:00
|
|
|
|
|
2009-08-18 16:23:09 +02:00
|
|
|
|
/* shared-library is a comma-separated list of libraries */
|
|
|
|
|
shlibs = g_strsplit (shlib_str, ",", 0);
|
2008-04-23 03:17:24 +02:00
|
|
|
|
|
2009-08-18 16:23:09 +02:00
|
|
|
|
/* We load all passed libs unconditionally as if the same library is loaded
|
2010-05-19 18:53:48 +02:00
|
|
|
|
* again with g_module_open(), the same file handle will be returned. See bug:
|
2009-08-18 16:23:09 +02:00
|
|
|
|
* http://bugzilla.gnome.org/show_bug.cgi?id=555294
|
|
|
|
|
*/
|
2024-01-16 01:57:09 +01:00
|
|
|
|
for (size_t i = 0; shlibs[i]; i++)
|
2008-04-23 03:17:24 +02:00
|
|
|
|
{
|
2009-08-18 16:23:09 +02:00
|
|
|
|
GModule *module;
|
|
|
|
|
|
2024-01-26 11:21:23 +01:00
|
|
|
|
module = load_one_shared_library (typelib, shlibs[i]);
|
2008-10-07 23:25:01 +02:00
|
|
|
|
|
2009-08-18 16:23:09 +02:00
|
|
|
|
if (module == NULL)
|
|
|
|
|
{
|
|
|
|
|
g_warning ("Failed to load shared library '%s' referenced by the typelib: %s",
|
|
|
|
|
shlibs[i], g_module_error ());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
typelib->modules = g_list_append (typelib->modules, module);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_strfreev (shlibs);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2009-08-18 16:23:09 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* If there's no shared-library entry for this module, assume that
|
|
|
|
|
* the module is for the application. Some of the hand-written .gir files
|
|
|
|
|
* in gobject-introspection don't have shared-library entries, but no one
|
|
|
|
|
* is really going to be calling g_module_symbol on them either.
|
|
|
|
|
*/
|
|
|
|
|
GModule *module = g_module_open (NULL, 0);
|
|
|
|
|
if (module == NULL)
|
|
|
|
|
g_warning ("gtypelib.c: Failed to g_module_open (NULL): %s", g_module_error ());
|
|
|
|
|
else
|
|
|
|
|
typelib->modules = g_list_prepend (typelib->modules, module);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
2023-11-08 16:23:31 +01:00
|
|
|
|
gi_typelib_ensure_open (GITypelib *typelib)
|
2009-08-18 16:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
if (typelib->open_attempted)
|
|
|
|
|
return;
|
|
|
|
|
typelib->open_attempted = TRUE;
|
2023-11-08 16:23:31 +01:00
|
|
|
|
gi_typelib_do_dlopen (typelib);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-01-26 10:49:56 +01:00
|
|
|
|
* gi_typelib_new_from_bytes:
|
|
|
|
|
* @bytes: memory chunk containing the typelib
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* @error: a [type@GLib.Error]
|
2010-03-24 19:00:06 +01:00
|
|
|
|
*
|
2024-01-26 10:49:56 +01:00
|
|
|
|
* Creates a new [type@GIRepository.Typelib] from a [type@GLib.Bytes].
|
2023-11-09 01:06:57 +01:00
|
|
|
|
*
|
2024-01-26 10:49:56 +01:00
|
|
|
|
* The [type@GLib.Bytes] can point to a memory location or a mapped file, and
|
|
|
|
|
* the typelib will hold a reference to it until the repository is destroyed.
|
2010-03-24 19:00:06 +01:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: (transfer full): the new [type@GIRepository.Typelib]
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *
|
2024-01-26 10:49:56 +01:00
|
|
|
|
gi_typelib_new_from_bytes (GBytes *bytes,
|
|
|
|
|
GError **error)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2010-08-31 22:36:06 +02:00
|
|
|
|
GITypelib *meta;
|
2024-01-26 10:49:56 +01:00
|
|
|
|
size_t len;
|
|
|
|
|
const uint8_t *data = g_bytes_get_data (bytes, &len);
|
2010-07-14 17:59:11 +02:00
|
|
|
|
|
|
|
|
|
if (!validate_header_basic (data, len, error))
|
|
|
|
|
return NULL;
|
2008-02-08 16:31:03 +01:00
|
|
|
|
|
2010-08-31 22:36:06 +02:00
|
|
|
|
meta = g_slice_new0 (GITypelib);
|
2024-02-07 15:38:05 +01:00
|
|
|
|
g_atomic_ref_count_init (&meta->ref_count);
|
2024-01-26 10:49:56 +01:00
|
|
|
|
meta->bytes = g_bytes_ref (bytes);
|
|
|
|
|
meta->data = data;
|
2010-07-14 17:59:11 +02:00
|
|
|
|
meta->len = len;
|
2024-01-26 10:49:56 +01:00
|
|
|
|
meta->modules = NULL;
|
2009-08-18 16:23:09 +02:00
|
|
|
|
|
2008-02-08 16:31:03 +01:00
|
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-02-07 15:38:05 +01:00
|
|
|
|
* gi_typelib_ref:
|
|
|
|
|
* @typelib: (transfer none): a #GITypelib
|
|
|
|
|
*
|
|
|
|
|
* Increment the reference count of a [type@GIRepository.Typelib].
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer full): the same @typelib pointer
|
|
|
|
|
* Since: 2.80
|
|
|
|
|
*/
|
|
|
|
|
GITypelib *
|
|
|
|
|
gi_typelib_ref (GITypelib *typelib)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (typelib != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
g_atomic_ref_count_inc (&typelib->ref_count);
|
|
|
|
|
|
|
|
|
|
return typelib;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gi_typelib_unref:
|
2023-11-09 01:09:45 +01:00
|
|
|
|
* @typelib: (transfer full): a #GITypelib
|
2010-03-24 19:00:06 +01:00
|
|
|
|
*
|
2024-02-07 15:38:05 +01:00
|
|
|
|
* Decrement the reference count of a [type@GIRepository.Typelib].
|
|
|
|
|
*
|
|
|
|
|
* Once the reference count reaches zero, the typelib is freed.
|
2023-11-09 01:06:57 +01:00
|
|
|
|
*
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2008-02-08 16:31:03 +01:00
|
|
|
|
void
|
2024-02-07 15:38:05 +01:00
|
|
|
|
gi_typelib_unref (GITypelib *typelib)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2024-02-07 15:38:05 +01:00
|
|
|
|
g_return_if_fail (typelib != NULL);
|
2024-01-26 11:21:23 +01:00
|
|
|
|
|
2024-02-07 15:38:05 +01:00
|
|
|
|
if (g_atomic_ref_count_dec (&typelib->ref_count))
|
2008-10-07 23:25:01 +02:00
|
|
|
|
{
|
2024-02-07 15:38:05 +01:00
|
|
|
|
g_clear_pointer (&typelib->bytes, g_bytes_unref);
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&typelib->library_paths, g_ptr_array_unref);
|
|
|
|
|
|
|
|
|
|
if (typelib->modules)
|
|
|
|
|
{
|
|
|
|
|
g_list_foreach (typelib->modules, (GFunc) (void *) g_module_close, NULL);
|
|
|
|
|
g_list_free (typelib->modules);
|
|
|
|
|
}
|
|
|
|
|
g_slice_free (GITypelib, typelib);
|
2008-10-07 23:25:01 +02:00
|
|
|
|
}
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 22:21:18 +02:00
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_get_namespace:
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* @typelib: a #GITypelib
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* Get the name of the namespace represented by @typelib.
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* Returns: name of the namespace represented by @typelib
|
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2024-01-15 20:20:47 +01:00
|
|
|
|
const char *
|
2023-11-08 15:17:52 +01:00
|
|
|
|
gi_typelib_get_namespace (GITypelib *typelib)
|
2008-02-08 16:31:03 +01:00
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
|
return gi_typelib_get_string (typelib, ((Header *) typelib->data)->namespace);
|
2008-02-08 16:31:03 +01:00
|
|
|
|
}
|
2008-10-07 23:25:01 +02:00
|
|
|
|
|
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
|
* gi_typelib_symbol:
|
2009-02-12 04:32:25 +01:00
|
|
|
|
* @typelib: the typelib
|
2008-10-07 23:25:01 +02:00
|
|
|
|
* @symbol_name: name of symbol to be loaded
|
2023-11-09 01:09:45 +01:00
|
|
|
|
* @symbol: (out) (nullable): returns a pointer to the symbol value, or `NULL`
|
|
|
|
|
* on failure
|
2008-10-07 23:25:01 +02:00
|
|
|
|
*
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* Loads a symbol from a `GITypelib`.
|
2008-10-07 23:25:01 +02:00
|
|
|
|
*
|
2023-12-14 02:02:42 +01:00
|
|
|
|
* Returns: `TRUE` on success
|
2023-11-09 01:06:57 +01:00
|
|
|
|
* Since: 2.80
|
2013-10-10 22:21:18 +02:00
|
|
|
|
*/
|
2008-10-07 23:25:01 +02:00
|
|
|
|
gboolean
|
2024-01-15 20:16:00 +01:00
|
|
|
|
gi_typelib_symbol (GITypelib *typelib, const char *symbol_name, void **symbol)
|
2008-10-07 23:25:01 +02:00
|
|
|
|
{
|
|
|
|
|
GList *l;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
|
gi_typelib_ensure_open (typelib);
|
2008-10-07 23:25:01 +02:00
|
|
|
|
|
|
|
|
|
/*
|
2009-08-18 16:23:09 +02:00
|
|
|
|
* The reason for having multiple modules dates from gir-repository
|
|
|
|
|
* when it was desired to inject code (accessors, etc.) into an
|
|
|
|
|
* existing library. In that situation, the first module listed
|
|
|
|
|
* will be the custom one, which overrides the main one. A bit
|
|
|
|
|
* inefficient, but the problem will go away when gir-repository
|
|
|
|
|
* does.
|
2010-03-24 19:00:06 +01:00
|
|
|
|
*
|
2009-08-18 16:23:09 +02:00
|
|
|
|
* For modules with no shared library, we dlopen'd the current
|
2010-03-24 19:00:06 +01:00
|
|
|
|
* process above.
|
2008-10-07 23:25:01 +02:00
|
|
|
|
*/
|
|
|
|
|
for (l = typelib->modules; l; l = l->next)
|
|
|
|
|
{
|
|
|
|
|
GModule *module = l->data;
|
|
|
|
|
|
|
|
|
|
if (g_module_symbol (module, symbol_name, symbol))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|