Skip to content

Commit

Permalink
Fix: Folders that contain a & can't be used (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Sep 16, 2023
1 parent 216fcf2 commit bb7f43e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 34 deletions.
28 changes: 19 additions & 9 deletions crates/imap-proto/src/parser/acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@
*/

use crate::{
protocol::acl::{self, ModRights, ModRightsOp, Rights},
protocol::{
acl::{self, ModRights, ModRightsOp, Rights},
ProtocolVersion,
},
receiver::Request,
utf7::utf7_maybe_decode,
Command,
};

Expand All @@ -45,19 +49,22 @@ use super::PushUnique;
*/

impl Request<Command> {
pub fn parse_acl(self) -> crate::Result<acl::Arguments> {
pub fn parse_acl(self, version: ProtocolVersion) -> crate::Result<acl::Arguments> {
let (has_identifier, has_mod_rights) = match self.command {
Command::SetAcl => (true, true),
Command::DeleteAcl | Command::ListRights => (true, false),
Command::GetAcl | Command::MyRights => (false, false),
_ => unreachable!(),
};
let mut tokens = self.tokens.into_iter();
let mailbox_name = tokens
.next()
.ok_or((self.tag.as_str(), "Missing mailbox name."))?
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?;
let mailbox_name = utf7_maybe_decode(
tokens
.next()
.ok_or((self.tag.as_str(), "Missing mailbox name."))?
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?,
version,
);
let identifier = if has_identifier {
tokens
.next()
Expand Down Expand Up @@ -138,7 +145,10 @@ impl ModRights {
mod tests {

use crate::{
protocol::acl::{self, ModRights, ModRightsOp, Rights},
protocol::{
acl::{self, ModRights, ModRightsOp, Rights},
ProtocolVersion,
},
receiver::Receiver,
};

Expand Down Expand Up @@ -222,7 +232,7 @@ mod tests {
receiver
.parse(&mut command.as_bytes().iter())
.unwrap()
.parse_acl()
.parse_acl(ProtocolVersion::Rev1)
.unwrap(),
arguments,
"{:?}",
Expand Down
24 changes: 14 additions & 10 deletions crates/imap-proto/src/parser/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
use crate::{
protocol::{
append::{self, Message},
Flag,
Flag, ProtocolVersion,
},
receiver::{Request, Token},
utf7::utf7_maybe_decode,
Command,
};

Expand All @@ -40,17 +41,20 @@ enum State {
}

impl Request<Command> {
pub fn parse_append(self) -> crate::Result<append::Arguments> {
pub fn parse_append(self, version: ProtocolVersion) -> crate::Result<append::Arguments> {
match self.tokens.len() {
0 | 1 => Err(self.into_error("Missing arguments.")),
_ => {
// Obtain mailbox name
let mut tokens = self.tokens.into_iter().peekable();
let mailbox_name = tokens
.next()
.unwrap()
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?;
let mailbox_name = utf7_maybe_decode(
tokens
.next()
.unwrap()
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?,
version,
);
let mut messages = Vec::new();

while tokens.peek().is_some() {
Expand Down Expand Up @@ -166,7 +170,7 @@ mod tests {
use crate::{
protocol::{
append::{self, Message},
Flag,
Flag, ProtocolVersion,
},
receiver::{Error, Receiver},
};
Expand Down Expand Up @@ -265,7 +269,7 @@ mod tests {
receiver
.parse(&mut command.as_bytes().iter())
.expect(command)
.parse_append()
.parse_append(ProtocolVersion::Rev1)
.expect(command),
arguments,
"{:?}",
Expand Down Expand Up @@ -298,7 +302,7 @@ mod tests {
match receiver.parse(&mut line.as_bytes().iter()) {
Ok(request) => {
assert_eq!(
request.parse_append().unwrap(),
request.parse_append(ProtocolVersion::Rev1).unwrap(),
append::Arguments {
tag: "A003".to_string(),
mailbox_name: "saved-messages".to_string(),
Expand Down
41 changes: 32 additions & 9 deletions crates/imap-proto/src/parser/copy_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@
* for more details.
*/

use crate::{protocol::copy_move, receiver::Request, Command};
use crate::{
protocol::{copy_move, ProtocolVersion},
receiver::Request,
utf7::utf7_maybe_decode,
Command,
};

use super::parse_sequence_set;

impl Request<Command> {
pub fn parse_copy_move(self) -> crate::Result<copy_move::Arguments> {
pub fn parse_copy_move(self, version: ProtocolVersion) -> crate::Result<copy_move::Arguments> {
if self.tokens.len() > 1 {
let mut tokens = self.tokens.into_iter();

Expand All @@ -38,11 +43,14 @@ impl Request<Command> {
.unwrap_bytes(),
)
.map_err(|v| (self.tag.as_str(), v))?,
mailbox_name: tokens
.next()
.ok_or((self.tag.as_str(), "Missing mailbox name."))?
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?,
mailbox_name: utf7_maybe_decode(
tokens
.next()
.ok_or((self.tag.as_str(), "Missing mailbox name."))?
.unwrap_string()
.map_err(|v| (self.tag.as_str(), v))?,
version,
),
tag: self.tag,
})
} else {
Expand All @@ -54,7 +62,7 @@ impl Request<Command> {
#[cfg(test)]
mod tests {
use crate::{
protocol::{copy_move, Sequence},
protocol::{copy_move, ProtocolVersion, Sequence},
receiver::Receiver,
};

Expand All @@ -66,7 +74,7 @@ mod tests {
receiver
.parse(&mut "A003 COPY 2:4 MEETING\r\n".as_bytes().iter())
.unwrap()
.parse_copy_move()
.parse_copy_move(ProtocolVersion::Rev1)
.unwrap(),
copy_move::Arguments {
sequence_set: Sequence::Range {
Expand All @@ -77,5 +85,20 @@ mod tests {
tag: "A003".to_string(),
}
);
assert_eq!(
receiver
.parse(&mut "A003 COPY 2:4 \"You &- Me\"\r\n".as_bytes().iter())
.unwrap()
.parse_copy_move(ProtocolVersion::Rev1)
.unwrap(),
copy_move::Arguments {
sequence_set: Sequence::Range {
start: 2.into(),
end: 4.into(),
},
mailbox_name: "You & Me".to_string(),
tag: "A003".to_string(),
}
);
}
}
8 changes: 4 additions & 4 deletions crates/imap/src/op/acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use crate::core::{MailboxId, Session, SessionData};

impl<T: AsyncRead> Session<T> {
pub async fn handle_get_acl(&mut self, request: Request<Command>) -> crate::OpResult {
match request.parse_acl() {
match request.parse_acl(self.version) {
Ok(arguments) => {
let data = self.state.session_data();
let is_rev2 = self.version.is_rev2();
Expand Down Expand Up @@ -165,7 +165,7 @@ impl<T: AsyncRead> Session<T> {
}

pub async fn handle_my_rights(&mut self, request: Request<Command>) -> crate::OpResult {
match request.parse_acl() {
match request.parse_acl(self.version) {
Ok(arguments) => {
let data = self.state.session_data();
let is_rev2 = self.version.is_rev2();
Expand Down Expand Up @@ -265,7 +265,7 @@ impl<T: AsyncRead> Session<T> {

pub async fn handle_set_acl(&mut self, request: Request<Command>) -> crate::OpResult {
let command = request.command;
match request.parse_acl() {
match request.parse_acl(self.version) {
Ok(arguments) => {
let data = self.state.session_data();

Expand Down Expand Up @@ -489,7 +489,7 @@ impl<T: AsyncRead> Session<T> {
}

pub async fn handle_list_rights(&mut self, request: Request<Command>) -> crate::OpResult {
match request.parse_acl() {
match request.parse_acl(self.version) {
Ok(arguments) => {
self.write_bytes(
StatusResponse::completed(Command::ListRights)
Expand Down
2 changes: 1 addition & 1 deletion crates/imap/src/op/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::core::{MailboxId, SelectedMailbox, Session, SessionData};

impl<T: AsyncRead> Session<T> {
pub async fn handle_append(&mut self, request: Request<Command>) -> crate::OpResult {
match request.parse_append() {
match request.parse_append(self.version) {
Ok(arguments) => {
let (data, selected_mailbox) = self.state.session_mailbox_state();

Expand Down
2 changes: 1 addition & 1 deletion crates/imap/src/op/copy_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<T: AsyncRead> Session<T> {
is_move: bool,
is_uid: bool,
) -> crate::OpResult {
match request.parse_copy_move() {
match request.parse_copy_move(self.version) {
Ok(arguments) => {
let (data, src_mailbox) = self.state.mailbox_state();

Expand Down

0 comments on commit bb7f43e

Please sign in to comment.