Hi all, I noticed that Balsa emits a critical warning on the console, e.g. when I select an encrypted message, but cancel the decryption: GLib-GIO-CRITICAL **: g_content_type_guess: assertion 'data_size != (gsize) -1' failed Looking into the details, this message originates from balsa-mime-widget.c, function balsa_mime_widget_new_unknown(), line 260 ff. Apparently, in the case above, reading data from the stream fails (g_mime_stream_read() returns -1), but libbalsa_vfs_content_type_of_buffer() is called with the broken data. However, I wonder why this code does *not* crash: (1) the buffer is allocated with a size of 1k, (2) g_mime_stream_read() tries to fill it completely, so it is *not* NUL-terminated, but (3) if libbalsa_vfs_content_type_of_buffer() guesses a text/* type, libbalsa_text_attr_string() is called which assumes a NUL-terminated string. The attached patch fixes both issues by - checking if g_mime_stream_read() failed, and assuming application/octet-stream in this case and - assuring that the buffer is always NUL-terminated. Cheers, Albrecht.
diff --git a/src/balsa-mime-widget.c b/src/balsa-mime-widget.c index 3375c24..fdd11a9 100644 --- a/src/balsa-mime-widget.c +++ b/src/balsa-mime-widget.c @@ -249,7 +249,6 @@ balsa_mime_widget_new_unknown(BalsaMessage * bm, g_ascii_strcasecmp(content_type, "application/octet-stream") == 0) && LIBBALSA_IS_MAILBOX_LOCAL(mime_body->message->mailbox)) { GError *err = NULL; - gpointer buffer; GMimeStream *stream = libbalsa_message_body_get_stream(mime_body, &err); if(!stream) { @@ -259,20 +258,25 @@ balsa_mime_widget_new_unknown(BalsaMessage * bm, g_clear_error(&err); use_content_type = g_strdup(content_type); } else { + gpointer buffer; ssize_t length = 1024 /* g_mime_stream_length(stream) */ ; ssize_t size; - buffer = g_malloc(length); + buffer = g_malloc0(length + 1); libbalsa_mime_stream_shared_lock(stream); size = g_mime_stream_read(stream, buffer, length); libbalsa_mime_stream_shared_unlock(stream); g_object_unref(stream); - use_content_type = libbalsa_vfs_content_type_of_buffer(buffer, size); - if (g_ascii_strncasecmp(use_content_type, "text", 4) == 0 - && (libbalsa_text_attr_string(buffer) & LIBBALSA_TEXT_HI_BIT)) { - /* Hmmm...better stick with application/octet-stream. */ - g_free(use_content_type); - use_content_type = g_strdup("application/octet-stream"); + if (size != -1) { + use_content_type = libbalsa_vfs_content_type_of_buffer(buffer, size); + if (g_ascii_strncasecmp(use_content_type, "text", 4) == 0 + && (libbalsa_text_attr_string(buffer) & LIBBALSA_TEXT_HI_BIT)) { + /* Hmmm...better stick with application/octet-stream. */ + g_free(use_content_type); + use_content_type = g_strdup("application/octet-stream"); + } + } else { + use_content_type = g_strdup("application/octet-stream"); } g_free(buffer); }
Attachment:
pgpiO4PTxjlGD.pgp
Description: PGP signature