From 41e159588d17acde7fba41fea8e724b2459a6076 Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 18 Feb 2022 21:51:17 -0800 Subject: [PATCH 1/2] Add missing parsers --- .../Grammar/Message/MessageAttributes.swift | 12 +++++++++ .../Grammar/GrammarParser+Message.swift | 27 ++++++++++++++++++- .../Grammar/GrammarParser+Message+Tests.swift | 9 +++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift b/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift index ced1e50ee..fb9d1b35f 100644 --- a/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift +++ b/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift @@ -28,6 +28,12 @@ public enum MessageAttribute: Hashable { case uid(UID) /// `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. /// @@ -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) } } diff --git a/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift b/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift index e157cd163..6a837da89 100644 --- a/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift +++ b/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift @@ -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)) @@ -176,12 +177,26 @@ extension GrammarParser { try PL.parseFixedString(")", buffer: &buffer, tracker: tracker) 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, @@ -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) } diff --git a/Tests/NIOIMAPCoreTests/Parser/Grammar/GrammarParser+Message+Tests.swift b/Tests/NIOIMAPCoreTests/Parser/Grammar/GrammarParser+Message+Tests.swift index 237f92401..604f28825 100644 --- a/Tests/NIOIMAPCoreTests/Parser/Grammar/GrammarParser+Message+Tests.swift +++ b/Tests/NIOIMAPCoreTests/Parser/Grammar/GrammarParser+Message+Tests.swift @@ -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: [] From b91bb8ba71ddac8cb44eb931259a903c0db3ef54 Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 18 Feb 2022 22:04:47 -0800 Subject: [PATCH 2/2] Soundness --- .../NIOIMAPCore/Grammar/Message/MessageAttributes.swift | 6 +++--- .../Parser/Grammar/GrammarParser+Message.swift | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift b/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift index fb9d1b35f..f8cce515c 100644 --- a/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift +++ b/Sources/NIOIMAPCore/Grammar/Message/MessageAttributes.swift @@ -28,11 +28,11 @@ public enum MessageAttribute: Hashable { case uid(UID) /// `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. diff --git a/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift b/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift index 6a837da89..29cc94548 100644 --- a/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift +++ b/Sources/NIOIMAPCore/Parser/Grammar/GrammarParser+Message.swift @@ -177,17 +177,17 @@ extension GrammarParser { try PL.parseFixedString(")", buffer: &buffer, tracker: tracker) 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)) @@ -206,7 +206,7 @@ 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