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