got distracted by formatting responses

This commit is contained in:
Michael Zhang 2021-08-23 02:11:06 -05:00
parent e78022f8ab
commit 5aa54dbfe3
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
3 changed files with 91 additions and 5 deletions

View file

@ -6,3 +6,8 @@ doc:
watch:
cargo watch -c
fuzz-imap:
#!/bin/bash
cd imap
cargo +nightly fuzz run parse_response

View file

@ -4,6 +4,3 @@ afl:
pwd
cargo afl build
cargo afl fuzz -i in -o out target/debug/imap-parsing-fuzz-target
fuzz:
cargo +nightly fuzz run parse_response

View file

@ -57,6 +57,17 @@ pub enum Response {
impl DisplayBytes for Response {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
Response::Capabilities(caps) => {
write_bytes!(w, b"CAPABILITY")?;
for cap in caps {
write_bytes!(w, b" {}", cap)?;
}
Ok(())
}
Response::Condition(cond) => write_bytes!(w, b"* {}", cond),
Response::Done(done) => write_bytes!(w, b""),
Response::MailboxData(data) => write_bytes!(w, b"* {}\r\n", data),
Response::Expunge(n) => write_bytes!(w, b"{} EXPUNGE", n),
_ => todo!(),
}
}
@ -126,6 +137,16 @@ pub struct Condition {
pub info: Bytes,
}
impl DisplayBytes for Condition {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
write_bytes!(w, b"{} ", self.status)?;
if let Some(code) = &self.code {
write_bytes!(w, b"[{}] ", code)?;
}
write_bytes!(w, b"{}", self.info)
}
}
#[derive(Debug)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub enum Status {
@ -136,6 +157,18 @@ pub enum Status {
Bye,
}
impl DisplayBytes for Status {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
Status::Ok => write_bytes!(w, b"OK"),
Status::No => write_bytes!(w, b"NO"),
Status::Bad => write_bytes!(w, b"BAD"),
Status::PreAuth => write_bytes!(w, b"PREAUTH"),
Status::Bye => write_bytes!(w, b"BYE"),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
@ -158,6 +191,14 @@ pub enum ResponseCode {
Other(Bytes, Option<Bytes>),
}
impl DisplayBytes for ResponseCode {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
_ => todo!(),
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub enum UidSetMember {
@ -173,6 +214,16 @@ pub enum Capability {
Atom(Atom),
}
impl DisplayBytes for Capability {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
Capability::Imap4rev1 => write_bytes!(w, b"IMAP4rev1"),
Capability::Auth(a) => write_bytes!(w, b"AUTH={}", a),
Capability::Atom(a) => write_bytes!(w, b"{}", a),
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub enum MailboxData {
@ -185,6 +236,24 @@ pub enum MailboxData {
Recent(u32),
}
impl DisplayBytes for MailboxData {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
MailboxData::Flags(flags) => {
write_bytes!(w, b"(")?;
for (i, flag) in flags.iter().enumerate() {
if i != 0 {
write_bytes!(w, b" ")?;
}
write_bytes!(w, b"{}", flag)?;
}
write_bytes!(w, b")")
}
_ => todo!(),
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub enum Mailbox {
@ -205,6 +274,21 @@ pub enum Flag {
Extension(Atom),
}
impl DisplayBytes for Flag {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
match self {
Flag::Answered => write_bytes!(w, b"\\Answered"),
Flag::Flagged => write_bytes!(w, b"\\Flagged"),
Flag::Deleted => write_bytes!(w, b"\\Deleted"),
Flag::Seen => write_bytes!(w, b"\\Seen"),
Flag::Draft => write_bytes!(w, b"\\Draft"),
Flag::Recent => write_bytes!(w, b"\\Recent"),
Flag::Keyword(atom) => write_bytes!(w, b"{}", atom),
Flag::Extension(atom) => write_bytes!(w, b"\\{}", atom),
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
pub struct MailboxList {