Skip to content

Commit

Permalink
FramingParser: Allow un-matched DQUOTE in lines
Browse files Browse the repository at this point in the history
  • Loading branch information
danieleggert committed Dec 16, 2024
1 parent 2cd1c55 commit 23ad08b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
8 changes: 5 additions & 3 deletions Sources/NIOIMAP/Client/FramingParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,11 @@ extension FramingParser {
let byte = self.readByte()
switch (byte, quotedState) {
case (CR, _), (LF, _):
// This is bogus: Can’t have CR or LR inside quoted string.
// Complete the frame and let it fail.
return .parsedCompleteFrame
// Can’t have CR or LF inside quoted strings, but certain
// parts (notably `text`) is allowed to have _any_ character
// (except CR or LF).
// Thus, fall through to “normal” state:
return readByte_state_normalTraversal(lineFeedStrategy: .includeInFrame)

case (ESCAPE, .normal):
self.state = .insideQuoted(.escaped)
Expand Down
20 changes: 20 additions & 0 deletions Tests/NIOIMAPTests/FramingParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ extension FramingParserTests {
XCTAssertEqual(try self.parser.appendAndFrameBuffer(&buffer), [.complete("A1 NOOP\r\n")])
}

func testSingleQuoteInLine() {
// RFC 3501 allows un-matched `"` in `text` parts, such as the text of an untagged OK response.
//
// Test that this:
//
// S: * OK Hello " foo
// S: * NO Hello bar
//
// gets parsed into the corresponding two frames / lines.
do {
var buffer: ByteBuffer = "* OK Hello \" foo\r\n"
XCTAssertEqual(try self.parser.appendAndFrameBuffer(&buffer), [.complete("* OK Hello \" foo\r\n")])
}
// Check that the next line parses:
do {
var buffer: ByteBuffer = "* NO Hello bar\r\n"
XCTAssertEqual(try self.parser.appendAndFrameBuffer(&buffer), [.complete("* NO Hello bar\r\n")])
}
}

func testCommandWithQuoted() {
var buffer: ByteBuffer = "A1 LOGIN \"foo\" \"bar\"\r\n"
XCTAssertEqual(try self.parser.appendAndFrameBuffer(&buffer), [.complete("A1 LOGIN \"foo\" \"bar\"\r\n")])
Expand Down

0 comments on commit 23ad08b

Please sign in to comment.