Fix: Folders that contain a & can't be used (#90)

This commit is contained in:
mdecimus 2023-09-16 11:06:52 +02:00
parent 216fcf2d73
commit bb7f43ecab
6 changed files with 71 additions and 34 deletions

View file

@ -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,
};
@ -45,7 +49,7 @@ 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),
@ -53,11 +57,14 @@ impl Request<Command> {
_ => 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()
@ -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,
};
@ -222,7 +232,7 @@ mod tests {
receiver
.parse(&mut command.as_bytes().iter())
.unwrap()
.parse_acl()
.parse_acl(ProtocolVersion::Rev1)
.unwrap(),
arguments,
"{:?}",

View file

@ -24,9 +24,10 @@
use crate::{
protocol::{
append::{self, Message},
Flag,
Flag, ProtocolVersion,
},
receiver::{Request, Token},
utf7::utf7_maybe_decode,
Command,
};
@ -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() {
@ -166,7 +170,7 @@ mod tests {
use crate::{
protocol::{
append::{self, Message},
Flag,
Flag, ProtocolVersion,
},
receiver::{Error, Receiver},
};
@ -265,7 +269,7 @@ mod tests {
receiver
.parse(&mut command.as_bytes().iter())
.expect(command)
.parse_append()
.parse_append(ProtocolVersion::Rev1)
.expect(command),
arguments,
"{:?}",
@ -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(),

View file

@ -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();
@ -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 {
@ -54,7 +62,7 @@ impl Request<Command> {
#[cfg(test)]
mod tests {
use crate::{
protocol::{copy_move, Sequence},
protocol::{copy_move, ProtocolVersion, Sequence},
receiver::Receiver,
};
@ -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 {
@ -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(),
}
);
}
}

View file

@ -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();
@ -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();
@ -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();
@ -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)

View file

@ -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();

View file

@ -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();