IMAP import failed with "LIST mailbox name missing" when a mailbox name is a purely numeric unquoted atom (closes #26)
This commit is contained in:
@@ -225,6 +225,7 @@ impl<'r, R: BufRead> Parser<'r, R> {
|
||||
let name_val = self.parse_value()?;
|
||||
let name = match name_val {
|
||||
Value::Str(s) | Value::Atom(s) => s,
|
||||
Value::Number(n) => n.to_string(),
|
||||
Value::Bytes(b) => String::from_utf8_lossy(&b).into_owned(),
|
||||
_ => return Err(ImapError::Parse("LIST mailbox name missing".into())),
|
||||
};
|
||||
@@ -246,6 +247,7 @@ impl<'r, R: BufRead> Parser<'r, R> {
|
||||
self.skip_ws();
|
||||
let mailbox = match self.parse_value()? {
|
||||
Value::Str(s) | Value::Atom(s) => s,
|
||||
Value::Number(n) => n.to_string(),
|
||||
Value::Bytes(b) => String::from_utf8_lossy(&b).into_owned(),
|
||||
_ => return Err(ImapError::Parse("STATUS mailbox missing".into())),
|
||||
};
|
||||
@@ -862,6 +864,26 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untagged_list_with_numeric_atom_name() {
|
||||
let r = parse(b"* LIST (\\Subscribed \\HasNoChildren \\UnMarked) \"/\" 200\r\n");
|
||||
match r {
|
||||
Response::Untagged(Untagged::List {
|
||||
attributes,
|
||||
delimiter,
|
||||
name,
|
||||
}) => {
|
||||
assert_eq!(
|
||||
attributes,
|
||||
vec!["\\Subscribed", "\\HasNoChildren", "\\UnMarked"]
|
||||
);
|
||||
assert_eq!(delimiter, Some('/'));
|
||||
assert_eq!(name, "200");
|
||||
}
|
||||
_ => panic!("expected List"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untagged_status() {
|
||||
let r = parse(b"* STATUS INBOX (UIDVALIDITY 12345 UIDNEXT 42 MESSAGES 7)\r\n");
|
||||
@@ -876,6 +898,20 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untagged_status_with_numeric_atom_mailbox() {
|
||||
let r = parse(b"* STATUS 200 (MESSAGES 5 UIDNEXT 6 UIDVALIDITY 1778253936)\r\n");
|
||||
match r {
|
||||
Response::Untagged(Untagged::Status { mailbox, items }) => {
|
||||
assert_eq!(mailbox, "200");
|
||||
assert_eq!(items.get("MESSAGES"), Some(&5));
|
||||
assert_eq!(items.get("UIDNEXT"), Some(&6));
|
||||
assert_eq!(items.get("UIDVALIDITY"), Some(&1778253936));
|
||||
}
|
||||
_ => panic!("expected Status"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untagged_search_with_uids() {
|
||||
let r = parse(b"* SEARCH 1 3 5 7\r\n");
|
||||
|
||||
+17
-3
@@ -89,7 +89,14 @@ impl Logger {
|
||||
eprintln!("{proto} {command} -> {status} ({} ms)", elapsed.as_millis());
|
||||
}
|
||||
|
||||
pub fn trace_http_error(&self, proto: &str, method: &str, url: &str, error: &str, elapsed: Duration) {
|
||||
pub fn trace_http_error(
|
||||
&self,
|
||||
proto: &str,
|
||||
method: &str,
|
||||
url: &str,
|
||||
error: &str,
|
||||
elapsed: Duration,
|
||||
) {
|
||||
if !self.enabled(LEVEL_METHOD) {
|
||||
return;
|
||||
}
|
||||
@@ -222,7 +229,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn redact_wire_hides_login_arguments() {
|
||||
assert_eq!(redact_wire("LOGIN \"alice\" \"s3cret\""), "LOGIN <redacted>");
|
||||
assert_eq!(
|
||||
redact_wire("LOGIN \"alice\" \"s3cret\""),
|
||||
"LOGIN <redacted>"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -264,7 +274,11 @@ mod tests {
|
||||
fn body_for_log_caps_long_text_without_scanning_whole_blob() {
|
||||
let body = vec![b'a'; TRACE_BODY_CAP * 4];
|
||||
let out = body_for_log(&body, Some("text/plain"));
|
||||
assert!(out.contains("bytes total>"), "got tail {}", &out[out.len() - 40..]);
|
||||
assert!(
|
||||
out.contains("bytes total>"),
|
||||
"got tail {}",
|
||||
&out[out.len() - 40..]
|
||||
);
|
||||
assert!(out.len() < body.len());
|
||||
}
|
||||
|
||||
|
||||
@@ -151,8 +151,12 @@ impl SieveClient {
|
||||
let started = Instant::now();
|
||||
self.write_all(command.as_bytes())?;
|
||||
let block = read_response(&mut self.reader)?;
|
||||
self.logger
|
||||
.trace_cmd("SIEVE", command, &sieve_status(&block.status), started.elapsed());
|
||||
self.logger.trace_cmd(
|
||||
"SIEVE",
|
||||
command,
|
||||
&sieve_status(&block.status),
|
||||
started.elapsed(),
|
||||
);
|
||||
finish_block(block, &mut self.closed)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user