Merge branch 'mjog/message-id-db' into 'mainline'

Message-Id data stored incorrectly in the database

Closes #834

See merge request GNOME/geary!540
This commit is contained in:
Michael Gratton 2020-08-13 08:28:26 +00:00
commit 3e156525ae
5 changed files with 116 additions and 4 deletions

7
sql/version-027.sql Normal file
View file

@ -0,0 +1,7 @@
--
-- Rebuild corrupted message ids.
--
UPDATE MessageTable
SET message_id = '<' || message_id || '>'
WHERE (message_id NOT LIKE '<%') AND (message_id NOT LIKE ' <%');

View file

@ -494,8 +494,8 @@ private class Geary.ImapDB.Account : BaseObject {
yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
Db.Statement stmt = cx.prepare("SELECT id FROM MessageTable WHERE message_id = ? OR in_reply_to = ?");
stmt.bind_string(0, message_id.value);
stmt.bind_string(1, message_id.value);
stmt.bind_string(0, message_id.to_rfc822_string());
stmt.bind_string(1, message_id.to_rfc822_string());
Db.Result result = stmt.exec(cancellable);
while (!result.finished) {

View file

@ -209,7 +209,7 @@ private class Geary.ImapDB.MessageRow {
}
if (email.fields.is_all_set(Geary.Email.Field.REFERENCES)) {
message_id = (email.message_id != null) ? email.message_id.value : null;
message_id = (email.message_id != null) ? email.message_id.to_rfc822_string() : null;
in_reply_to = (email.in_reply_to != null) ? email.in_reply_to.to_rfc822_string() : null;
references = (email.references != null) ? email.references.to_rfc822_string() : null;

View file

@ -107,7 +107,7 @@ class Geary.ImapDB.DatabaseTest : TestCase {
);
db.open.end(async_result());
assert_equal<int?>(db.get_schema_version(), 26, "Post-upgrade version");
assert_equal<int?>(db.get_schema_version(), 27, "Post-upgrade version");
// Since schema v22 deletes the re-creates all attachments,
// attachment 12 should no longer exist on the file system and

View file

@ -15,6 +15,7 @@ class Geary.RFC822.MessageDataTest : TestCase {
add_test("header_from_rfc822", header_from_rfc822);
add_test("header_names_from_rfc822", header_names_from_rfc822);
add_test("PreviewText.with_header", preview_text_with_header);
add_test("MessageIDList.from_rfc822_string", message_id_list_from_rfc822_string);
}
public void preview_text_with_header() throws GLib.Error {
@ -108,6 +109,110 @@ class Geary.RFC822.MessageDataTest : TestCase {
assert_equal(neg_half_hour_tz.to_rfc822_string(), NEG_HALF_HOUR_TZ);
}
public void message_id_list_from_rfc822_string() throws GLib.Error {
// Standard variants
assert_collection(
new MessageIDList.from_rfc822_string("<id@example.com>").get_all(),
"<id@example.com>"
)
.size(1)
.contains(new MessageID("id@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("<id1@example.com><id2@example.com>").get_all(),
"<id1@example.com><id2@example.com>"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("<id1@example.com> <id2@example.com>").get_all(),
"<id1@example.com> <id2@example.com>"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
// Parens as delim are invalid but seen in the wild
assert_collection(
new MessageIDList.from_rfc822_string("(id@example.com)").get_all(),
"(id@example.com)"
)
.size(1)
.contains(new MessageID("id@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("(id1@example.com)(id2@example.com>").get_all(),
"(id1@example.com)(id2@example.com>"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("(id1@example.com) (id2@example.com)").get_all(),
"(id1@example.com) (id2@example.com)"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
// No delimiters
assert_collection(
new MessageIDList.from_rfc822_string("id@example.com").get_all(),
"id@example.com"
)
.size(1)
.contains(new MessageID("id@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("id1@example.com id2@example.com").get_all(),
"id1@example.com id2@example.com"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
// Comma-separated is invalid but seen in the wild
assert_collection(
new MessageIDList.from_rfc822_string("<id1@example.com>,<id2@example.com>").get_all(),
"<id1@example.com>,<id2@example.com>"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("<id1@example.com>, <id2@example.com>").get_all(),
"<id1@example.com>, <id2@example.com>"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("(id1@example.com),(id2@example.com)").get_all(),
"(id1@example.com),(id2@example.com)"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
assert_collection(
new MessageIDList.from_rfc822_string("(id1@example.com), (id2@example.com)").get_all(),
"(id1@example.com), (id2@example.com)"
)
.size(2)
.contains(new MessageID("id1@example.com"))
.contains(new MessageID("id2@example.com"));
}
private const string HEADER_FIXTURE = """From: Test <test@example.com>
Subject: test