gvariant: Re-use g_variant_serialised_check() to check alignment

Rather than duplicating the alignment checks when constructing a new
GVariant, re-use the alignment checks from GVariantSerialised. This
ensures that the same checks are done everywhere in the GVariant code.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/glib/issues/1342
This commit is contained in:
Philip Withnall 2018-11-06 11:43:43 +00:00
parent 7b0f2e0e34
commit 409ff69bd1
3 changed files with 25 additions and 16 deletions

View File

@ -523,6 +523,7 @@ g_variant_new_from_bytes (const GVariantType *type,
guint alignment; guint alignment;
gsize size; gsize size;
GBytes *owned_bytes = NULL; GBytes *owned_bytes = NULL;
GVariantSerialised serialised;
value = g_variant_alloc (type, TRUE, trusted); value = g_variant_alloc (type, TRUE, trusted);
@ -535,7 +536,11 @@ g_variant_new_from_bytes (const GVariantType *type,
* only cause an abort on some architectures so is unlikely to be caught * only cause an abort on some architectures so is unlikely to be caught
* in testing). Callers can always actively ensure they use the correct * in testing). Callers can always actively ensure they use the correct
* alignment to avoid the performance hit. */ * alignment to avoid the performance hit. */
if ((alignment & (gsize) g_bytes_get_data (bytes, NULL)) != 0) serialised.type_info = value->type_info;
serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size);
serialised.depth = 0;
if (!g_variant_serialised_check (serialised))
{ {
#ifdef HAVE_POSIX_MEMALIGN #ifdef HAVE_POSIX_MEMALIGN
gpointer aligned_data = NULL; gpointer aligned_data = NULL;

View File

@ -127,20 +127,24 @@
* *
* Checks @serialised for validity according to the invariants described * Checks @serialised for validity according to the invariants described
* above. * above.
*
* Returns: %TRUE if @serialised is valid; %FALSE otherwise
*/ */
static void gboolean
g_variant_serialised_check (GVariantSerialised serialised) g_variant_serialised_check (GVariantSerialised serialised)
{ {
gsize fixed_size; gsize fixed_size;
guint alignment; guint alignment;
g_assert (serialised.type_info != NULL); if (serialised.type_info == NULL)
return FALSE;
g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size); g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size);
if (fixed_size) if (fixed_size != 0 && serialised.size != fixed_size)
g_assert_cmpint (serialised.size, ==, fixed_size); return FALSE;
else else if (fixed_size == 0 &&
g_assert (serialised.size == 0 || serialised.data != NULL); !(serialised.size == 0 || serialised.data != NULL))
return FALSE;
/* Depending on the native alignment requirements of the machine, the /* Depending on the native alignment requirements of the machine, the
* compiler will insert either 3 or 7 padding bytes after the char. * compiler will insert either 3 or 7 padding bytes after the char.
@ -167,10 +171,8 @@ g_variant_serialised_check (GVariantSerialised serialised)
* Check if this is a small allocation and return without enforcing * Check if this is a small allocation and return without enforcing
* the alignment assertion if this is the case. * the alignment assertion if this is the case.
*/ */
if (serialised.size <= alignment) return (serialised.size <= alignment ||
return; (alignment & (gsize) serialised.data) == 0);
g_assert_cmpint (alignment & (gsize) serialised.data, ==, 0);
} }
/* < private > /* < private >
@ -1355,7 +1357,7 @@ gvs_variant_is_normal (GVariantSerialised value)
gsize gsize
g_variant_serialised_n_children (GVariantSerialised serialised) g_variant_serialised_n_children (GVariantSerialised serialised)
{ {
g_variant_serialised_check (serialised); g_assert (g_variant_serialised_check (serialised));
DISPATCH_CASES (serialised.type_info, DISPATCH_CASES (serialised.type_info,
@ -1392,7 +1394,7 @@ g_variant_serialised_get_child (GVariantSerialised serialised,
{ {
GVariantSerialised child; GVariantSerialised child;
g_variant_serialised_check (serialised); g_assert (g_variant_serialised_check (serialised));
if G_LIKELY (index_ < g_variant_serialised_n_children (serialised)) if G_LIKELY (index_ < g_variant_serialised_n_children (serialised))
{ {
@ -1400,7 +1402,7 @@ g_variant_serialised_get_child (GVariantSerialised serialised,
child = gvs_/**/,/**/_get_child (serialised, index_); child = gvs_/**/,/**/_get_child (serialised, index_);
g_assert (child.size || child.data == NULL); g_assert (child.size || child.data == NULL);
g_variant_serialised_check (child); g_assert (g_variant_serialised_check (child));
return child; return child;
) )
@ -1441,7 +1443,7 @@ g_variant_serialiser_serialise (GVariantSerialised serialised,
const gpointer *children, const gpointer *children,
gsize n_children) gsize n_children)
{ {
g_variant_serialised_check (serialised); g_assert (g_variant_serialised_check (serialised));
DISPATCH_CASES (serialised.type_info, DISPATCH_CASES (serialised.type_info,
@ -1496,7 +1498,7 @@ g_variant_serialised_byteswap (GVariantSerialised serialised)
gsize fixed_size; gsize fixed_size;
guint alignment; guint alignment;
g_variant_serialised_check (serialised); g_assert (g_variant_serialised_check (serialised));
if (!serialised.data) if (!serialised.data)
return; return;

View File

@ -55,6 +55,8 @@ void g_variant_serialiser_serialise (GVarian
gsize n_children); gsize n_children);
/* misc */ /* misc */
GLIB_AVAILABLE_IN_2_60
gboolean g_variant_serialised_check (GVariantSerialised serialised);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
gboolean g_variant_serialised_is_normal (GVariantSerialised value); gboolean g_variant_serialised_is_normal (GVariantSerialised value);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL