mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-31 04:43:06 +02:00
gvariant-core: Don’t call posix_memalign() with size==0
While glibc is fine with it (and returns a `NULL` pointer), technically it’s implementation-defined behaviour according to POSIX, so it’s best avoided. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html. In particular, valgrind will warn about it, which is causing failures of the gdbus-codegen tests when valgrind is enabled. For example, https://gitlab.gnome.org/GNOME/glib/-/jobs/3460673 gives ``` ==15276== posix_memalign() invalid size value: 0 ==15276== at 0x484B7BC: posix_memalign (vg_replace_malloc.c:2099) ==15276== by 0x49320B2: g_variant_new_from_bytes (gvariant-core.c:629) ==15276== by 0x4931853: g_variant_new_from_data (gvariant.c:6226) ==15276== by 0x4B9A951: g_dbus_gvalue_to_gvariant (gdbusutils.c:708) ==15276== by 0x41BD15: _foo_igen_bat_skeleton_handle_get_property (gdbus-test-codegen-generated.c:13503) ==15276== by 0x41BFAF: foo_igen_bat_skeleton_dbus_interface_get_properties (gdbus-test-codegen-generated.c:13582) … ``` Signed-off-by: Philip Withnall <pwithnall@gnome.org> Helps: #3228
This commit is contained in:
parent
554eb407de
commit
635f8d43eb
@ -625,8 +625,14 @@ g_variant_new_from_bytes (const GVariantType *type,
|
|||||||
|
|
||||||
/* posix_memalign() requires the alignment to be a multiple of
|
/* posix_memalign() requires the alignment to be a multiple of
|
||||||
* sizeof(void*), and a power of 2. See g_variant_type_info_query() for
|
* sizeof(void*), and a power of 2. See g_variant_type_info_query() for
|
||||||
* details on the alignment format. */
|
* details on the alignment format.
|
||||||
if (posix_memalign (&aligned_data, MAX (sizeof (void *), alignment + 1),
|
*
|
||||||
|
* While calling posix_memalign() with aligned_size==0 is safe on glibc,
|
||||||
|
* POSIX specifies that the behaviour is implementation-defined, so avoid
|
||||||
|
* that and leave aligned_data==NULL in that case.
|
||||||
|
* See https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html */
|
||||||
|
if (aligned_size != 0 &&
|
||||||
|
posix_memalign (&aligned_data, MAX (sizeof (void *), alignment + 1),
|
||||||
aligned_size) != 0)
|
aligned_size) != 0)
|
||||||
g_error ("posix_memalign failed");
|
g_error ("posix_memalign failed");
|
||||||
|
|
||||||
|
@ -1337,12 +1337,15 @@ flavoured_free (gpointer data,
|
|||||||
static gpointer
|
static gpointer
|
||||||
align_malloc (gsize size)
|
align_malloc (gsize size)
|
||||||
{
|
{
|
||||||
gpointer mem;
|
gpointer mem = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_POSIX_MEMALIGN
|
#ifdef HAVE_POSIX_MEMALIGN
|
||||||
/* posix_memalign() requires the alignment to be a multiple of
|
/* posix_memalign() requires the alignment to be a multiple of
|
||||||
* sizeof(void*), and a power of 2. */
|
* sizeof(void*), and a power of 2.
|
||||||
if (posix_memalign (&mem, MAX (sizeof (void *), 8), size))
|
* Calling it with size==0 leads to implementation-defined behaviour, so avoid
|
||||||
|
* that and guarantee to return NULL. */
|
||||||
|
if (size != 0 &&
|
||||||
|
posix_memalign (&mem, MAX (sizeof (void *), 8), size))
|
||||||
g_error ("posix_memalign failed");
|
g_error ("posix_memalign failed");
|
||||||
#else
|
#else
|
||||||
/* NOTE: there may be platforms that lack posix_memalign() and also
|
/* NOTE: there may be platforms that lack posix_memalign() and also
|
||||||
@ -4959,6 +4962,12 @@ test_gbytes (void)
|
|||||||
g_bytes_unref (bytes2);
|
g_bytes_unref (bytes2);
|
||||||
g_variant_unref (a);
|
g_variant_unref (a);
|
||||||
g_variant_unref (tuple);
|
g_variant_unref (tuple);
|
||||||
|
|
||||||
|
bytes = g_bytes_new (NULL, 0);
|
||||||
|
a = g_variant_new_from_bytes (G_VARIANT_TYPE ("as"), bytes, TRUE);
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
g_assert_cmpuint (g_variant_n_children (a), ==, 0);
|
||||||
|
g_variant_unref (a);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user