[geary/mjog/crash-sending-multipart] Geary.RFC822.Message: Fix `get_body()` critical with multipart messages
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/crash-sending-multipart] Geary.RFC822.Message: Fix `get_body()` critical with multipart messages
- Date: Mon, 3 Aug 2020 04:17:18 +0000 (UTC)
commit fdef80998cc2faa57a537426ba3cfda999056069
Author: Michael Gratton <mike vee net>
Date: Mon Aug 3 14:13:34 2020 +1000
Geary.RFC822.Message: Fix `get_body()` critical with multipart messages
Fixes a bad assumption MR !534 made about GMime structure and causing
a crash on sending multipart messages. Add unit tests to cover this
case.
src/engine/rfc822/rfc822-message.vala | 24 +++++++++++--
test/engine/api/geary-email-test.vala | 52 +++++++++++++++++++++++++++++
test/engine/rfc822/rfc822-message-test.vala | 30 +++++++++++++++--
test/meson.build | 3 +-
test/test-engine.vala | 1 +
5 files changed, 103 insertions(+), 7 deletions(-)
---
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index 61a0f3d66..e995f430b 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -624,11 +624,29 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
}
/**
- * Returns the possibly body of the message.
+ * Returns the body of the message.
*/
public Text get_body() {
- GMime.Part part = (GMime.Part) this.message.get_mime_part();
- return new Text.from_gmime(part.get_content().get_stream());
+ Text? body = null;
+ GMime.Object? gmime = this.message.get_mime_part();
+ if (gmime != null) {
+ var stream = new GMime.StreamMem();
+
+ // GMime doens't support writing content-only via the
+ // public API, so suppress all headers in the message
+ // instead.
+ GMime.FormatOptions options = Geary.RFC822.get_format_options().clone();
+ GMime.HeaderList headers = message.get_header_list();
+ int count = headers.get_count();
+ for (int i = 0; i < count; i++) {
+ options.add_hidden_header(headers.get_header_at(i).get_name());
+ }
+ gmime.write_to_stream(options, stream);
+ body = new Text.from_gmime(stream);
+ } else {
+ body = new Text(Memory.EmptyBuffer.instance);
+ }
+ return body;
}
/**
diff --git a/test/engine/api/geary-email-test.vala b/test/engine/api/geary-email-test.vala
new file mode 100644
index 000000000..d52f929d3
--- /dev/null
+++ b/test/engine/api/geary-email-test.vala
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2020 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+class Geary.EmailTest: TestCase {
+
+
+ private const string BASIC_TEXT_PLAIN = "basic-text-plain.eml";
+ private const string BASIC_MULTIPART_ALTERNATIVE =
+ "basic-multipart-alternative.eml";
+
+
+ public EmailTest() {
+ base("Geary.EmailTest");
+ add_test("email_from_basic_message", email_from_basic_message);
+ add_test("email_from_multipart", email_from_multipart);
+ }
+
+ public void email_from_basic_message() throws GLib.Error {
+ var message = resource_to_message(BASIC_TEXT_PLAIN);
+ var email = new Email.from_message(new MockEmailIdentifer(0), message);
+
+ assert_non_null(email);
+ assert_non_null(email.subject);
+ assert_equal(email.subject.to_string(), "Re: Basic text/plain message");
+ }
+
+ public void email_from_multipart() throws GLib.Error {
+ var message = resource_to_message(BASIC_MULTIPART_ALTERNATIVE);
+ var email = new Email.from_message(new MockEmailIdentifer(0), message);
+
+ assert_non_null(email);
+ assert_non_null(email.subject);
+ assert_equal(email.subject.to_string(), "Re: Basic text/html message");
+ }
+
+ private RFC822.Message resource_to_message(string path) throws GLib.Error {
+ GLib.File resource =
+ GLib.File.new_for_uri(RESOURCE_URI).resolve_relative_path(path);
+
+ uint8[] contents;
+ resource.load_contents(null, out contents, null);
+
+ return new RFC822.Message.from_buffer(
+ new Geary.Memory.ByteBuffer(contents, contents.length)
+ );
+ }
+
+}
diff --git a/test/engine/rfc822/rfc822-message-test.vala b/test/engine/rfc822/rfc822-message-test.vala
index 2d151ba39..083ea3d43 100644
--- a/test/engine/rfc822/rfc822-message-test.vala
+++ b/test/engine/rfc822/rfc822-message-test.vala
@@ -54,7 +54,8 @@ This is the second line.
add_test("multipart_alternative_as_html",
multipart_alternative_as_html);
add_test("get_header", get_header);
- add_test("get_body", get_body);
+ add_test("get_body_single_part", get_body_single_part);
+ add_test("get_body_multipart", get_body_multipart);
add_test("get_preview", get_preview);
add_test("get_recipients", get_recipients);
add_test("get_searchable_body", get_searchable_body);
@@ -185,10 +186,33 @@ This is the second line.
assert(header.get_header("From") == "Alice <alice example net>");
}
- public void get_body() throws GLib.Error {
+ public void get_body_single_part() throws GLib.Error {
Message message = resource_to_message(BASIC_TEXT_PLAIN);
Text body = message.get_body();
- assert(body.buffer.to_string().replace("\r", "") == BASIC_PLAIN_BODY);
+ assert_string(
+ body.buffer.to_string().replace("\r", "")
+ ).contains(
+ // should contain the body
+ BASIC_PLAIN_BODY
+ ).not_contains(
+ // should not contain headers (like the subject)
+ "Re: Basic text/plain message"
+ );
+ }
+
+ public void get_body_multipart() throws GLib.Error {
+ Message message = resource_to_message(BASIC_MULTIPART_ALTERNATIVE);
+ Text body = message.get_body();
+
+ assert_string(
+ body.buffer.to_string().replace("\r", "")
+ ).contains(
+ // should contain the body
+ BASIC_PLAIN_BODY
+ ).not_contains(
+ // should not contain headers (like the subject)
+ "Re: Basic text/html message"
+ );
}
public void get_preview() throws GLib.Error {
diff --git a/test/meson.build b/test/meson.build
index aec82e3f4..4ccfbd0f5 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -21,10 +21,11 @@ geary_test_engine_sources = [
'engine/api/geary-account-information-test.vala',
'engine/api/geary-attachment-test.vala',
+ 'engine/api/geary-composed-email-test.vala',
+ 'engine/api/geary-email-test.vala',
'engine/api/geary-engine-test.vala',
'engine/api/geary-folder-path-test.vala',
'engine/api/geary-service-information-test.vala',
- 'engine/api/geary-composed-email-test.vala',
'engine/app/app-conversation-test.vala',
'engine/app/app-conversation-monitor-test.vala',
'engine/app/app-conversation-set-test.vala',
diff --git a/test/test-engine.vala b/test/test-engine.vala
index 82d728b0f..483163deb 100644
--- a/test/test-engine.vala
+++ b/test/test-engine.vala
@@ -90,6 +90,7 @@ int main(string[] args) {
// last
engine.add_suite(new Geary.RFC822.MessageTest().suite);
engine.add_suite(new Geary.String.Test().suite);
+ engine.add_suite(new Geary.EmailTest().suite);
engine.add_suite(new Geary.ComposedEmailTest().suite);
/*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]