[geary: 1/23] Change GMime dependency from 2.6.17 to 3.2.4
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary: 1/23] Change GMime dependency from 2.6.17 to 3.2.4
- Date: Sat, 21 Dec 2019 05:41:59 +0000 (UTC)
commit 1aac6f22847f2602b10b9f3da91d8d38a949ec0f
Author: Torben <torben letorbi gmail com>
Date: Sat Nov 30 20:09:28 2019 +0100
Change GMime dependency from 2.6.17 to 3.2.4
This commit squashes several non-compiling commits:
66dd6500 Change required GMime version to 3.2.4 or higher
4b9c8a38 Fix some compilations errors in test code
98aa5a2e Fix some (hopefully) last compilation errors
558360c6 Fix parser format when getting message headers
cc248ffc Fix name of stream-buffer mode
b293c66b Fix another iteration over a header-list
52fa183f Fix parsing of Gmime parameters
e078ee62 Use Unix2Dos-, Dos2Unix- and/or SmtpData-filters instead of 'FilterCRLF'
ff31b8e5 Fix setting of email headers
eb676482 Fix compilation errros due to string-uint8-char conversion problems
8558769f Fix datetime conversion
d44a28cd Remove some obsolete arguments
1ce81662 Pass charset where it's required
6013806f Pass GMime.ParserOptions to header-decode methods
986d05a0 Pass GMime.FormatOptions where it's required
e9b93187 Pass GMime.ParserOptions where it's required
640ce667 Fix compilation errors in GMime initialization
312f80bf Remove use of GMime.HeaderIter
acc73d14 Change GMime dependency from 2.6 to 3.0
54fc250a Adapt names to 'offical' gmime-2.6 bindings
The commits are part of the branch 'letorbi/gmime-3-spread', which can be
found at: https://gitlab.gnome.org/letorbi/geary/tree/letorbi/gmime-3-spread
meson.build | 2 +-
src/engine/imap-db/imap-db-attachment.vala | 2 +-
src/engine/mime/mime-content-disposition.vala | 2 +-
src/engine/mime/mime-content-parameters.vala | 10 +-
src/engine/mime/mime-content-type.vala | 7 +-
.../rfc822/rfc822-gmime-filter-blockquotes.vala | 8 +-
src/engine/rfc822/rfc822-gmime-filter-flowed.vala | 6 +-
src/engine/rfc822/rfc822-gmime-filter-plain.vala | 6 +-
src/engine/rfc822/rfc822-mailbox-address.vala | 32 ++-
src/engine/rfc822/rfc822-mailbox-addresses.vala | 17 +-
src/engine/rfc822/rfc822-message-data.vala | 50 ++---
src/engine/rfc822/rfc822-message.vala | 215 ++++++++++++---------
src/engine/rfc822/rfc822-part.vala | 4 +-
src/engine/rfc822/rfc822-utils.vala | 4 +-
src/engine/rfc822/rfc822.vala | 24 +--
test/engine/imap-db/imap-db-attachment-test.vala | 20 +-
test/engine/rfc822-part-test.vala | 12 +-
17 files changed, 227 insertions(+), 194 deletions(-)
---
diff --git a/meson.build b/meson.build
index 62f092a6..c8e0c277 100644
--- a/meson.build
+++ b/meson.build
@@ -57,7 +57,7 @@ target_webkit = '2.24'
# Primary deps
glib = dependency('glib-2.0', version: '>=' + target_glib)
-gmime = dependency('gmime-2.6', version: '>= 2.6.17')
+gmime = dependency('gmime-3.0', version: '>= 3.2.4')
gtk = dependency('gtk+-3.0', version: '>=' + target_gtk)
sqlite = dependency('sqlite3', version: '>= 3.24')
webkit2gtk = dependency('webkit2gtk-4.0', version: '>=' + target_webkit)
diff --git a/src/engine/imap-db/imap-db-attachment.vala b/src/engine/imap-db/imap-db-attachment.vala
index f2aacc25..4db81717 100644
--- a/src/engine/imap-db/imap-db-attachment.vala
+++ b/src/engine/imap-db/imap-db-attachment.vala
@@ -180,7 +180,7 @@ private class Geary.ImapDB.Attachment : Geary.Attachment {
target_stream
);
stream = new GMime.StreamBuffer(
- stream, GMime.StreamBufferMode.BLOCK_WRITE
+ stream, GMime.StreamBufferMode.WRITE
);
part.write_to_stream(stream, RFC822.Part.EncodingConversion.NONE);
diff --git a/src/engine/mime/mime-content-disposition.vala b/src/engine/mime/mime-content-disposition.vala
index 9b34849f..675aac75 100644
--- a/src/engine/mime/mime-content-disposition.vala
+++ b/src/engine/mime/mime-content-disposition.vala
@@ -102,7 +102,7 @@ public class Geary.Mime.ContentDisposition : Geary.BaseObject {
out is_unknown);
is_unknown_disposition_type = is_unknown;
original_disposition_type_string = content_disposition.get_disposition();
- params = new ContentParameters.from_gmime(content_disposition.get_params());
+ params = new ContentParameters.from_gmime(content_disposition.get_parameters());
}
}
diff --git a/src/engine/mime/mime-content-parameters.vala b/src/engine/mime/mime-content-parameters.vala
index 0267a9d5..cc201053 100644
--- a/src/engine/mime/mime-content-parameters.vala
+++ b/src/engine/mime/mime-content-parameters.vala
@@ -51,11 +51,13 @@ public class Geary.Mime.ContentParameters : BaseObject {
}
}
- internal ContentParameters.from_gmime(GMime.Param? gmime_param) {
+ internal ContentParameters.from_gmime(GMime.ParamList? gmime_params) {
Gee.Map<string,string> params = new Gee.HashMap<string,string>();
- while (gmime_param != null) {
- params.set(gmime_param.get_name(), gmime_param.get_value());
- gmime_param = gmime_param.get_next();
+ if (gmime_params != null) {
+ for (int i=0; i < gmime_params.length(); i++) {
+ GMime.Param gmime_param = gmime_params.get_parameter_at(i);
+ params.set(gmime_param.get_name(), gmime_param.get_value());
+ }
}
this(params);
}
diff --git a/src/engine/mime/mime-content-type.vala b/src/engine/mime/mime-content-type.vala
index ed59a491..9fe333d8 100644
--- a/src/engine/mime/mime-content-type.vala
+++ b/src/engine/mime/mime-content-type.vala
@@ -74,7 +74,10 @@ public class Geary.Mime.ContentType : Geary.BaseObject {
if (!str.contains("/"))
throw new MimeError.PARSE("Invalid MIME Content-Type: %s", str);
- return new ContentType.from_gmime(new GMime.ContentType.from_string(str));
+ return new ContentType.from_gmime(GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
+ str
+ ));
}
/**
@@ -158,7 +161,7 @@ public class Geary.Mime.ContentType : Geary.BaseObject {
internal ContentType.from_gmime(GMime.ContentType content_type) {
media_type = content_type.get_media_type().strip();
media_subtype = content_type.get_media_subtype().strip();
- params = new ContentParameters.from_gmime(content_type.get_params());
+ params = new ContentParameters.from_gmime(content_type.get_parameters());
}
/**
diff --git a/src/engine/rfc822/rfc822-gmime-filter-blockquotes.vala
b/src/engine/rfc822/rfc822-gmime-filter-blockquotes.vala
index 7d18342d..6f8c118f 100644
--- a/src/engine/rfc822/rfc822-gmime-filter-blockquotes.vala
+++ b/src/engine/rfc822/rfc822-gmime-filter-blockquotes.vala
@@ -49,7 +49,7 @@ private class Geary.RFC822.FilterBlockquotes : GMime.Filter {
return new_filter;
}
- private void do_filter(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ private void do_filter(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace, bool flush) {
// This may not be strictly necessary.
@@ -64,7 +64,7 @@ private class Geary.RFC822.FilterBlockquotes : GMime.Filter {
}
for (uint i = 0; i < inbuf.length; i++) {
- char c = inbuf[i];
+ uint8 c = inbuf[i];
if (in_prefix && !in_tag) {
if (c == Geary.RFC822.Utils.QUOTE_MARKER) {
@@ -122,12 +122,12 @@ private class Geary.RFC822.FilterBlockquotes : GMime.Filter {
outprespace = this.outpre;
}
- public override void filter(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void filter(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
do_filter(inbuf, prespace, out processed_buffer, out outprespace, false);
}
- public override void complete(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void complete(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
do_filter(inbuf, prespace, out processed_buffer, out outprespace, true);
}
diff --git a/src/engine/rfc822/rfc822-gmime-filter-flowed.vala
b/src/engine/rfc822/rfc822-gmime-filter-flowed.vala
index 3f5a28a9..d018c537 100644
--- a/src/engine/rfc822/rfc822-gmime-filter-flowed.vala
+++ b/src/engine/rfc822/rfc822-gmime-filter-flowed.vala
@@ -57,7 +57,7 @@ private class Geary.RFC822.FilterFlowed : GMime.Filter {
return new_filter;
}
- public override void filter(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void filter(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
// Worst-case scenario: We are about to leave the prefix,
@@ -67,7 +67,7 @@ private class Geary.RFC822.FilterFlowed : GMime.Filter {
uint out_index = 0;
for (uint i = 0; i < inbuf.length; i++) {
- char c = inbuf[i];
+ uint8 c = inbuf[i];
if (this.in_prefix) {
if (c == '>') {
@@ -147,7 +147,7 @@ private class Geary.RFC822.FilterFlowed : GMime.Filter {
outprespace = this.outpre;
}
- public override void complete(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void complete(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
filter(inbuf, prespace, out processed_buffer, out outprespace);
}
diff --git a/src/engine/rfc822/rfc822-gmime-filter-plain.vala
b/src/engine/rfc822/rfc822-gmime-filter-plain.vala
index d66e3284..b38baac0 100644
--- a/src/engine/rfc822/rfc822-gmime-filter-plain.vala
+++ b/src/engine/rfc822/rfc822-gmime-filter-plain.vala
@@ -26,7 +26,7 @@ private class Geary.RFC822.FilterPlain : GMime.Filter {
return new_filter;
}
- public override void filter(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void filter(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
// This may not be strictly necessary.
@@ -34,7 +34,7 @@ private class Geary.RFC822.FilterPlain : GMime.Filter {
uint out_index = 0;
for (uint i = 0; i < inbuf.length; i++) {
- char c = inbuf[i];
+ uint8 c = inbuf[i];
if (in_prefix) {
if (c == '>') {
@@ -56,7 +56,7 @@ private class Geary.RFC822.FilterPlain : GMime.Filter {
outprespace = this.outpre;
}
- public override void complete(char[] inbuf, size_t prespace, out unowned char[] processed_buffer,
+ public override void complete(uint8[] inbuf, size_t prespace, out unowned uint8[] processed_buffer,
out size_t outprespace) {
filter(inbuf, prespace, out processed_buffer, out outprespace);
}
diff --git a/src/engine/rfc822/rfc822-mailbox-address.vala b/src/engine/rfc822/rfc822-mailbox-address.vala
index 73803f19..1153cdd1 100644
--- a/src/engine/rfc822/rfc822-mailbox-address.vala
+++ b/src/engine/rfc822/rfc822-mailbox-address.vala
@@ -42,11 +42,17 @@ public class Geary.RFC822.MailboxAddress :
}
private static string decode_name(string name) {
- return GMime.utils_header_decode_phrase(prepare_header_text_part(name));
+ return GMime.utils_header_decode_phrase(
+ Geary.RFC822.get_parser_options(),
+ prepare_header_text_part(name)
+ );
}
private static string decode_address_part(string mailbox) {
- return GMime.utils_header_decode_text(prepare_header_text_part(mailbox));
+ return GMime.utils_header_decode_text(
+ Geary.RFC822.get_parser_options(),
+ prepare_header_text_part(mailbox)
+ );
}
private static bool display_name_needs_quoting(string name) {
@@ -118,8 +124,9 @@ public class Geary.RFC822.MailboxAddress :
// _internet_address_decode_name() function.
// see if a broken mailer has sent raw 8-bit information
- string text = GMime.utils_text_is_8bit(part, part.length)
- ? part : GMime.utils_decode_8bit(part, part.length);
+ string text = GMime.utils_text_is_8bit(part.data)
+ ? part : GMime.utils_decode_8bit(Geary.RFC822.get_parser_options(),
+ part.data);
// unquote the string then decode the text
GMime.utils_unquote_string(text);
@@ -222,16 +229,19 @@ public class Geary.RFC822.MailboxAddress :
}
public MailboxAddress.from_rfc822_string(string rfc822) throws RFC822Error {
- InternetAddressList addrlist = InternetAddressList.parse_string(rfc822);
+ GMime.InternetAddressList addrlist = GMime.InternetAddressList.parse(
+ Geary.RFC822.get_parser_options(),
+ rfc822
+ );
if (addrlist == null)
return;
int length = addrlist.length();
for (int ctr = 0; ctr < length; ctr++) {
- InternetAddress? addr = addrlist.get_address(ctr);
+ GMime.InternetAddress? addr = addrlist.get_address(ctr);
// TODO: Handle group lists
- InternetAddressMailbox? mbox_addr = addr as InternetAddressMailbox;
+ GMime.InternetAddressMailbox? mbox_addr = addr as GMime.InternetAddressMailbox;
if (mbox_addr != null) {
this.gmime(mbox_addr);
return;
@@ -240,7 +250,7 @@ public class Geary.RFC822.MailboxAddress :
throw new RFC822Error.INVALID("Could not parse RFC822 address: %s", rfc822);
}
- public MailboxAddress.gmime(InternetAddressMailbox mailbox) {
+ public MailboxAddress.gmime(GMime.InternetAddressMailbox mailbox) {
// GMime strips source route for us, so the address part
// should only ever contain a single '@'
string? name = mailbox.get_name();
@@ -456,7 +466,11 @@ public class Geary.RFC822.MailboxAddress :
public string to_rfc822_string() {
return has_distinct_name()
? "%s <%s>".printf(
- GMime.utils_header_encode_phrase(this.name),
+ GMime.utils_header_encode_phrase(
+ Geary.RFC822.get_format_options(),
+ this.name,
+ Geary.RFC822.get_charset()
+ ),
to_rfc822_address()
)
: to_rfc822_address();
diff --git a/src/engine/rfc822/rfc822-mailbox-addresses.vala b/src/engine/rfc822/rfc822-mailbox-addresses.vala
index 8ebf79de..5d647fa7 100644
--- a/src/engine/rfc822/rfc822-mailbox-addresses.vala
+++ b/src/engine/rfc822/rfc822-mailbox-addresses.vala
@@ -74,27 +74,30 @@ public class Geary.RFC822.MailboxAddresses :
}
public MailboxAddresses.from_rfc822_string(string rfc822) {
- InternetAddressList addrlist = InternetAddressList.parse_string(rfc822);
+ GMime.InternetAddressList addrlist = GMime.InternetAddressList.parse(
+ Geary.RFC822.get_parser_options(),
+ rfc822
+ );
if (addrlist == null)
return;
int length = addrlist.length();
for (int ctr = 0; ctr < length; ctr++) {
- InternetAddress? addr = addrlist.get_address(ctr);
+ GMime.InternetAddress? addr = addrlist.get_address(ctr);
- InternetAddressMailbox? mbox_addr = addr as InternetAddressMailbox;
+ GMime.InternetAddressMailbox? mbox_addr = addr as GMime.InternetAddressMailbox;
if (mbox_addr != null) {
this.addrs.add(new MailboxAddress.gmime(mbox_addr));
} else {
// XXX this is pretty bad - we just flatten the
// group's addresses into this list, merging lists and
// losing the group names.
- InternetAddressGroup? mbox_group = addr as InternetAddressGroup;
+ GMime.InternetAddressGroup? mbox_group = addr as GMime.InternetAddressGroup;
if (mbox_group != null) {
- InternetAddressList group_list = mbox_group.get_members();
+ GMime.InternetAddressList group_list = mbox_group.get_members();
for (int i = 0; i < group_list.length(); i++) {
- InternetAddressMailbox? group_addr =
- addrlist.get_address(i) as InternetAddressMailbox;
+ GMime.InternetAddressMailbox? group_addr =
+ addrlist.get_address(i) as GMime.InternetAddressMailbox;
if (group_addr != null) {
this.addrs.add(new MailboxAddress.gmime(group_addr));
}
diff --git a/src/engine/rfc822/rfc822-message-data.vala b/src/engine/rfc822/rfc822-message-data.vala
index 2d399986..b5d62ad5 100644
--- a/src/engine/rfc822/rfc822-message-data.vala
+++ b/src/engine/rfc822/rfc822-message-data.vala
@@ -173,27 +173,13 @@ public class Geary.RFC822.Date : Geary.RFC822.MessageData, Geary.MessageData.Abs
public DateTime value { get; private set; }
public Date(string rfc822) throws ImapError {
- int offset = 0;
- int64 time_t_utc = GMime.utils_header_decode_date(rfc822, out offset);
- if (time_t_utc == 0)
- throw new ImapError.PARSE_ERROR(
- "Unable to parse \"%s\": Not ISO-8601 date", rfc822
- );
-
- DateTime? value = new DateTime.from_unix_utc(time_t_utc);
+ DateTime? value = GMime.utils_header_decode_date(rfc822);
if (value == null) {
throw new ImapError.PARSE_ERROR(
"Unable to parse \"%s\": Outside supported range", rfc822
);
}
this.value = value;
-
- if (offset != 0) {
- this.value = value.to_timezone(
- new GLib.TimeZone("%+05d".printf(offset))
- );
- }
-
this.original = rfc822;
}
@@ -206,18 +192,7 @@ public class Geary.RFC822.Date : Geary.RFC822.MessageData, Geary.MessageData.Abs
* Returns the {@link Date} in RFC 822 format.
*/
public string to_rfc822_string() {
- // Although GMime documents its conversion methods as
- // requiring the tz offset in hours, it appears the number is
- // handed directly to the string (i.e. an offset of -7:30 becomes
- // "-0007", whereas we want "-0730").
- int hours = (int) GLib.Math.floor(value.get_utc_offset() / TimeSpan.HOUR);
- int minutes = (int) (
- (value.get_utc_offset() % TimeSpan.HOUR) / (double) TimeSpan.HOUR * 60
- );
- return GMime.utils_header_format_date(
- (time_t) this.value.to_utc().to_unix(),
- (hours * 100) + minutes
- );
+ return GMime.utils_header_format_date(this.value);
}
/**
@@ -261,7 +236,7 @@ public class Geary.RFC822.Subject : Geary.MessageData.StringMessageData,
}
public Subject.decode(string value) {
- base (GMime.utils_header_decode_text(value));
+ base (GMime.utils_header_decode_text(Geary.RFC822.get_parser_options(), value));
original = value;
}
@@ -337,9 +312,10 @@ public class Geary.RFC822.Header : Geary.MessageData.BlockMessageData, Geary.RFC
GMime.Parser parser = new GMime.Parser.with_stream(Utils.create_stream_mem(buffer));
parser.set_respect_content_length(false);
- parser.set_scan_from(false);
+ // TODO Could this be omitted?
+ parser.set_format(GMime.Format.MESSAGE);
- message = parser.construct_message();
+ message = parser.construct_message(Geary.RFC822.get_parser_options());
if (message == null)
throw new RFC822Error.INVALID("Unable to parse RFC 822 headers");
@@ -347,17 +323,15 @@ public class Geary.RFC822.Header : Geary.MessageData.BlockMessageData, Geary.RFC
}
public string? get_header(string name) throws RFC822Error {
- return get_headers().get(name);
+ return get_headers().get_header(name).get_value();
}
public string[] get_header_names() throws RFC822Error {
if (this.names == null) {
this.names = new string[0];
- GMime.HeaderIter iter = new GMime.HeaderIter();
- if (get_headers().get_iter(iter) && iter.first()) {
- do {
- names += iter.get_name();
- } while (iter.next());
+ GMime.HeaderList headers = get_headers();
+ for (int i = 0; i < headers.get_count(); i++) {
+ names += headers.get_header_at(i).get_name();
}
}
return this.names;
@@ -388,7 +362,7 @@ public class Geary.RFC822.PreviewText : Geary.RFC822.Text {
// Parse the header.
GMime.Stream header_stream = Utils.create_stream_mem(preview_header);
GMime.Parser parser = new GMime.Parser.with_stream(header_stream);
- GMime.Part? gpart = parser.construct_part() as GMime.Part;
+ GMime.Part? gpart = parser.construct_part(Geary.RFC822.get_parser_options()) as GMime.Part;
if (gpart != null) {
Part part = new Part(gpart);
@@ -402,7 +376,7 @@ public class Geary.RFC822.PreviewText : Geary.RFC822.Text {
new GMime.StreamMem.with_buffer(preview.get_uint8_array()),
gpart.get_content_encoding()
);
- gpart.set_content_object(body);
+ gpart.set_content(body);
try {
Memory.Buffer preview_buffer = part.write_to_buffer(
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index 02d4b397..8a94cf2c 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -29,6 +29,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
*/
public delegate string? InlinePartReplacer(Part part);
+ private const string HEADER_DATE = "Date";
private const string HEADER_SENDER = "Sender";
private const string HEADER_IN_REPLY_TO = "In-Reply-To";
private const string HEADER_REFERENCES = "References";
@@ -89,7 +90,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
public Message(Full full) throws RFC822Error {
GMime.Parser parser = new GMime.Parser.with_stream(Utils.create_stream_mem(full.buffer));
- message = parser.construct_message();
+ message = parser.construct_message(Geary.RFC822.get_parser_options());
if (message == null)
throw new RFC822Error.INVALID("Unable to parse RFC 822 message");
@@ -115,7 +116,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
stream_cat.add_source(new GMime.StreamMem.with_buffer(body.buffer.get_bytes().get_data()));
GMime.Parser parser = new GMime.Parser.with_stream(stream_cat);
- message = parser.construct_message();
+ message = parser.construct_message(Geary.RFC822.get_parser_options());
if (message == null)
throw new RFC822Error.INVALID("Unable to parse RFC 822 message");
@@ -136,67 +137,71 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
this.from = email.from;
this.date = email.date;
- // GMimeMessage.set_sender actually sets the From header - and
- // although the API docs make it sound otherwise, it also
- // supports a list of addresses
- message.set_sender(this.from.to_rfc822_string());
- message.set_date_as_string(this.date.serialize());
- if (message_id != null) {
- this.message_id = new MessageID(message_id);
- message.set_message_id(message_id);
+ //message.set_date_as_string(this.date.serialize());
+ this.message.set_header(HEADER_DATE,
+ this.date.serialize(),
+ Geary.RFC822.get_charset());
+
+ if (email.from != null) {
+ foreach (RFC822.MailboxAddress mailbox in email.from)
+ this.message.add_mailbox(GMime.AddressType.FROM, mailbox.name, mailbox.address);
+ }
+
+ if (email.sender != null) {
+ this.message.add_mailbox(GMime.AddressType.SENDER, this.sender.name, this.sender.address);
+ // TODO Is setting the header still required?
+ this.message.set_header(HEADER_SENDER,
+ this.sender.to_rfc822_string(),
+ Geary.RFC822.get_charset());
}
// Optional headers
if (email.to != null) {
this.to = email.to;
foreach (RFC822.MailboxAddress mailbox in email.to)
- this.message.add_recipient(GMime.RecipientType.TO, mailbox.name, mailbox.address);
+ this.message.add_mailbox(GMime.AddressType.TO, mailbox.name, mailbox.address);
}
if (email.cc != null) {
this.cc = email.cc;
foreach (RFC822.MailboxAddress mailbox in email.cc)
- this.message.add_recipient(GMime.RecipientType.CC, mailbox.name, mailbox.address);
+ this.message.add_mailbox(GMime.AddressType.CC, mailbox.name, mailbox.address);
}
if (email.bcc != null) {
this.bcc = email.bcc;
foreach (RFC822.MailboxAddress mailbox in email.bcc)
- this.message.add_recipient(GMime.RecipientType.BCC, mailbox.name, mailbox.address);
- }
-
- if (email.sender != null) {
- this.sender = email.sender;
- this.message.set_header(HEADER_SENDER,
- email.sender.to_rfc822_string());
- }
-
- if (email.reply_to != null) {
- this.reply_to = email.reply_to;
- this.message.set_reply_to(email.reply_to.to_rfc822_string());
+ this.message.add_mailbox(GMime.AddressType.BCC, mailbox.name, mailbox.address);
}
if (email.in_reply_to != null) {
this.in_reply_to = email.in_reply_to;
+ foreach (RFC822.MailboxAddress mailbox in email.reply_to)
+ this.message.add_mailbox(GMime.AddressType.BCC, mailbox.name, mailbox.address);
+ // TODO Is setting the header still required?
this.message.set_header(HEADER_IN_REPLY_TO,
- email.in_reply_to.to_rfc822_string());
+ email.in_reply_to.to_rfc822_string(),
+ Geary.RFC822.get_charset());
}
if (email.references != null) {
this.references = email.references;
this.message.set_header(HEADER_REFERENCES,
- email.references.to_rfc822_string());
+ email.references.to_rfc822_string(),
+ Geary.RFC822.get_charset());
}
if (email.subject != null) {
this.subject = email.subject;
- this.message.set_subject(email.subject.value);
+ this.message.set_subject(email.subject.value,
+ Geary.RFC822.get_charset());
}
// User-Agent
if (!Geary.String.is_empty(email.mailer)) {
this.mailer = email.mailer;
- this.message.set_header(HEADER_MAILER, email.mailer);
+ this.message.set_header(HEADER_MAILER, email.mailer,
+ Geary.RFC822.get_charset());
}
// Build the message's body mime parts
@@ -406,7 +411,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
string type) {
GMime.Object? part = coalesce_parts(parts, "related");
if (parts.size > 1) {
- part.set_header("Type", type);
+ part.set_header("Type", type, Geary.RFC822.get_charset());
}
return part;
}
@@ -437,7 +442,8 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
part.set_disposition(disposition.serialize());
part.set_filename(file.get_basename());
- GMime.ContentType content_type = new GMime.ContentType.from_string(
+ GMime.ContentType content_type = GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
file_info.get_content_type()
);
part.set_content_type(content_type);
@@ -468,7 +474,10 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
);
}
- GMime.ContentType? content_type = new GMime.ContentType.from_string(mime_type.get_mime_type());
+ GMime.ContentType? content_type = GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
+ mime_type.get_mime_type()
+ );
if (content_type == null) {
throw new RFC822Error.INVALID(
@@ -515,7 +524,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
}
part.set_content_encoding(encoding);
- part.set_content_object(
+ part.set_content(
new GMime.DataWrapper.with_stream(
stream, GMime.ContentEncoding.BINARY
)
@@ -536,7 +545,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
Geary.Email email = new Geary.Email(id);
email.set_message_header(new Geary.RFC822.Header(new Geary.Memory.StringBuffer(
- message.get_headers())));
+ message.get_headers(Geary.RFC822.get_format_options()))));
email.set_send_date(date);
email.set_originators(from, sender, reply_to);
email.set_receivers(to, cc, bcc);
@@ -884,68 +893,72 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
}
private void stock_from_gmime() {
- this.message.get_header_list().foreach((name, value) => {
- switch (name.down()) {
- case "from":
- this.from = append_address(this.from, value);
- break;
-
- case "sender":
- try {
- this.sender = new RFC822.MailboxAddress.from_rfc822_string(value);
- } catch (Error err) {
- debug("Could parse subject: %s", err.message);
- }
- break;
+ GMime.HeaderList headers = this.message.get_header_list();
+ for (int i=0; i < headers.get_count(); i++) {
+ GMime.Header header = headers.get_header_at(i);
+ string name = header.get_name();
+ string value = header.get_value();
+ switch (name.down()) {
+ case "from":
+ this.from = append_address(this.from, value);
+ break;
+
+ case "sender":
+ try {
+ this.sender = new RFC822.MailboxAddress.from_rfc822_string(value);
+ } catch (Error err) {
+ debug("Could parse subject: %s", err.message);
+ }
+ break;
- case "reply-to":
- this.reply_to = append_address(this.reply_to, value);
- break;
+ case "reply-to":
+ this.reply_to = append_address(this.reply_to, value);
+ break;
- case "to":
- this.to = append_address(this.to, value);
- break;
+ case "to":
+ this.to = append_address(this.to, value);
+ break;
- case "cc":
- this.cc = append_address(this.cc, value);
- break;
+ case "cc":
+ this.cc = append_address(this.cc, value);
+ break;
- case "bcc":
- this.bcc = append_address(this.bcc, value);
- break;
+ case "bcc":
+ this.bcc = append_address(this.bcc, value);
+ break;
- case "subject":
- this.subject = new RFC822.Subject.decode(value);
- break;
+ case "subject":
+ this.subject = new RFC822.Subject.decode(value);
+ break;
- case "date":
- try {
- this.date = new Geary.RFC822.Date(value);
- } catch (Error err) {
- debug("Could not parse date: %s", err.message);
- }
- break;
+ case "date":
+ try {
+ this.date = new Geary.RFC822.Date(value);
+ } catch (Error err) {
+ debug("Could not parse date: %s", err.message);
+ }
+ break;
- case "message-id":
- this.message_id = new MessageID(value);
- break;
+ case "message-id":
+ this.message_id = new MessageID(value);
+ break;
- case "in-reply-to":
- this.in_reply_to = append_message_id(this.in_reply_to, value);
- break;
+ case "in-reply-to":
+ this.in_reply_to = append_message_id(this.in_reply_to, value);
+ break;
- case "references":
- this.references = append_message_id(this.references, value);
- break;
+ case "references":
+ this.references = append_message_id(this.references, value);
+ break;
- case "x-mailer":
- this.mailer = GMime.utils_header_decode_text(value);
- break;
+ case "x-mailer":
+ this.mailer = GMime.utils_header_decode_text(Geary.RFC822.get_parser_options(), value);
+ break;
- default:
- break;
- }
- });
+ default:
+ break;
+ }
+ };
}
private MailboxAddresses append_address(MailboxAddresses? existing,
@@ -990,11 +1003,11 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
if (requested_disposition == Mime.DispositionType.UNSPECIFIED || disposition ==
requested_disposition) {
GMime.Stream stream = new GMime.StreamMem();
- message.write_to_stream(stream);
+ message.write_to_stream(Geary.RFC822.get_format_options(), stream);
GMime.DataWrapper data = new GMime.DataWrapper.with_stream(stream,
GMime.ContentEncoding.BINARY); // Equivalent to no encoding
GMime.Part part = new GMime.Part.with_type("message", "rfc822");
- part.set_content_object(data);
+ part.set_content(data);
part.set_filename((message.get_subject() ?? _("(no subject)")) + ".eml");
attachments.add(new Part(part));
}
@@ -1017,7 +1030,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
#if WITH_TNEF_SUPPORT
if (content_type.is_type("application", "vnd.ms-tnef")) {
GMime.StreamMem stream = new GMime.StreamMem();
- ((GMime.Part) root).get_content_object().write_to_stream(stream);
+ ((GMime.Part) root).get_content().write_to_stream(stream);
ByteArray tnef_data = stream.get_byte_array();
Ytnef.TNEFStruct tn;
if (Ytnef.ParseMemory(tnef_data.data, out tn) == 0) {
@@ -1052,8 +1065,8 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
GMime.Part part = new GMime.Part();
part.set_filename(filename);
- part.set_content_type(new GMime.ContentType.from_string(GLib.ContentType.guess(filename, data,
null)));
- part.set_content_object(new GMime.DataWrapper.with_stream(new GMime.StreamMem.with_buffer(data),
GMime.ContentEncoding.BINARY));
+ part.set_content_type(GMime.ContentType.parse(Geary.RFC822.get_parser_options(),
GLib.ContentType.guess(filename, data, null)));
+ part.set_content(new GMime.DataWrapper.with_stream(new GMime.StreamMem.with_buffer(data),
GMime.ContentEncoding.BINARY));
return part;
}
#endif
@@ -1092,9 +1105,17 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
stream.set_owner(false);
GMime.StreamFilter stream_filter = new GMime.StreamFilter(stream);
- stream_filter.add(new GMime.FilterCRLF(encoded, dotstuffed));
+ if (encoded) {
+ stream_filter.add(new GMime.FilterUnix2Dos(false));
+ }
+ else {
+ stream_filter.add(new GMime.FilterDos2Unix(false));
+ }
+ if (dotstuffed) {
+ stream_filter.add(new GMime.FilterSmtpData());
+ }
- if (message.write_to_stream(stream_filter) < 0)
+ if (message.write_to_stream(Geary.RFC822.get_format_options(), stream_filter) < 0)
throw new RFC822Error.FAILED("Unable to write RFC822 message to memory buffer");
if (stream_filter.flush() != 0)
@@ -1104,7 +1125,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
}
public string to_string() {
- return message.to_string();
+ return message.to_string(Geary.RFC822.get_format_options());
}
/**
@@ -1152,11 +1173,13 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
// Base64-encoded text needs to have CR's added after LF's
// before encoding, otherwise it breaks format=flowed. See
// Bug 753528.
- filter_stream.add(new GMime.FilterCRLF(true, false));
+ filter_stream.add(new GMime.FilterUnix2Dos(false));
}
- GMime.ContentType complete_type =
- new GMime.ContentType.from_string(content_type);
+ GMime.ContentType complete_type = GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
+ content_type
+ );
complete_type.set_parameter("charset", charset);
if (is_flowed) {
complete_type.set_parameter("format", "flowed");
@@ -1168,7 +1191,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
GMime.Part body_part = new GMime.Part();
body_part.set_content_type(complete_type);
- body_part.set_content_object(body);
+ body_part.set_content(body);
body_part.set_content_encoding(encoding);
return body_part;
}
diff --git a/src/engine/rfc822/rfc822-part.vala b/src/engine/rfc822/rfc822-part.vala
index b8a3b2a8..6d0521d1 100644
--- a/src/engine/rfc822/rfc822-part.vala
+++ b/src/engine/rfc822/rfc822-part.vala
@@ -160,7 +160,7 @@ public class Geary.RFC822.Part : Object {
BodyFormatting format = BodyFormatting.NONE)
throws RFC822Error {
GMime.DataWrapper? wrapper = (this.source_part != null)
- ? this.source_part.get_content_object() : null;
+ ? this.source_part.get_content() : null;
if (wrapper == null) {
throw new RFC822Error.INVALID(
"Could not get the content wrapper for content-type %s",
@@ -201,7 +201,7 @@ public class Geary.RFC822.Part : Object {
if ((this.source_part == null ||
this.source_part.encoding != BASE64) &&
!(content_type.media_subtype in CR_PRESERVING_TEXT_TYPES)) {
- filter.add(new GMime.FilterCRLF(false, false));
+ filter.add(new GMime.FilterDos2Unix(false));
}
if (flowed) {
diff --git a/src/engine/rfc822/rfc822-utils.vala b/src/engine/rfc822/rfc822-utils.vala
index 37a967fb..d9278f64 100644
--- a/src/engine/rfc822/rfc822-utils.vala
+++ b/src/engine/rfc822/rfc822-utils.vala
@@ -186,7 +186,7 @@ public string email_addresses_for_reply(Geary.RFC822.MailboxAddresses? addresses
}
-public bool comp_char_arr_slice(char[] array, uint start, string comp) {
+public bool comp_char_arr_slice(uint8[] array, uint start, string comp) {
for (int i = 0; i < comp.length; i++) {
if (array[start + i] != comp[i])
return false;
@@ -277,7 +277,7 @@ public async string get_best_charset(GMime.Stream in_stream,
},
cancellable
);
- return filter.charset();
+ return filter.get_charset();
}
/**
diff --git a/src/engine/rfc822/rfc822.vala b/src/engine/rfc822/rfc822.vala
index 9195eac1..39a400e5 100644
--- a/src/engine/rfc822/rfc822.vala
+++ b/src/engine/rfc822/rfc822.vala
@@ -32,18 +32,7 @@ public void init() {
if (init_count++ != 0)
return;
- GMime.init(GMime.ENABLE_RFC2047_WORKAROUNDS);
-
- // This has the effect of ensuring all non US-ASCII and non-ISO-8859-1
- // headers are always encoded as UTF-8. This should be fine because
- // message bodies are also always sent as UTF-8.
- const string?[] USER_CHARSETS = {
- UTF8_CHARSET,
- // GMime.set_user_charsets calls g_strdupv under the hood, so
- // the array needs to be null-terminated
- null
- };
- GMime.set_user_charsets(USER_CHARSETS);
+ GMime.init();
try {
invalid_filename_character_re = new Regex("[/\\0]");
@@ -52,6 +41,17 @@ public void init() {
}
}
+public GMime.FormatOptions get_format_options() {
+ return new GMime.FormatOptions();
+}
+
+public GMime.ParserOptions get_parser_options() {
+ return new GMime.ParserOptions();
+}
+
+public string? get_charset() {
+ return null;
+}
internal bool is_utf_8(string charset) {
string up = charset.up();
diff --git a/test/engine/imap-db/imap-db-attachment-test.vala
b/test/engine/imap-db/imap-db-attachment-test.vala
index d24f2b8d..9366802e 100644
--- a/test/engine/imap-db/imap-db-attachment-test.vala
+++ b/test/engine/imap-db/imap-db-attachment-test.vala
@@ -21,7 +21,7 @@ class Geary.ImapDB.AttachmentTest : TestCase {
public void new_from_minimal_mime_part() throws Error {
GMime.Part part = new_part(null, ATTACHMENT_BODY.data);
- part.set_header("Content-Type", "");
+ part.set_header("Content-Type", "", Geary.RFC822.get_charset());
Attachment test = new Attachment.from_part(
1, new Geary.RFC822.Part(part)
@@ -51,7 +51,8 @@ class Geary.ImapDB.AttachmentTest : TestCase {
part.set_content_id(ID);
part.set_content_description(DESC);
part.set_content_disposition(
- new GMime.ContentDisposition.from_string(
+ GMime.ContentDisposition.parse(
+ Geary.RFC822.get_parser_options(),
"attachment; filename=%s".printf(NAME)
)
);
@@ -74,7 +75,10 @@ class Geary.ImapDB.AttachmentTest : TestCase {
public void new_from_inline_mime_part() throws Error {
GMime.Part part = new_part(null, ATTACHMENT_BODY.data);
part.set_content_disposition(
- new GMime.ContentDisposition.from_string("inline")
+ GMime.ContentDisposition.parse(
+ Geary.RFC822.get_parser_options(),
+ "inline"
+ )
);
Attachment test = new Attachment.from_part(
@@ -205,7 +209,8 @@ CREATE TABLE MessageAttachmentTable (
part.set_content_id(ID);
part.set_content_description(DESCRIPTION);
part.set_content_disposition(
- new GMime.ContentDisposition.from_string(
+ GMime.ContentDisposition.parse(
+ Geary.RFC822.get_parser_options(),
"inline; filename=%s;".printf(FILENAME)
));
@@ -352,12 +357,15 @@ private GMime.Part new_part(string? mime_type,
GMime.ContentEncoding encoding = GMime.ContentEncoding.DEFAULT) {
GMime.Part part = new GMime.Part();
if (mime_type != null) {
- part.set_content_type(new GMime.ContentType.from_string(mime_type));
+ part.set_content_type(GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
+ mime_type
+ ));
}
GMime.DataWrapper body_wrapper = new GMime.DataWrapper.with_stream(
new GMime.StreamMem.with_buffer(body),
encoding
);
- part.set_content_object(body_wrapper);
+ part.set_content(body_wrapper);
return part;
}
diff --git a/test/engine/rfc822-part-test.vala b/test/engine/rfc822-part-test.vala
index b6e82e60..4fbe5d87 100644
--- a/test/engine/rfc822-part-test.vala
+++ b/test/engine/rfc822-part-test.vala
@@ -40,7 +40,10 @@ class Geary.RFC822.PartTest : TestCase {
part.set_content_id(ID);
part.set_content_description(DESC);
part.set_content_disposition(
- new GMime.ContentDisposition.from_string("inline")
+ GMime.ContentDisposition.parse(
+ Geary.RFC822.get_parser_options(),
+ "inline"
+ )
);
Part test = new Part(part);
@@ -93,13 +96,16 @@ class Geary.RFC822.PartTest : TestCase {
uint8[] body) {
GMime.Part part = new GMime.Part();
if (mime_type != null) {
- part.set_content_type(new GMime.ContentType.from_string(mime_type));
+ part.set_content_type(GMime.ContentType.parse(
+ Geary.RFC822.get_parser_options(),
+ mime_type
+ ));
}
GMime.DataWrapper body_wrapper = new GMime.DataWrapper.with_stream(
new GMime.StreamMem.with_buffer(body),
GMime.ContentEncoding.BINARY
);
- part.set_content_object(body_wrapper);
+ part.set_content(body_wrapper);
part.encode(GMime.EncodingConstraint.7BIT);
return part;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]