Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 27 additions & 23 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
pub async fn rename<S1: AsRef<str>, S2: AsRef<str>>(&mut self, from: S1, to: S2) -> Result<()> {
self.run_command_and_check_ok(&format!(
"RENAME {} {}",
quote!(from.as_ref()),
quote!(to.as_ref())
validate_str(from.as_ref())?,
validate_str(to.as_ref())?
))
.await?;

Expand All @@ -611,7 +611,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
/// However, it will not unilaterally remove an existing mailbox name from the subscription
/// list even if a mailbox by that name no longer exists.
pub async fn subscribe<S: AsRef<str>>(&mut self, mailbox: S) -> Result<()> {
self.run_command_and_check_ok(&format!("SUBSCRIBE {}", quote!(mailbox.as_ref())))
self.run_command_and_check_ok(&format!("SUBSCRIBE {}", validate_str(mailbox.as_ref())?))
.await?;
Ok(())
}
Expand All @@ -621,7 +621,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
/// returned by [`Session::lsub`]. This command returns `Ok` only if the unsubscription is
/// successful.
pub async fn unsubscribe<S: AsRef<str>>(&mut self, mailbox: S) -> Result<()> {
self.run_command_and_check_ok(&format!("UNSUBSCRIBE {}", quote!(mailbox.as_ref())))
self.run_command_and_check_ok(&format!("UNSUBSCRIBE {}", validate_str(mailbox.as_ref())?))
.await?;
Ok(())
}
Expand Down Expand Up @@ -839,7 +839,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
self.run_command_and_check_ok(&format!(
"COPY {} {}",
sequence_set.as_ref(),
mailbox_name.as_ref()
validate_str(mailbox_name.as_ref())?
))
.await?;

Expand All @@ -856,7 +856,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
self.run_command_and_check_ok(&format!(
"UID COPY {} {}",
uid_set.as_ref(),
mailbox_name.as_ref()
validate_str(mailbox_name.as_ref())?
))
.await?;

Expand Down Expand Up @@ -966,7 +966,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
let id = self
.run_command(&format!(
"LIST {} {}",
quote!(reference_name.unwrap_or("")),
validate_str(reference_name.unwrap_or(""))?,
mailbox_pattern.unwrap_or("\"\"")
))
.await?;
Expand Down Expand Up @@ -1002,8 +1002,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
let id = self
.run_command(&format!(
"LSUB {} {}",
quote!(reference_name.unwrap_or("")),
mailbox_pattern.unwrap_or("")
validate_str(reference_name.unwrap_or(""))?,
validate_str(mailbox_pattern.unwrap_or(""))?
))
.await?;
let names = parse_names(
Expand Down Expand Up @@ -1122,8 +1122,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
let content = content.as_ref();
let id = self
.run_command(&format!(
"APPEND \"{}\"{}{}{}{} {{{}}}",
mailbox.as_ref(),
"APPEND {}{}{}{}{} {{{}}}",
validate_str(mailbox.as_ref())?,
if flags.is_some() { " " } else { "" },
flags.unwrap_or(""),
if internaldate.is_some() { " " } else { "" },
Expand Down Expand Up @@ -1226,7 +1226,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
/// The [`GETQUOTA` command](https://tools.ietf.org/html/rfc2087#section-4.2)
pub async fn get_quota(&mut self, quota_root: &str) -> Result<Quota> {
let id = self
.run_command(format!("GETQUOTA {}", quote!(quota_root)))
.run_command(format!("GETQUOTA {}", validate_str(quota_root)?))
.await?;
let c = parse_get_quota(
&mut self.conn.stream,
Expand All @@ -1243,7 +1243,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
mailbox_name: &str,
) -> Result<(Vec<QuotaRoot>, Vec<Quota>)> {
let id = self
.run_command(format!("GETQUOTAROOT {}", quote!(mailbox_name)))
.run_command(format!("GETQUOTAROOT {}", validate_str(mailbox_name)?))
.await?;
let c = parse_get_quota_root(
&mut self.conn.stream,
Expand All @@ -1269,7 +1269,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
let id = self
.run_command(format!(
"GETMETADATA {} {}{}",
quote!(mailbox_name),
validate_str(mailbox_name)?,
options,
entry_specifier
))
Expand Down Expand Up @@ -2014,15 +2014,19 @@ mod tests {
F: 'a + FnOnce(Arc<Mutex<Session<MockStream>>>, &'a str, &'a str) -> K,
K: 'a + Future<Output = Result<T>>,
{
generic_with_uid(
"A0001 OK COPY completed\r\n",
"COPY",
"2:4",
"MEETING",
prefix,
op,
)
.await;
let resp = "A0001 OK COPY completed\r\n".as_bytes().to_vec();
let seq = "2:4";
let query = "MEETING";
let line = format!("A0001{prefix}COPY {seq} {}\r\n", quote!(query));
let session = Arc::new(Mutex::new(mock_session!(MockStream::new(resp))));

{
let _ = op(session.clone(), seq, query).await.unwrap();
}
assert!(
session.lock().await.stream.inner.written_buf == line.as_bytes().to_vec(),
"Invalid command"
);
}

#[cfg_attr(feature = "runtime-tokio", tokio::test)]
Expand Down
Loading