Geary.RFC822: Ensure various data constructors throw errors
Rather than just silently ignoring error conditions, throw RFC822 errors instead.
This commit is contained in:
parent
97e0093e29
commit
e0c1fb8a80
10 changed files with 160 additions and 144 deletions
|
|
@ -1274,10 +1274,15 @@ public class Accounts.AccountConfigLegacy : AccountConfig, GLib.Object {
|
|||
ALTERNATE_EMAILS_KEY
|
||||
);
|
||||
foreach (string alt_email in alt_email_list) {
|
||||
Geary.RFC822.MailboxAddresses mailboxes =
|
||||
new Geary.RFC822.MailboxAddresses.from_rfc822_string(alt_email);
|
||||
foreach (Geary.RFC822.MailboxAddress mailbox in mailboxes.get_all()) {
|
||||
info.append_sender(mailbox);
|
||||
try {
|
||||
var mailboxes = new Geary.RFC822.MailboxAddresses.from_rfc822_string(alt_email);
|
||||
foreach (Geary.RFC822.MailboxAddress mailbox in mailboxes.get_all()) {
|
||||
info.append_sender(mailbox);
|
||||
}
|
||||
} catch (Geary.RFC822Error error) {
|
||||
throw new ConfigError.SYNTAX(
|
||||
"Invalid alternate email: %s", error.message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,9 +81,14 @@ public class Composer.EmailEntry : Gtk.Entry {
|
|||
this._addresses = new Geary.RFC822.MailboxAddresses();
|
||||
this.is_valid = false;
|
||||
} else {
|
||||
this._addresses =
|
||||
new Geary.RFC822.MailboxAddresses.from_rfc822_string(text);
|
||||
this.is_valid = true;
|
||||
try {
|
||||
this._addresses =
|
||||
new Geary.RFC822.MailboxAddresses.from_rfc822_string(text);
|
||||
this.is_valid = true;
|
||||
} catch (Geary.RFC822Error err) {
|
||||
this._addresses = new Geary.RFC822.MailboxAddresses();
|
||||
this.is_valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,20 +272,22 @@ private class Geary.ImapDB.MessageRow {
|
|||
return (addrs == null || addrs.size == 0) ? null : addrs.to_rfc822_string();
|
||||
}
|
||||
|
||||
private RFC822.MailboxAddress? unflatten_address(string? str) {
|
||||
RFC822.MailboxAddress? addr = null;
|
||||
if (str != null) {
|
||||
try {
|
||||
addr = new RFC822.MailboxAddress.from_rfc822_string(str);
|
||||
} catch (RFC822Error e) {
|
||||
// oh well
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
private RFC822.MailboxAddress? unflatten_address(string? str)
|
||||
throws RFC822Error {
|
||||
return (
|
||||
String.is_empty_or_whitespace(str)
|
||||
? null
|
||||
: new RFC822.MailboxAddress.from_rfc822_string(str)
|
||||
);
|
||||
}
|
||||
|
||||
private RFC822.MailboxAddresses? unflatten_addresses(string? str) {
|
||||
return String.is_empty(str) ? null : new RFC822.MailboxAddresses.from_rfc822_string(str);
|
||||
private RFC822.MailboxAddresses? unflatten_addresses(string? str)
|
||||
throws RFC822Error {
|
||||
return (
|
||||
String.is_empty_or_whitespace(str)
|
||||
? null
|
||||
: new RFC822.MailboxAddresses.from_rfc822_string(str)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,13 @@ public class Geary.Imap.RFC822Size : Geary.RFC822.Size, Geary.Imap.MessageData {
|
|||
}
|
||||
|
||||
public class Geary.Imap.RFC822Header : Geary.RFC822.Header, Geary.Imap.MessageData {
|
||||
public RFC822Header(Memory.Buffer buffer) {
|
||||
base (buffer);
|
||||
public RFC822Header(Memory.Buffer buffer)
|
||||
throws ImapError {
|
||||
try {
|
||||
base(buffer);
|
||||
} catch (RFC822Error error) {
|
||||
throw new ImapError.INVALID(error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,4 +47,3 @@ public class Geary.Imap.RFC822Full : Geary.RFC822.Full, Geary.Imap.MessageData {
|
|||
base (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -233,21 +233,27 @@ public class Geary.RFC822.MailboxAddress :
|
|||
Geary.RFC822.get_parser_options(),
|
||||
rfc822
|
||||
);
|
||||
if (addrlist == null)
|
||||
return;
|
||||
|
||||
int length = addrlist.length();
|
||||
for (int ctr = 0; ctr < length; ctr++) {
|
||||
GMime.InternetAddress? addr = addrlist.get_address(ctr);
|
||||
|
||||
// TODO: Handle group lists
|
||||
GMime.InternetAddressMailbox? mbox_addr = addr as GMime.InternetAddressMailbox;
|
||||
if (mbox_addr != null) {
|
||||
this.gmime(mbox_addr);
|
||||
return;
|
||||
}
|
||||
if (addrlist == null) {
|
||||
throw new RFC822Error.INVALID(
|
||||
"Not a RFC822 mailbox address: %s", rfc822
|
||||
);
|
||||
}
|
||||
throw new RFC822Error.INVALID("Could not parse RFC822 address: %s", rfc822);
|
||||
if (addrlist.length() != 1) {
|
||||
throw new RFC822Error.INVALID(
|
||||
"Not a single RFC822 mailbox address: %s", rfc822
|
||||
);
|
||||
}
|
||||
|
||||
GMime.InternetAddress? addr = addrlist.get_address(0);
|
||||
// TODO: Handle group lists
|
||||
var mbox_addr = addr as GMime.InternetAddressMailbox;
|
||||
if (mbox_addr == null) {
|
||||
throw new RFC822Error.INVALID(
|
||||
"Group lists not currently supported: %s", rfc822
|
||||
);
|
||||
}
|
||||
|
||||
this.gmime(mbox_addr);
|
||||
}
|
||||
|
||||
public MailboxAddress.gmime(GMime.InternetAddressMailbox mailbox) {
|
||||
|
|
|
|||
|
|
@ -78,13 +78,12 @@ public class Geary.RFC822.MailboxAddresses :
|
|||
this.addrs.add(addr);
|
||||
}
|
||||
|
||||
public MailboxAddresses.from_rfc822_string(string rfc822) {
|
||||
GMime.InternetAddressList addrlist = GMime.InternetAddressList.parse(
|
||||
Geary.RFC822.get_parser_options(),
|
||||
rfc822
|
||||
);
|
||||
if (addrlist == null)
|
||||
return;
|
||||
public MailboxAddresses.from_rfc822_string(string rfc822)
|
||||
throws RFC822Error {
|
||||
var addrlist = GMime.InternetAddressList.parse(null, rfc822);
|
||||
if (addrlist == null) {
|
||||
throw new RFC822Error.INVALID("Not a RFC822 mailbox address list");
|
||||
}
|
||||
|
||||
int length = addrlist.length();
|
||||
for (int ctr = 0; ctr < length; ctr++) {
|
||||
|
|
|
|||
|
|
@ -169,17 +169,15 @@ public class Geary.RFC822.MessageIDList : Geary.MessageData.AbstractMessageData,
|
|||
public class Geary.RFC822.Date : Geary.RFC822.MessageData, Geary.MessageData.AbstractMessageData,
|
||||
Gee.Hashable<Geary.RFC822.Date> {
|
||||
|
||||
public string? original { get; private set; }
|
||||
public string original { get; private set; }
|
||||
public DateTime value { get; private set; }
|
||||
|
||||
public Date(string rfc822) throws ImapError {
|
||||
DateTime? value = GMime.utils_header_decode_date(rfc822);
|
||||
if (value == null) {
|
||||
throw new ImapError.PARSE_ERROR(
|
||||
"Unable to parse \"%s\": Outside supported range", rfc822
|
||||
);
|
||||
public Date(string rfc822) throws RFC822Error {
|
||||
var date = GMime.utils_header_decode_date(rfc822);
|
||||
if (date == null) {
|
||||
throw new RFC822Error.INVALID("Not ISO-8601 date: %s", rfc822);
|
||||
}
|
||||
this.value = value;
|
||||
this.value = date;
|
||||
this.original = rfc822;
|
||||
}
|
||||
|
||||
|
|
@ -302,42 +300,38 @@ public class Geary.RFC822.Header : Geary.MessageData.BlockMessageData, Geary.RFC
|
|||
private GMime.Message? message = null;
|
||||
private string[]? names = null;
|
||||
|
||||
public Header(Memory.Buffer buffer) {
|
||||
public Header(Memory.Buffer buffer) throws RFC822Error {
|
||||
base("RFC822.Header", buffer);
|
||||
}
|
||||
|
||||
private unowned GMime.HeaderList get_headers() throws RFC822Error {
|
||||
if (message != null)
|
||||
return message.get_header_list();
|
||||
|
||||
GMime.Parser parser = new GMime.Parser.with_stream(Utils.create_stream_mem(buffer));
|
||||
var parser = new GMime.Parser.with_stream(
|
||||
Utils.create_stream_mem(buffer)
|
||||
);
|
||||
parser.set_respect_content_length(false);
|
||||
parser.set_format(MESSAGE);
|
||||
|
||||
message = parser.construct_message(Geary.RFC822.get_parser_options());
|
||||
if (message == null)
|
||||
this.message = parser.construct_message(null);
|
||||
if (this.message == null) {
|
||||
throw new RFC822Error.INVALID("Unable to parse RFC 822 headers");
|
||||
|
||||
return message.get_header_list();
|
||||
}
|
||||
}
|
||||
|
||||
public string? get_header(string name) throws RFC822Error {
|
||||
GMime.Header header = get_headers().get_header(name);
|
||||
if (header != null)
|
||||
// We should not parse the raw-value here, but use GMime's parsing
|
||||
// functionality instead.
|
||||
// See: https://gitlab.gnome.org/GNOME/geary/merge_requests/382#note_669699
|
||||
return GMime.utils_header_unfold(header.get_raw_value());
|
||||
else
|
||||
return null;
|
||||
public string? get_header(string name) {
|
||||
string? value = null;
|
||||
var header = this.message.get_header_list().get_header(name);
|
||||
if (header != null) {
|
||||
value = header.get_value();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public string[] get_header_names() throws RFC822Error {
|
||||
public string[] get_header_names() {
|
||||
if (this.names == null) {
|
||||
this.names = new string[0];
|
||||
GMime.HeaderList headers = get_headers();
|
||||
for (int i = 0; i < headers.get_count(); i++) {
|
||||
names += headers.get_header_at(i).get_name();
|
||||
GMime.HeaderList headers = this.message.get_header_list();
|
||||
var names = new string[headers.get_count()];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = headers.get_header_at(i).get_name();
|
||||
}
|
||||
this.names = names;
|
||||
}
|
||||
return this.names;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* An RFC-822 style email message.
|
||||
*
|
||||
|
|
@ -99,16 +100,19 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
stock_from_gmime();
|
||||
}
|
||||
|
||||
public Message.from_gmime_message(GMime.Message message) {
|
||||
public Message.from_gmime_message(GMime.Message message)
|
||||
throws RFC822Error {
|
||||
this.message = message;
|
||||
stock_from_gmime();
|
||||
}
|
||||
|
||||
public Message.from_buffer(Memory.Buffer full_email) throws RFC822Error {
|
||||
public Message.from_buffer(Memory.Buffer full_email)
|
||||
throws RFC822Error {
|
||||
this(new Geary.RFC822.Full(full_email));
|
||||
}
|
||||
|
||||
public Message.from_parts(Header header, Text body) throws RFC822Error {
|
||||
public Message.from_parts(Header header, Text body)
|
||||
throws RFC822Error {
|
||||
GMime.StreamCat stream_cat = new GMime.StreamCat();
|
||||
stream_cat.add_source(new GMime.StreamMem.with_buffer(header.buffer.get_bytes().get_data()));
|
||||
stream_cat.add_source(new GMime.StreamMem.with_buffer(body.buffer.get_bytes().get_data()));
|
||||
|
|
@ -126,9 +130,11 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
|
||||
public async Message.from_composed_email(Geary.ComposedEmail email,
|
||||
string? message_id,
|
||||
GLib.Cancellable? cancellable) {
|
||||
GLib.Cancellable? cancellable)
|
||||
throws RFC822Error {
|
||||
this.message = new GMime.Message(true);
|
||||
|
||||
//
|
||||
// Required headers
|
||||
|
||||
this.from = email.from;
|
||||
|
|
@ -802,7 +808,8 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
* disabled by passing false in include_sub_messages). Note that values
|
||||
* that come out of this function are persisted.
|
||||
*/
|
||||
public string? get_searchable_body(bool include_sub_messages = true) {
|
||||
public string? get_searchable_body(bool include_sub_messages = true)
|
||||
throws RFC822Error {
|
||||
string? body = null;
|
||||
bool html = false;
|
||||
try {
|
||||
|
|
@ -880,81 +887,70 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
return attachments;
|
||||
}
|
||||
|
||||
private void stock_from_gmime() {
|
||||
GMime.HeaderList headers = this.message.get_header_list();
|
||||
private void stock_from_gmime() throws RFC822Error {
|
||||
GMime.HeaderList headers = this.message.headers;
|
||||
for (int i = 0; i < headers.get_count(); i++) {
|
||||
GMime.Header header = headers.get_header_at(i);
|
||||
string name = header.get_name();
|
||||
// We should not parse the raw-value here, but use GMime's parsing
|
||||
// functionality instead.
|
||||
// See: https://gitlab.gnome.org/GNOME/geary/merge_requests/382#note_669699
|
||||
string value = GMime.utils_header_unfold(header.get_raw_value());
|
||||
switch (name.down()) {
|
||||
case "from":
|
||||
this.from = append_address(this.from, value);
|
||||
break;
|
||||
string value = header.get_value();
|
||||
switch (header.get_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 "sender":
|
||||
this.sender = new MailboxAddress.from_rfc822_string(value);
|
||||
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 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":
|
||||
this.date = new Date(value);
|
||||
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(Geary.RFC822.get_parser_options(), value);
|
||||
break;
|
||||
case "x-mailer":
|
||||
this.mailer = GMime.utils_header_decode_text(null, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
// Ignore anything else not
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private MailboxAddresses append_address(MailboxAddresses? existing,
|
||||
string header_value) {
|
||||
string header_value)
|
||||
throws RFC822Error {
|
||||
MailboxAddresses addresses = new MailboxAddresses.from_rfc822_string(header_value);
|
||||
if (existing != null) {
|
||||
addresses = existing.append(addresses);
|
||||
|
|
@ -1063,13 +1059,16 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
}
|
||||
#endif
|
||||
|
||||
public Gee.List<Geary.RFC822.Message> get_sub_messages() {
|
||||
public Gee.List<Geary.RFC822.Message> get_sub_messages()
|
||||
throws RFC822Error {
|
||||
Gee.List<Geary.RFC822.Message> messages = new Gee.ArrayList<Geary.RFC822.Message>();
|
||||
find_sub_messages(messages, message.get_mime_part());
|
||||
return messages;
|
||||
}
|
||||
|
||||
private void find_sub_messages(Gee.List<Geary.RFC822.Message> messages, GMime.Object root) {
|
||||
private void find_sub_messages(Gee.List<Message> messages,
|
||||
GMime.Object root)
|
||||
throws RFC822Error {
|
||||
// If this is a multipart container, check each of its children.
|
||||
GMime.Multipart? multipart = root as GMime.Multipart;
|
||||
if (multipart != null) {
|
||||
|
|
@ -1084,7 +1083,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
|
|||
if (messagepart != null) {
|
||||
GMime.Message sub_message = messagepart.get_message();
|
||||
if (sub_message != null) {
|
||||
messages.add(new Geary.RFC822.Message.from_gmime_message(sub_message));
|
||||
messages.add(new Message.from_gmime_message(sub_message));
|
||||
} else {
|
||||
warning("Corrupt message, possibly bug 769697");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,7 +371,8 @@ This is the second line.
|
|||
assert_true(out_buffer.size > (buffer.size+buffer2.size), "Expected sizeable message");
|
||||
}
|
||||
|
||||
private async Geary.RFC822.Message message_from_composed_email(Geary.ComposedEmail composed) {
|
||||
private async Message message_from_composed_email(ComposedEmail composed)
|
||||
throws RFC822Error {
|
||||
return yield new Geary.RFC822.Message.from_composed_email(
|
||||
composed,
|
||||
GMime.utils_generate_message_id(composed.from.get(0).domain),
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@ class Integration.Smtp.ClientSession : TestCase {
|
|||
}
|
||||
|
||||
private async Geary.RFC822.Message new_message(Geary.RFC822.MailboxAddress from,
|
||||
Geary.RFC822.MailboxAddress to) {
|
||||
Geary.RFC822.MailboxAddress to)
|
||||
throws Geary.RFC822Error {
|
||||
Geary.ComposedEmail composed = new Geary.ComposedEmail(
|
||||
new GLib.DateTime.now_local(),
|
||||
new Geary.RFC822.MailboxAddresses.single(from)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue