mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 17:56:17 +01:00
gdbusmessage: Add more bounds checking when parsing D-Bus messages
Perform strict bounds checking when reading data from the D-Bus message, and propagate errors to the callers. Previously, truncated D-Bus messages could cause out-of-bounds reads. This is a security issue, but one which is only exploitable when communicating with an untrusted peer (who might send malicious messages). Almost all D-Bus traffic is with a session or system bus, where the dbus-daemon or dbus-broker is trusted, and is known to have already rejected malformed (malicious) messages. Accordingly, this is only exploitable with peer-to-peer D-Bus conversations with an untrusted peer. (Includes some minor cleanups from Philip Withnall.) oss-fuzz#17408 Fixes: #2528
This commit is contained in:
parent
9aaaf719da
commit
4b9a27a868
@ -83,21 +83,36 @@ g_memory_buffer_is_byteswapped (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guchar
|
static guchar
|
||||||
g_memory_buffer_read_byte (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_byte (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, 0);
|
||||||
|
|
||||||
if (mbuf->pos >= mbuf->valid_len)
|
if (mbuf->pos >= mbuf->valid_len)
|
||||||
return 0;
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading byte.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return mbuf->data [mbuf->pos++];
|
return mbuf->data [mbuf->pos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint16
|
static gint16
|
||||||
g_memory_buffer_read_int16 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_int16 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
gint16 v;
|
gint16 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 2)
|
if (mbuf->pos > mbuf->valid_len - 2)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading int16.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,13 +126,19 @@ g_memory_buffer_read_int16 (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guint16
|
static guint16
|
||||||
g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
guint16 v;
|
guint16 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, 0);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 2)
|
if (mbuf->pos > mbuf->valid_len - 2)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading uint16.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,13 +152,19 @@ g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gint32
|
static gint32
|
||||||
g_memory_buffer_read_int32 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_int32 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
gint32 v;
|
gint32 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 4)
|
if (mbuf->pos > mbuf->valid_len - 4)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading int32.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,13 +178,19 @@ g_memory_buffer_read_int32 (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
guint32 v;
|
guint32 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, 0);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 4)
|
if (mbuf->pos > mbuf->valid_len - 4)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading uint32.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,13 +204,19 @@ g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gint64
|
static gint64
|
||||||
g_memory_buffer_read_int64 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_int64 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
gint64 v;
|
gint64 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 8)
|
if (mbuf->pos > mbuf->valid_len - 8)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading int64.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,13 +230,19 @@ g_memory_buffer_read_int64 (GMemoryBuffer *mbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guint64
|
static guint64
|
||||||
g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf)
|
g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
guint64 v;
|
guint64 v;
|
||||||
|
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, 0);
|
||||||
|
|
||||||
if (mbuf->pos > mbuf->valid_len - 8)
|
if (mbuf->pos > mbuf->valid_len - 8)
|
||||||
{
|
{
|
||||||
mbuf->pos = mbuf->valid_len;
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Unexpected end of message while reading uint64.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,7 +1545,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
gboolean v;
|
gboolean v;
|
||||||
v = g_memory_buffer_read_uint32 (buf);
|
v = g_memory_buffer_read_uint32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_boolean (v);
|
ret = g_variant_new_boolean (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1509,7 +1556,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
guchar v;
|
guchar v;
|
||||||
v = g_memory_buffer_read_byte (buf);
|
v = g_memory_buffer_read_byte (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_byte (v);
|
ret = g_variant_new_byte (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1519,7 +1568,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
gint16 v;
|
gint16 v;
|
||||||
v = g_memory_buffer_read_int16 (buf);
|
v = g_memory_buffer_read_int16 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_int16 (v);
|
ret = g_variant_new_int16 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1529,7 +1580,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
guint16 v;
|
guint16 v;
|
||||||
v = g_memory_buffer_read_uint16 (buf);
|
v = g_memory_buffer_read_uint16 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_uint16 (v);
|
ret = g_variant_new_uint16 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1539,7 +1592,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
gint32 v;
|
gint32 v;
|
||||||
v = g_memory_buffer_read_int32 (buf);
|
v = g_memory_buffer_read_int32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_int32 (v);
|
ret = g_variant_new_int32 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1549,7 +1604,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
guint32 v;
|
guint32 v;
|
||||||
v = g_memory_buffer_read_uint32 (buf);
|
v = g_memory_buffer_read_uint32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_uint32 (v);
|
ret = g_variant_new_uint32 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1559,7 +1616,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
gint64 v;
|
gint64 v;
|
||||||
v = g_memory_buffer_read_int64 (buf);
|
v = g_memory_buffer_read_int64 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_int64 (v);
|
ret = g_variant_new_int64 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1569,7 +1628,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
guint64 v;
|
guint64 v;
|
||||||
v = g_memory_buffer_read_uint64 (buf);
|
v = g_memory_buffer_read_uint64 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_uint64 (v);
|
ret = g_variant_new_uint64 (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1583,7 +1644,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
gdouble v_double;
|
gdouble v_double;
|
||||||
} u;
|
} u;
|
||||||
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
|
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
|
||||||
u.v_uint64 = g_memory_buffer_read_uint64 (buf);
|
u.v_uint64 = g_memory_buffer_read_uint64 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_double (u.v_double);
|
ret = g_variant_new_double (u.v_double);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1594,7 +1657,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
{
|
{
|
||||||
guint32 len;
|
guint32 len;
|
||||||
const gchar *v;
|
const gchar *v;
|
||||||
len = g_memory_buffer_read_uint32 (buf);
|
len = g_memory_buffer_read_uint32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
v = read_string (buf, (gsize) len, &local_error);
|
v = read_string (buf, (gsize) len, &local_error);
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1608,7 +1673,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
{
|
{
|
||||||
guint32 len;
|
guint32 len;
|
||||||
const gchar *v;
|
const gchar *v;
|
||||||
len = g_memory_buffer_read_uint32 (buf);
|
len = g_memory_buffer_read_uint32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
v = read_string (buf, (gsize) len, &local_error);
|
v = read_string (buf, (gsize) len, &local_error);
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1630,7 +1697,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
{
|
{
|
||||||
guchar len;
|
guchar len;
|
||||||
const gchar *v;
|
const gchar *v;
|
||||||
len = g_memory_buffer_read_byte (buf);
|
len = g_memory_buffer_read_byte (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
v = read_string (buf, (gsize) len, &local_error);
|
v = read_string (buf, (gsize) len, &local_error);
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1652,7 +1721,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
if (!just_align)
|
if (!just_align)
|
||||||
{
|
{
|
||||||
gint32 v;
|
gint32 v;
|
||||||
v = g_memory_buffer_read_int32 (buf);
|
v = g_memory_buffer_read_int32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
ret = g_variant_new_handle (v);
|
ret = g_variant_new_handle (v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1672,7 +1743,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
const GVariantType *element_type;
|
const GVariantType *element_type;
|
||||||
guint fixed_size;
|
guint fixed_size;
|
||||||
|
|
||||||
array_len = g_memory_buffer_read_uint32 (buf);
|
array_len = g_memory_buffer_read_uint32 (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
#ifdef DEBUG_SERIALIZER
|
#ifdef DEBUG_SERIALIZER
|
||||||
is_leaf = FALSE;
|
is_leaf = FALSE;
|
||||||
@ -1880,7 +1953,9 @@ parse_value_from_blob (GMemoryBuffer *buf,
|
|||||||
GVariantType *variant_type;
|
GVariantType *variant_type;
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
|
|
||||||
siglen = g_memory_buffer_read_byte (buf);
|
siglen = g_memory_buffer_read_byte (buf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
sig = read_string (buf, (gsize) siglen, &local_error);
|
sig = read_string (buf, (gsize) siglen, &local_error);
|
||||||
if (sig == NULL)
|
if (sig == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -2078,7 +2153,7 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
GDBusCapabilityFlags capabilities,
|
GDBusCapabilityFlags capabilities,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
GError *local_error = NULL;
|
||||||
GMemoryBuffer mbuf;
|
GMemoryBuffer mbuf;
|
||||||
GDBusMessage *message;
|
GDBusMessage *message;
|
||||||
guchar endianness;
|
guchar endianness;
|
||||||
@ -2091,8 +2166,6 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
|
|
||||||
/* TODO: check against @capabilities */
|
/* TODO: check against @capabilities */
|
||||||
|
|
||||||
ret = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (blob != NULL, NULL);
|
g_return_val_if_fail (blob != NULL, NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
g_return_val_if_fail (blob_len >= 12, NULL);
|
g_return_val_if_fail (blob_len >= 12, NULL);
|
||||||
@ -2103,7 +2176,10 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
mbuf.data = (gchar *)blob;
|
mbuf.data = (gchar *)blob;
|
||||||
mbuf.len = mbuf.valid_len = blob_len;
|
mbuf.len = mbuf.valid_len = blob_len;
|
||||||
|
|
||||||
endianness = g_memory_buffer_read_byte (&mbuf);
|
endianness = g_memory_buffer_read_byte (&mbuf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
switch (endianness)
|
switch (endianness)
|
||||||
{
|
{
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -2115,28 +2191,38 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
|
message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error (error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value 0x%02x"),
|
_("Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value 0x%02x"),
|
||||||
endianness);
|
endianness);
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
message->type = g_memory_buffer_read_byte (&mbuf);
|
message->type = g_memory_buffer_read_byte (&mbuf, &local_error);
|
||||||
message->flags = g_memory_buffer_read_byte (&mbuf);
|
if (local_error)
|
||||||
major_protocol_version = g_memory_buffer_read_byte (&mbuf);
|
goto fail;
|
||||||
|
message->flags = g_memory_buffer_read_byte (&mbuf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
|
major_protocol_version = g_memory_buffer_read_byte (&mbuf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
if (major_protocol_version != 1)
|
if (major_protocol_version != 1)
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Invalid major protocol version. Expected 1 but found %d"),
|
_("Invalid major protocol version. Expected 1 but found %d"),
|
||||||
major_protocol_version);
|
major_protocol_version);
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
message_body_len = g_memory_buffer_read_uint32 (&mbuf);
|
message_body_len = g_memory_buffer_read_uint32 (&mbuf, &local_error);
|
||||||
message->serial = g_memory_buffer_read_uint32 (&mbuf);
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
|
message->serial = g_memory_buffer_read_uint32 (&mbuf, &local_error);
|
||||||
|
if (local_error)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
#ifdef DEBUG_SERIALIZER
|
#ifdef DEBUG_SERIALIZER
|
||||||
g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len);
|
g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len);
|
||||||
@ -2156,9 +2242,9 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
G_DBUS_MAX_TYPE_DEPTH + 2 /* for the a{yv} */,
|
G_DBUS_MAX_TYPE_DEPTH + 2 /* for the a{yv} */,
|
||||||
FALSE,
|
FALSE,
|
||||||
2,
|
2,
|
||||||
error);
|
&local_error);
|
||||||
if (headers == NULL)
|
if (headers == NULL)
|
||||||
goto out;
|
goto fail;
|
||||||
g_variant_iter_init (&iter, headers);
|
g_variant_iter_init (&iter, headers);
|
||||||
while ((item = g_variant_iter_next_value (&iter)) != NULL)
|
while ((item = g_variant_iter_next_value (&iter)) != NULL)
|
||||||
{
|
{
|
||||||
@ -2182,11 +2268,11 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
|
|
||||||
if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
|
if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
|
||||||
{
|
{
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Signature header found but is not of type signature"));
|
_("Signature header found but is not of type signature"));
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
signature_str = g_variant_get_string (signature, &signature_str_len);
|
signature_str = g_variant_get_string (signature, &signature_str_len);
|
||||||
@ -2194,12 +2280,12 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
/* signature but no body */
|
/* signature but no body */
|
||||||
if (message_body_len == 0 && signature_str_len > 0)
|
if (message_body_len == 0 && signature_str_len > 0)
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Signature header with signature “%s” found but message body is empty"),
|
_("Signature header with signature “%s” found but message body is empty"),
|
||||||
signature_str);
|
signature_str);
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if (signature_str_len > 0)
|
else if (signature_str_len > 0)
|
||||||
{
|
{
|
||||||
@ -2209,13 +2295,13 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
if (!g_variant_is_signature (signature_str) ||
|
if (!g_variant_is_signature (signature_str) ||
|
||||||
!g_variant_type_string_is_valid (tupled_signature_str))
|
!g_variant_type_string_is_valid (tupled_signature_str))
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Parsed value “%s” is not a valid D-Bus signature (for body)"),
|
_("Parsed value “%s” is not a valid D-Bus signature (for body)"),
|
||||||
signature_str);
|
signature_str);
|
||||||
g_free (tupled_signature_str);
|
g_free (tupled_signature_str);
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
variant_type = g_variant_type_new (tupled_signature_str);
|
variant_type = g_variant_type_new (tupled_signature_str);
|
||||||
@ -2228,10 +2314,10 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
G_DBUS_MAX_TYPE_DEPTH + 1 /* for the surrounding tuple */,
|
G_DBUS_MAX_TYPE_DEPTH + 1 /* for the surrounding tuple */,
|
||||||
FALSE,
|
FALSE,
|
||||||
2,
|
2,
|
||||||
error);
|
&local_error);
|
||||||
g_variant_type_free (variant_type);
|
g_variant_type_free (variant_type);
|
||||||
if (message->body == NULL)
|
if (message->body == NULL)
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2240,7 +2326,7 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
if (message_body_len != 0)
|
if (message_body_len != 0)
|
||||||
{
|
{
|
||||||
/* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
|
/* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
|
||||||
g_set_error (error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
g_dngettext (GETTEXT_PACKAGE,
|
g_dngettext (GETTEXT_PACKAGE,
|
||||||
@ -2248,29 +2334,22 @@ g_dbus_message_new_from_blob (guchar *blob,
|
|||||||
"No signature header in message but the message body is %u bytes",
|
"No signature header in message but the message body is %u bytes",
|
||||||
message_body_len),
|
message_body_len),
|
||||||
message_body_len);
|
message_body_len);
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validate_headers (message, error))
|
if (!validate_headers (message, &local_error))
|
||||||
{
|
{
|
||||||
g_prefix_error (error, _("Cannot deserialize message: "));
|
g_prefix_error (&local_error, _("Cannot deserialize message: "));
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
return message;
|
||||||
|
|
||||||
out:
|
fail:
|
||||||
if (ret)
|
g_clear_object (&message);
|
||||||
{
|
g_propagate_error (error, local_error);
|
||||||
return message;
|
return NULL;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (message != NULL)
|
|
||||||
g_object_unref (message);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
Loading…
Reference in New Issue
Block a user