girnode: Improve int types in GIIrNodeField

`GIIrNodeField` is built dynamically at runtime (rather than being
mmapped from disk), so its types can accurately reflect their runtime
semantics, rather than an on-disk format.

As part of this, switch from `atoi()` to `g_ascii_string_to_unsigned()`
for parsing the relevant fields from a GIR XML file. This means we now
get error handling for invalid integers.

This also includes some offset validity changes which were forgotten
from commit 515b3fc1dc.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3155
This commit is contained in:
Philip Withnall 2024-01-26 09:20:07 +00:00
parent 48d9f356c3
commit 501ff95cea
4 changed files with 18 additions and 7 deletions

View File

@ -252,8 +252,9 @@ struct _GIIrNodeField
uint8_t readable : 1; uint8_t readable : 1;
uint8_t writable : 1; uint8_t writable : 1;
int bits; unsigned int bits;
int offset; size_t offset;
GIIrOffsetsState offset_state;
GIIrNodeFunction *callback; /* (owned) */ GIIrNodeFunction *callback; /* (owned) */
GIIrNodeType *type; /* (owned) */ GIIrNodeType *type; /* (owned) */

View File

@ -1601,7 +1601,7 @@ gi_ir_node_build_typelib (GIIrNode *node,
blob->writable = field->writable; blob->writable = field->writable;
blob->reserved = 0; blob->reserved = 0;
blob->bits = 0; blob->bits = 0;
if (field->offset >= 0) if (field->offset_state == GI_IR_OFFSETS_COMPUTED)
blob->struct_offset = field->offset; blob->struct_offset = field->offset;
else else
blob->struct_offset = 0xFFFF; /* mark as unknown */ blob->struct_offset = 0xFFFF; /* mark as unknown */

View File

@ -392,6 +392,7 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
size = GI_ALIGN (size, member_alignment); size = GI_ALIGN (size, member_alignment);
alignment = MAX (alignment, member_alignment); alignment = MAX (alignment, member_alignment);
field->offset = size; field->offset = size;
field->offset_state = GI_IR_OFFSETS_COMPUTED;
size += member_size; size += member_size;
} }
else else
@ -399,7 +400,10 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
} }
if (have_error) if (have_error)
field->offset = -1; {
field->offset = 0;
field->offset_state = GI_IR_OFFSETS_FAILED;
}
} }
else if (member->type == GI_IR_NODE_CALLBACK) else if (member->type == GI_IR_NODE_CALLBACK)
{ {

View File

@ -1366,6 +1366,7 @@ start_field (GMarkupParseContext *context,
GIIrNodeField *field; GIIrNodeField *field;
ParseState target_state; ParseState target_state;
gboolean introspectable; gboolean introspectable;
guint64 parsed_bits;
switch (ctx->state) switch (ctx->state)
{ {
@ -1428,10 +1429,15 @@ start_field (GMarkupParseContext *context,
field->readable = readable == NULL || strcmp (readable, "0") == 0; field->readable = readable == NULL || strcmp (readable, "0") == 0;
field->writable = writable != NULL && strcmp (writable, "1") == 0; field->writable = writable != NULL && strcmp (writable, "1") == 0;
if (bits) if (bits == NULL)
field->bits = atoi (bits);
else
field->bits = 0; field->bits = 0;
else if (g_ascii_string_to_unsigned (bits, 10, 0, G_MAXUINT, &parsed_bits, error))
field->bits = parsed_bits;
else
{
gi_ir_node_free ((GIIrNode *) field);
return FALSE;
}
switch (CURRENT_NODE (ctx)->type) switch (CURRENT_NODE (ctx)->type)
{ {