mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-02-25 08:23:00 +08:00
Fix: Folders that contain a & can't be used (#90)
This commit is contained in:
parent
216fcf2d73
commit
bb7f43ecab
6 changed files with 71 additions and 34 deletions
|
@ -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,
|
||||
"{:?}",
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue