@@ -594,8 +594,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
594594 pub async fn rename < S1 : AsRef < str > , S2 : AsRef < str > > ( & mut self , from : S1 , to : S2 ) -> Result < ( ) > {
595595 self . run_command_and_check_ok ( & format ! (
596596 "RENAME {} {}" ,
597- quote! ( from. as_ref( ) ) ,
598- quote! ( to. as_ref( ) )
597+ validate_str ( from. as_ref( ) ) ? ,
598+ validate_str ( to. as_ref( ) ) ?
599599 ) )
600600 . await ?;
601601
@@ -611,7 +611,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
611611 /// However, it will not unilaterally remove an existing mailbox name from the subscription
612612 /// list even if a mailbox by that name no longer exists.
613613 pub async fn subscribe < S : AsRef < str > > ( & mut self , mailbox : S ) -> Result < ( ) > {
614- self . run_command_and_check_ok ( & format ! ( "SUBSCRIBE {}" , quote! ( mailbox. as_ref( ) ) ) )
614+ self . run_command_and_check_ok ( & format ! ( "SUBSCRIBE {}" , validate_str ( mailbox. as_ref( ) ) ? ) )
615615 . await ?;
616616 Ok ( ( ) )
617617 }
@@ -621,7 +621,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
621621 /// returned by [`Session::lsub`]. This command returns `Ok` only if the unsubscription is
622622 /// successful.
623623 pub async fn unsubscribe < S : AsRef < str > > ( & mut self , mailbox : S ) -> Result < ( ) > {
624- self . run_command_and_check_ok ( & format ! ( "UNSUBSCRIBE {}" , quote! ( mailbox. as_ref( ) ) ) )
624+ self . run_command_and_check_ok ( & format ! ( "UNSUBSCRIBE {}" , validate_str ( mailbox. as_ref( ) ) ? ) )
625625 . await ?;
626626 Ok ( ( ) )
627627 }
@@ -839,7 +839,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
839839 self . run_command_and_check_ok ( & format ! (
840840 "COPY {} {}" ,
841841 sequence_set. as_ref( ) ,
842- mailbox_name. as_ref( )
842+ validate_str ( mailbox_name. as_ref( ) ) ?
843843 ) )
844844 . await ?;
845845
@@ -856,7 +856,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
856856 self . run_command_and_check_ok ( & format ! (
857857 "UID COPY {} {}" ,
858858 uid_set. as_ref( ) ,
859- mailbox_name. as_ref( )
859+ validate_str ( mailbox_name. as_ref( ) ) ?
860860 ) )
861861 . await ?;
862862
@@ -966,7 +966,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
966966 let id = self
967967 . run_command ( & format ! (
968968 "LIST {} {}" ,
969- quote! ( reference_name. unwrap_or( "" ) ) ,
969+ validate_str ( reference_name. unwrap_or( "" ) ) ? ,
970970 mailbox_pattern. unwrap_or( "\" \" " )
971971 ) )
972972 . await ?;
@@ -1002,8 +1002,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
10021002 let id = self
10031003 . run_command ( & format ! (
10041004 "LSUB {} {}" ,
1005- quote! ( reference_name. unwrap_or( "" ) ) ,
1006- mailbox_pattern. unwrap_or( "" )
1005+ validate_str ( reference_name. unwrap_or( "" ) ) ? ,
1006+ validate_str ( mailbox_pattern. unwrap_or( "" ) ) ?
10071007 ) )
10081008 . await ?;
10091009 let names = parse_names (
@@ -1122,8 +1122,8 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
11221122 let content = content. as_ref ( ) ;
11231123 let id = self
11241124 . run_command ( & format ! (
1125- "APPEND \" {} \" {}{}{}{} {{{}}}" ,
1126- mailbox. as_ref( ) ,
1125+ "APPEND {} {}{}{}{} {{{}}}" ,
1126+ validate_str ( mailbox. as_ref( ) ) ? ,
11271127 if flags. is_some( ) { " " } else { "" } ,
11281128 flags. unwrap_or( "" ) ,
11291129 if internaldate. is_some( ) { " " } else { "" } ,
@@ -1226,7 +1226,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
12261226 /// The [`GETQUOTA` command](https://tools.ietf.org/html/rfc2087#section-4.2)
12271227 pub async fn get_quota ( & mut self , quota_root : & str ) -> Result < Quota > {
12281228 let id = self
1229- . run_command ( format ! ( "GETQUOTA {}" , quote! ( quota_root) ) )
1229+ . run_command ( format ! ( "GETQUOTA {}" , validate_str ( quota_root) ? ) )
12301230 . await ?;
12311231 let c = parse_get_quota (
12321232 & mut self . conn . stream ,
@@ -1243,7 +1243,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
12431243 mailbox_name : & str ,
12441244 ) -> Result < ( Vec < QuotaRoot > , Vec < Quota > ) > {
12451245 let id = self
1246- . run_command ( format ! ( "GETQUOTAROOT {}" , quote! ( mailbox_name) ) )
1246+ . run_command ( format ! ( "GETQUOTAROOT {}" , validate_str ( mailbox_name) ? ) )
12471247 . await ?;
12481248 let c = parse_get_quota_root (
12491249 & mut self . conn . stream ,
@@ -1269,7 +1269,7 @@ impl<T: Read + Write + Unpin + fmt::Debug + Send> Session<T> {
12691269 let id = self
12701270 . run_command ( format ! (
12711271 "GETMETADATA {} {}{}" ,
1272- quote! ( mailbox_name) ,
1272+ validate_str ( mailbox_name) ? ,
12731273 options,
12741274 entry_specifier
12751275 ) )
@@ -2014,15 +2014,19 @@ mod tests {
20142014 F : ' a + FnOnce ( Arc < Mutex < Session < MockStream > > > , & ' a str , & ' a str ) -> K ,
20152015 K : ' a + Future < Output = Result < T > > ,
20162016 {
2017- generic_with_uid (
2018- "A0001 OK COPY completed\r \n " ,
2019- "COPY" ,
2020- "2:4" ,
2021- "MEETING" ,
2022- prefix,
2023- op,
2024- )
2025- . await ;
2017+ let resp = "A0001 OK COPY completed\r \n " . as_bytes ( ) . to_vec ( ) ;
2018+ let seq = "2:4" ;
2019+ let query = "MEETING" ;
2020+ let line = format ! ( "A0001{prefix}COPY {seq} {}\r \n " , quote!( query) ) ;
2021+ let session = Arc :: new ( Mutex :: new ( mock_session ! ( MockStream :: new( resp) ) ) ) ;
2022+
2023+ {
2024+ let _ = op ( session. clone ( ) , seq, query) . await . unwrap ( ) ;
2025+ }
2026+ assert ! (
2027+ session. lock( ) . await . stream. inner. written_buf == line. as_bytes( ) . to_vec( ) ,
2028+ "Invalid command"
2029+ ) ;
20262030 }
20272031
20282032 #[ cfg_attr( feature = "runtime-tokio" , tokio:: test) ]
0 commit comments