Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing RFC822 parsers #689

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public enum MessageAttribute: Hashable {
/// `RFC822.SIZE` -- A number expressing the RFC 2822 size of the message.
case rfc822Size(Int)

case rfc822(ByteBuffer?)

case rfc822Text(ByteBuffer?)

case rfc822Header(ByteBuffer?)

/// `BODYSTRUCTURE` or `BODY` -- A list that describes the MIME body structure of a message.
///
/// A `BODYSTRUCTURE` response will have `hasExtensionData` set to `true`.
Expand Down Expand Up @@ -91,6 +97,12 @@ extension EncodeBuffer {
return self.writeMessageAttribute_gmailThreadID(id)
case .gmailLabels(let labels):
return self.writeMessageAttribute_gmailLabels(labels)
case .rfc822(let buffer):
return self.writeMessageAttribute_rfc822(buffer)
case .rfc822Header(let buffer):
return self.writeMessageAttribute_rfc822Header(buffer)
case .rfc822Text(let buffer):
return self.writeMessageAttribute_rfc822Text(buffer)
}
}

Expand Down
27 changes: 26 additions & 1 deletion Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ let badOS = { fatalError("unsupported OS") }()

import struct NIO.ByteBuffer
import struct NIO.ByteBufferView
import SwiftUI

extension GrammarParser {
// message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
Expand Down Expand Up @@ -177,11 +178,25 @@ extension GrammarParser {
return .gmailLabels(attributes)
}

func parseMessageAttribute_rfc822(buffer: inout ParseBuffer, tracker: StackTracker) throws -> MessageAttribute {
try PL.parseSpaces(buffer: &buffer, tracker: tracker)
return .rfc822(try self.parseNString(buffer: &buffer, tracker: tracker))
}

func parseMessageAttribute_rfc822Text(buffer: inout ParseBuffer, tracker: StackTracker) throws -> MessageAttribute {
try PL.parseSpaces(buffer: &buffer, tracker: tracker)
return .rfc822Text(try self.parseNString(buffer: &buffer, tracker: tracker))
}

func parseMessageAttribute_rfc822Header(buffer: inout ParseBuffer, tracker: StackTracker) throws -> MessageAttribute {
try PL.parseSpaces(buffer: &buffer, tracker: tracker)
return .rfc822Header(try self.parseNString(buffer: &buffer, tracker: tracker))
}

let parsers: [String: (inout ParseBuffer, StackTracker) throws -> MessageAttribute] = [
"FLAGS": parseMessageAttribute_flags,
"ENVELOPE": parseMessageAttribute_envelope,
"INTERNALDATE": parseMessageAttribute_internalDate,
"RFC822.SIZE": parseMessageAttribute_rfc822Size,
"BODY": parseMessageAttribute_body,
"BODYSTRUCTURE": parseMessageAttribute_bodyStructure,
"UID": parseMessageAttribute_uid,
Expand All @@ -191,6 +206,16 @@ extension GrammarParser {
"X-GM-THRID": parseMessageAttribute_gmailThreadID,
"X-GM-LABELS": parseMessageAttribute_gmailLabels,
"MODSEQ": parseMessageAttribute_fetchModifierResponse,

// note the order matters here
// RFC822 needs to be the *last* attempted out of
// all of the RFC822.* options, as RFC822.SIZE will
// successfully parse as rfc822(nil), but the next
// parser will fail
"RFC822.SIZE": parseMessageAttribute_rfc822Size,
"RFC822.HEADER": parseMessageAttribute_rfc822Header,
"RFC822.TEXT": parseMessageAttribute_rfc822Text,
"RFC822": parseMessageAttribute_rfc822,
]
return try self.parseFromLookupTable(buffer: &buffer, tracker: tracker, parsers: parsers)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ extension GrammarParser_Message_Tests {
("X-GM-LABELS ()", " ", .gmailLabels([]), #line),
(#"X-GM-LABELS (\Drafts)"#, " ", .gmailLabels([GmailLabel(#"\Drafts"#)]), #line),
(#"X-GM-LABELS ("\\Important")"#, " ", .gmailLabels([GmailLabel(#"\Important"#)]), #line),
("RFC822 NIL", " ", .rfc822(nil), #line),
(#"RFC822 "test""#, " ", .rfc822("test"), #line),
("RFC822 {4}\r\ntest", " ", .rfc822("test"), #line),
("RFC822.TEXT NIL", " ", .rfc822Text(nil), #line),
(#"RFC822.TEXT "test""#, " ", .rfc822Text("test"), #line),
("RFC822.TEXT {4}\r\ntest", " ", .rfc822Text("test"), #line),
("RFC822.HEADER NIL", " ", .rfc822Header(nil), #line),
(#"RFC822.HEADER "test""#, " ", .rfc822Header("test"), #line),
("RFC822.HEADER {4}\r\ntest", " ", .rfc822Header("test"), #line),
],
parserErrorInputs: [],
incompleteMessageInputs: []
Expand Down