[glib] GDBusMessage: Validate UTF-8 strings when serializing from blob
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GDBusMessage: Validate UTF-8 strings when serializing from blob
- Date: Wed, 4 Aug 2010 15:27:32 +0000 (UTC)
commit 5bd34a820eb79f0765e312215e0a3e0a339ace78
Author: David Zeuthen <davidz redhat com>
Date: Wed Aug 4 11:26:48 2010 -0400
GDBusMessage: Validate UTF-8 strings when serializing from blob
Signed-off-by: David Zeuthen <davidz redhat com>
gio/gdbusmessage.c | 24 +++++++++-
gio/tests/gdbus-serialization.c | 88 +++++++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+), 3 deletions(-)
---
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index b435d6f..afdd2a4 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -728,6 +728,7 @@ read_string (GMemoryInputStream *mis,
gsize remaining;
guchar nul;
GError *local_error;
+ const gchar *end_valid;
s = g_string_new (NULL);
@@ -767,13 +768,30 @@ read_string (GMemoryInputStream *mis,
g_propagate_error (error, local_error);
goto fail;
}
+ if (!g_utf8_validate (s->str, -1, &end_valid))
+ {
+ gint offset;
+ gchar *valid_str;
+ offset = (gint) (end_valid - s->str);
+ valid_str = g_strndup (s->str, offset);
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). "
+ "The valid UTF-8 string up until that that point was `%s'"),
+ offset,
+ (gint) s->len,
+ valid_str);
+ g_free (valid_str);
+ goto fail;
+ }
if (nul != '\0')
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
- _("Expected NUL byte after the string `%s' but found `%c' (%d)"),
- s->str, nul, nul);
+ _("Expected NUL byte after the string `%s' but found byte %d"),
+ s->str, nul);
goto fail;
}
@@ -1051,7 +1069,7 @@ parse_value_from_blob (GMemoryInputStream *mis,
g_set_error (&local_error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
- _("Encountered array of length %u bytes. Maximum length is 2<<26 bytes."),
+ _("Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."),
array_len);
goto fail;
}
diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c
index 2cb80ce..0268c54 100644
--- a/gio/tests/gdbus-serialization.c
+++ b/gio/tests/gdbus-serialization.c
@@ -705,6 +705,93 @@ message_serialize_complex (void)
/* ---------------------------------------------------------------------------------------------------- */
+static void
+message_serialize_invalid (void)
+{
+ guint n;
+
+ /* Here we're relying on libdbus-1's DBusMessage type not checking
+ * anything. If that were to change, we'd need to do our own
+ * thing.
+ *
+ * Other things we could check (note that GDBus _does_ check for all
+ * these things - we just don't have test-suit coverage for it)
+ *
+ * - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
+ * this, e.g.
+ *
+ * process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect,
+ * assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)"
+ * failed in file dbus-message.c line 2344.
+ * This is normally a bug in some application using the D-Bus library.
+ * D-Bus not built with -rdynamic so unable to print a backtrace
+ * Aborted (core dumped)
+ *
+ * - message exceeding 128 MiB (2^27 bytes)
+ *
+ * - endianness, message type, flags, protocol version
+ */
+
+ for (n = 0; n < 3; n++)
+ {
+ GDBusMessage *message;
+ GError *error;
+ DBusMessage *dbus_message;
+ char *blob;
+ int blob_len;
+ const gchar *invalid_utf8_str = "this is invalid\xff";
+ const gchar *invalid_object_path = "/this/is/not a valid object path";
+ const gchar *invalid_signature = "not valid signature";
+
+ dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
+ dbus_message_set_serial (dbus_message, 0x41);
+ dbus_message_set_path (dbus_message, "/foo/bar");
+ dbus_message_set_member (dbus_message, "Member");
+ switch (n)
+ {
+ case 0:
+ /* invalid UTF-8 */
+ dbus_message_append_args (dbus_message,
+ DBUS_TYPE_STRING, &invalid_utf8_str,
+ DBUS_TYPE_INVALID);
+ break;
+
+ case 1:
+ /* invalid object path */
+ dbus_message_append_args (dbus_message,
+ DBUS_TYPE_OBJECT_PATH, &invalid_object_path,
+ DBUS_TYPE_INVALID);
+ break;
+
+ case 2:
+ /* invalid signature */
+ dbus_message_append_args (dbus_message,
+ DBUS_TYPE_SIGNATURE, &invalid_signature,
+ DBUS_TYPE_INVALID);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ dbus_message_marshal (dbus_message, &blob, &blob_len);
+
+ error = NULL;
+ message = g_dbus_message_new_from_blob ((guchar *) blob,
+ blob_len,
+ G_DBUS_CAPABILITY_FLAGS_NONE,
+ &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ g_error_free (error);
+ g_assert (message == NULL);
+
+ dbus_free (blob);
+ }
+
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
int
main (int argc,
char *argv[])
@@ -714,6 +801,7 @@ main (int argc,
g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic);
g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex);
+ g_test_add_func ("/gdbus/message-serialize-invalid", message_serialize_invalid);
return g_test_run();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]