diff options
| -rw-r--r-- | Changelog | 2 | ||||
| -rwxr-xr-x | pullimap | 11 | ||||
| -rw-r--r-- | tests/pullimap/t | 61 | ||||
| -rwxr-xr-x | tests/run | 6 | 
4 files changed, 65 insertions, 15 deletions
@@ -107,6 +107,8 @@ interimap (0.5) upstream;     for other servers the number remains 1).   - interimap: gracefully ignore messages with a NIL RFC822 attribute.   - pullimap: treat messages with a NIL RFC822 attribute as empty. + - pullimap: fix mangling of data lines starting with a dot (when an RFC +   5322 line starts with a '.', double it).   -- Guilhem Moulin <guilhem@fripost.org>  Fri, 10 May 2019 00:58:14 +0200 @@ -175,17 +175,18 @@ sub sendmail($$) {          my $length = length($$rfc822);          while ((my $end = index($$rfc822, "\r\n", $offset) + 2) != 1) {              my $line = substr($$rfc822, $offset, $end-$offset); -            # RFC 5321 section 4.5.2: the character sequence "\r\n.\r\n" -            # ends the mail text and cannot be sent by the user -            $SMTP->print($line eq ".\r\n" ? "..\r\n" : $line) or die; +            # RFC 5321 sec. 4.5.2: if the line starts with a dot, double it +            $line = ".".$line if substr($line, 0, 1) eq "."; +            $SMTP->print($line) or die;              $offset = $end;          }          if ($offset < $length) {              # the last line did not end with "\r\n"; add it in order to              # have the receiving SMTP server recognize the "end of data" -            # condition.  See RFC 5321 section 4.1.1.4 +            # condition.  See RFC 5321 sec. 4.1.1.4              my $line = substr($$rfc822, $offset); -            $SMTP->print(($line eq "." ? ".." : $line), "\r\n") or die; +            $line = ".".$line if substr($line, 0, 1) eq "."; +            $SMTP->print($line, "\r\n") or die;          }          $SMTP->printflush(".\r\n") or die;      } diff --git a/tests/pullimap/t b/tests/pullimap/t index 7ae0c5f..79da3e0 100644 --- a/tests/pullimap/t +++ b/tests/pullimap/t @@ -6,12 +6,9 @@ step_start "\`pullimap --idle\` refuses to create the state file"  ! pullimap --idle "remote" || error  step_done -# make sure remote UIDs are 11-bytes long -doveadm -u "remote" mailbox update --min-next-uid 1000000000 "$MAILBOX" -  # compare mailboxes; can't compare the RFC 3501 TEXT as LMTP adds a  # Received: header. -# TODO unset lmtp_add_received_header once avaisable in Sid: +# TODO unset lmtp_add_received_header once available in sid:  # https://doc.dovecot.org/settings/dovecot_core_settings/#lmtp-add-received-header  list_mails_sha256() {      local u="$1" guid uid @@ -26,7 +23,59 @@ check() {          <( list_mails_sha256 "remote" ) \          || error "mailboxes differ"  } +message_from() { +    local date="$(date +"%s.%N")" sender="$1" +    cat <<-EOF +		From: $sender +		To: <me@example.net> +		Date: $(date -R -d@"$date") +		Message-ID: <$date@example.net> + +	EOF +    xxd -ps -l8 /dev/urandom +} +step_start "Quote envelope sender address" +declare -a senders=("sender" "first.last" "foo-bar" \"\" "\"x\\\" #&\\\\y\"") +for s in "${senders[@]}"; do +    message_from "$s@example.net" | deliver -u "remote" -- -m "$MAILBOX" +done +pullimap "remote" || error +check +for s in "${senders[@]}"; do +    grep -F " from <$s@example.net> " <"$STDERR" || error "$s" +done +step_done + +step_start "Mail without data" +deliver -u "remote" -- -m "$MAILBOX" </dev/null +pullimap "remote" || error +check +step_done + +step_start "Dot-leading lines" +deliver -u "remote" -- -m "$MAILBOX" <<-EOF +	From: alice@example.net +	To: bob@example.net +	Date: $(date -R) +    Message-ID: <$(xxd -ps -l8 /dev/urandom)@example.net> + +	foo +	. +	.bar +	..baz +EOF +# we can't add a test for message data not ending with CRLF, because the +# LMTP/SMTP client needs to add a CRLF so local and remote message +# bodies would differ.  that said, while such a message could be added +# by IMAP and LDA, it's not valid for SMTP (RFC 5321 sec. 4.1.1.4) +pullimap "remote" || error +check +step_done + + +# make sure remote UIDs are 11-bytes long +doveadm -u "remote" mailbox update --min-next-uid 1000000000 "$MAILBOX"  # Add some messages and sync  step_start "Fetching messages" @@ -40,11 +89,11 @@ check  # same thing, but with some missing messages  for ((i = 0; i < N; i+=2)); do      sample_message | deliver -u "remote" -- -m "$MAILBOX" -    deliver -u "remote" -- -m "$MAILBOX" </dev/null # even seqnum +    deliver -u "remote" -- -m "$MAILBOX" </dev/null # odd seqnum  done  for ((i = 0; i < N; i+=2)); do      # expunge every other message -    doveadm -u "remote" expunge mailbox "$MAILBOX" $((N-i+32)) +    doveadm -u "remote" expunge mailbox "$MAILBOX" $((N-i+32+7))      sample_message | deliver -u "remote" -- -m "$MAILBOX"  done @@ -235,11 +235,9 @@ sqlite3() {  # Sample (random) message  sample_message() {      local date="$(date +"%s.%N")" -    # also try non-conventional addresses for pullimap -    local sender="$(shuf -n1 -e "sender" "first.last" "foo-bar" \"\" "\"x\\\" #&\\\\y\"" )"      cat <<-EOF -		From: <$sender@example.net> -		To: <recipient@example.net> +		From: <$(xxd -ps -l6 /dev/urandom)@example.net> +		To: <me@example.net>  		Date: $(date -R -d@"$date")  		Message-ID: <$date@example.net>  | 
