mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 16:26:17 +01:00
gvariant-serialiser: Factor out functions for dealing with framing offsets
This introduces no functional changes. Helps: #2121
This commit is contained in:
parent
1deacdd4e8
commit
446e69f5ed
@ -635,30 +635,62 @@ gvs_calculate_total_size (gsize body_size,
|
|||||||
return body_size + 8 * offsets;
|
return body_size + 8 * offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gsize
|
struct Offsets
|
||||||
gvs_variable_sized_array_n_children (GVariantSerialised value)
|
|
||||||
{
|
{
|
||||||
|
gsize data_size;
|
||||||
|
|
||||||
|
guchar *array;
|
||||||
|
gsize length;
|
||||||
|
guint offset_size;
|
||||||
|
|
||||||
|
gboolean is_normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
gvs_offsets_get_offset_n (struct Offsets *offsets,
|
||||||
|
gsize n)
|
||||||
|
{
|
||||||
|
return gvs_read_unaligned_le (
|
||||||
|
offsets->array + (offsets->offset_size * n), offsets->offset_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct Offsets
|
||||||
|
gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value)
|
||||||
|
{
|
||||||
|
struct Offsets out = { 0, };
|
||||||
gsize offsets_array_size;
|
gsize offsets_array_size;
|
||||||
gsize offset_size;
|
|
||||||
gsize last_end;
|
gsize last_end;
|
||||||
|
|
||||||
if (value.size == 0)
|
if (value.size == 0)
|
||||||
return 0;
|
{
|
||||||
|
out.is_normal = TRUE;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
offset_size = gvs_get_offset_size (value.size);
|
out.offset_size = gvs_get_offset_size (value.size);
|
||||||
|
last_end = gvs_read_unaligned_le (value.data + value.size - out.offset_size,
|
||||||
last_end = gvs_read_unaligned_le (value.data + value.size -
|
out.offset_size);
|
||||||
offset_size, offset_size);
|
|
||||||
|
|
||||||
if (last_end > value.size)
|
if (last_end > value.size)
|
||||||
return 0;
|
return out; /* offsets not normal */
|
||||||
|
|
||||||
offsets_array_size = value.size - last_end;
|
offsets_array_size = value.size - last_end;
|
||||||
|
|
||||||
if (offsets_array_size % offset_size)
|
if (offsets_array_size % out.offset_size)
|
||||||
return 0;
|
return out; /* offsets not normal */
|
||||||
|
|
||||||
return offsets_array_size / offset_size;
|
out.data_size = last_end;
|
||||||
|
out.array = value.data + last_end;
|
||||||
|
out.length = offsets_array_size / out.offset_size;
|
||||||
|
out.is_normal = TRUE;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
gvs_variable_sized_array_n_children (GVariantSerialised value)
|
||||||
|
{
|
||||||
|
return gvs_variable_sized_array_get_frame_offsets (value).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GVariantSerialised
|
static GVariantSerialised
|
||||||
@ -666,8 +698,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
|
|||||||
gsize index_)
|
gsize index_)
|
||||||
{
|
{
|
||||||
GVariantSerialised child = { 0, };
|
GVariantSerialised child = { 0, };
|
||||||
gsize offset_size;
|
|
||||||
gsize last_end;
|
struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value);
|
||||||
|
|
||||||
gsize start;
|
gsize start;
|
||||||
gsize end;
|
gsize end;
|
||||||
|
|
||||||
@ -675,18 +708,11 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
|
|||||||
g_variant_type_info_ref (child.type_info);
|
g_variant_type_info_ref (child.type_info);
|
||||||
child.depth = value.depth + 1;
|
child.depth = value.depth + 1;
|
||||||
|
|
||||||
offset_size = gvs_get_offset_size (value.size);
|
|
||||||
|
|
||||||
last_end = gvs_read_unaligned_le (value.data + value.size -
|
|
||||||
offset_size, offset_size);
|
|
||||||
|
|
||||||
if (index_ > 0)
|
if (index_ > 0)
|
||||||
{
|
{
|
||||||
guint alignment;
|
guint alignment;
|
||||||
|
|
||||||
start = gvs_read_unaligned_le (value.data + last_end +
|
start = gvs_offsets_get_offset_n (&offsets, index_ - 1);
|
||||||
(offset_size * (index_ - 1)),
|
|
||||||
offset_size);
|
|
||||||
|
|
||||||
g_variant_type_info_query (child.type_info, &alignment, NULL);
|
g_variant_type_info_query (child.type_info, &alignment, NULL);
|
||||||
start += (-start) & alignment;
|
start += (-start) & alignment;
|
||||||
@ -694,11 +720,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
|
|||||||
else
|
else
|
||||||
start = 0;
|
start = 0;
|
||||||
|
|
||||||
end = gvs_read_unaligned_le (value.data + last_end +
|
end = gvs_offsets_get_offset_n (&offsets, index_);
|
||||||
(offset_size * index_),
|
|
||||||
offset_size);
|
|
||||||
|
|
||||||
if (start < end && end <= value.size && end <= last_end)
|
if (start < end && end <= value.size && end <= offsets.data_size)
|
||||||
{
|
{
|
||||||
child.data = value.data + start;
|
child.data = value.data + start;
|
||||||
child.size = end - start;
|
child.size = end - start;
|
||||||
@ -770,34 +794,16 @@ static gboolean
|
|||||||
gvs_variable_sized_array_is_normal (GVariantSerialised value)
|
gvs_variable_sized_array_is_normal (GVariantSerialised value)
|
||||||
{
|
{
|
||||||
GVariantSerialised child = { 0, };
|
GVariantSerialised child = { 0, };
|
||||||
gsize offsets_array_size;
|
|
||||||
guchar *offsets_array;
|
|
||||||
guint offset_size;
|
|
||||||
guint alignment;
|
guint alignment;
|
||||||
gsize last_end;
|
|
||||||
gsize length;
|
|
||||||
gsize offset;
|
gsize offset;
|
||||||
gsize i;
|
gsize i;
|
||||||
|
|
||||||
if (value.size == 0)
|
struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
offset_size = gvs_get_offset_size (value.size);
|
if (!offsets.is_normal)
|
||||||
last_end = gvs_read_unaligned_le (value.data + value.size -
|
|
||||||
offset_size, offset_size);
|
|
||||||
|
|
||||||
if (last_end > value.size)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
offsets_array_size = value.size - last_end;
|
if (value.size != 0 && offsets.length == 0)
|
||||||
|
|
||||||
if (offsets_array_size % offset_size)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
offsets_array = value.data + value.size - offsets_array_size;
|
|
||||||
length = offsets_array_size / offset_size;
|
|
||||||
|
|
||||||
if (length == 0)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
child.type_info = g_variant_type_info_element (value.type_info);
|
child.type_info = g_variant_type_info_element (value.type_info);
|
||||||
@ -805,14 +811,14 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
|
|||||||
child.depth = value.depth + 1;
|
child.depth = value.depth + 1;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < offsets.length; i++)
|
||||||
{
|
{
|
||||||
gsize this_end;
|
gsize this_end;
|
||||||
|
|
||||||
this_end = gvs_read_unaligned_le (offsets_array + offset_size * i,
|
this_end = gvs_read_unaligned_le (offsets.array + offsets.offset_size * i,
|
||||||
offset_size);
|
offsets.offset_size);
|
||||||
|
|
||||||
if (this_end < offset || this_end > last_end)
|
if (this_end < offset || this_end > offsets.data_size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
while (offset & alignment)
|
while (offset & alignment)
|
||||||
@ -834,7 +840,7 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
|
|||||||
offset = this_end;
|
offset = this_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (offset == last_end);
|
g_assert (offset == offsets.data_size);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user