]> git.notmuchmail.org Git - notmuch/commitdiff
Merge branch 'release'
authorDavid Bremner <david@tethera.net>
Sat, 4 Sep 2021 15:05:32 +0000 (08:05 -0700)
committerDavid Bremner <david@tethera.net>
Sat, 4 Sep 2021 15:05:32 +0000 (08:05 -0700)
13 files changed:
emacs/notmuch-draft.el
emacs/notmuch-hello.el
emacs/notmuch-jump.el
emacs/notmuch-show.el
emacs/notmuch-tag.el
emacs/notmuch-tree.el
emacs/notmuch.el
lib/message-file.c
notmuch-reply.c
test/T220-reply.sh
test/T357-index-decryption.sh
test/T450-emacs-show.sh
test/corpora/crypto/encrypted-rfc822-attachment [new file with mode: 0644]

index a68b7d8da002a7f3f76b2ccded426bb465724de7..aeb6c5882a4125da3e19c528999dd8c557fffb56 100644 (file)
@@ -42,7 +42,7 @@
   :group 'notmuch)
 
 (defcustom notmuch-draft-tags '("+draft")
-  "List of tags changes to apply to a draft message when it is saved in the database.
+  "List of tag changes to apply when saving a draft message in the database.
 
 Tags starting with \"+\" (or not starting with either \"+\" or
 \"-\") in the list will be added, and tags starting with \"-\"
index 1e66555b7fc17cb6a2b7c9a755c388ea620a9185..21855b7021e946b2c0c9b5965b5874dae5f90782 100644 (file)
@@ -144,9 +144,11 @@ a plist. Supported properties are
                    Possible values are `oldest-first', `newest-first'
                    or nil. Nil means use the default sort order.
   :search-type     Specify whether to run the search in search-mode,
-                   tree mode or unthreaded mode. Set to 'tree to specify tree
-                   mode, 'unthreaded to specify unthreaded mode, and set to nil
-                   (or anything except tree and unthreaded) to specify search mode.
+                   tree mode or unthreaded mode. Set to `tree' to
+                   specify tree mode, 'unthreaded to specify
+                   unthreaded mode, and set to nil (or anything
+                   except tree and unthreaded) to specify search
+                   mode.
 
 Other accepted forms are a cons cell of the form (NAME . QUERY)
 or a list of the form (NAME QUERY COUNT-QUERY)."
@@ -869,16 +871,16 @@ Supports the following entries in OPTIONS as a plist:
        (start (point)))
     (if is-hidden
        (widget-create 'push-button
-                      :notify `(lambda (widget &rest _ignore)
-                                 (setq notmuch-hello-hidden-sections
-                                       (delete ,title notmuch-hello-hidden-sections))
-                                 (notmuch-hello-update))
+                      :notify (lambda (&rest _ignore)
+                                (setq notmuch-hello-hidden-sections
+                                      (delete title notmuch-hello-hidden-sections))
+                                (notmuch-hello-update))
                       "show")
       (widget-create 'push-button
-                    :notify `(lambda (widget &rest _ignore)
-                               (add-to-list 'notmuch-hello-hidden-sections
-                                            ,title)
-                               (notmuch-hello-update))
+                    :notify (lambda (&rest _ignore)
+                              (add-to-list 'notmuch-hello-hidden-sections
+                                           title)
+                              (notmuch-hello-update))
                     "hide"))
     (widget-insert "\n")
     (unless is-hidden
index 5ec8eb9c8e3e06839a6e653ef554c50429b34e77..6a2769282ec666190b1a7cdeea8364782389977f 100644 (file)
 (require 'notmuch-lib)
 (require 'notmuch-hello)
 
+(declare-function notmuch-search "notmuch")
+(declare-function notmuch-tree "notmuch-tree")
+(declare-function notmuch-unthreaded "notmuch-tree")
+
 ;;;###autoload
 (defun notmuch-jump-search ()
   "Jump to a saved search by shortcut key.
@@ -50,11 +54,11 @@ fast way to jump to a saved search from anywhere in Notmuch."
            (push (list key name
                        (cond
                         ((eq (plist-get saved-search :search-type) 'tree)
-                         `(lambda () (notmuch-tree ',query)))
+                         (lambda () (notmuch-tree query)))
                         ((eq (plist-get saved-search :search-type) 'unthreaded)
-                         `(lambda () (notmuch-unthreaded ',query)))
+                         (lambda () (notmuch-unthreaded query)))
                         (t
-                         `(lambda () (notmuch-search ',query ',oldest-first)))))
+                         (lambda () (notmuch-search query oldest-first)))))
                  action-map)))))
     (setq action-map (nreverse action-map))
     (if action-map
@@ -168,9 +172,10 @@ buffer."
     (pcase-dolist (`(,key ,_name ,fn) action-map)
       (when (= (length key) 1)
        (define-key map key
-         `(lambda () (interactive)
-            (setq notmuch-jump--action ',fn)
-            (exit-minibuffer)))))
+         (lambda ()
+           (interactive)
+           (setq notmuch-jump--action fn)
+           (exit-minibuffer)))))
     ;; By doing this in two passes (and checking if we already have a
     ;; binding) we avoid problems if the user specifies a binding which
     ;; is a prefix of another binding.
@@ -191,12 +196,13 @@ buffer."
                  action-submap)
            (setq action-submap (nreverse action-submap))
            (define-key map keystr
-             `(lambda () (interactive)
-                (setq notmuch-jump--action
-                      ',(apply-partially #'notmuch-jump
-                                         action-submap
-                                         new-prompt))
-                (exit-minibuffer)))))))
+             (lambda ()
+               (interactive)
+               (setq notmuch-jump--action
+                     (apply-partially #'notmuch-jump
+                                      action-submap
+                                      new-prompt))
+               (exit-minibuffer)))))))
     map))
 
 (provide 'notmuch-jump)
index 0f96c4fe9f7074d36b90e475b2790885ea437aac..eeb0c54bfeb377f76c72b2b9653a48ca0cc4d726 100644 (file)
@@ -719,21 +719,23 @@ will return nil if the CID is unknown or cannot be retrieved."
   t)
 
 (defun notmuch-show-insert-part-message/rfc822 (msg part _content-type _nth depth _button)
-  (let* ((message (car (plist-get part :content)))
-        (body (car (plist-get message :body)))
-        (start (point)))
-    ;; Override `notmuch-message-headers' to force `From' to be
-    ;; displayed.
-    (let ((notmuch-message-headers '("From" "Subject" "To" "Cc" "Date")))
-      (notmuch-show-insert-headers (plist-get message :headers)))
-    ;; Blank line after headers to be compatible with the normal
-    ;; message display.
-    (insert "\n")
-    ;; Show the body
-    (notmuch-show-insert-bodypart msg body depth)
-    (when notmuch-show-indent-multipart
-      (indent-rigidly start (point) 1)))
-  t)
+  (let ((message (car (plist-get part :content))))
+    (and
+     message
+     (let ((body (car (plist-get message :body)))
+          (start (point)))
+       ;; Override `notmuch-message-headers' to force `From' to be
+       ;; displayed.
+       (let ((notmuch-message-headers '("From" "Subject" "To" "Cc" "Date")))
+        (notmuch-show-insert-headers (plist-get message :headers)))
+       ;; Blank line after headers to be compatible with the normal
+       ;; message display.
+       (insert "\n")
+       ;; Show the body
+       (notmuch-show-insert-bodypart msg body depth)
+       (when notmuch-show-indent-multipart
+        (indent-rigidly start (point) 1))
+       t))))
 
 (defun notmuch-show-insert-part-text/plain (msg part _content-type _nth depth button)
   ;; For backward compatibility we want to apply the text/plain hook
@@ -2078,19 +2080,19 @@ message."
     (let ((cwd default-directory)
          (buf (get-buffer-create (concat "*notmuch-pipe*"))))
       (with-current-buffer buf
-       (setq buffer-read-only nil)
-       (erase-buffer)
-       ;; Use the originating buffer's working directory instead of
-       ;; that of the pipe buffer.
-       (cd cwd)
-       (let ((exit-code (call-process-shell-command shell-command nil buf)))
-         (goto-char (point-max))
-         (set-buffer-modified-p nil)
-         (setq buffer-read-only t)
-         (unless (zerop exit-code)
-           (pop-to-buffer buf)
-           (message (format "Command '%s' exited abnormally with code %d"
-                            shell-command exit-code))))))))
+       (setq buffer-read-only t)
+       (let ((inhibit-read-only t))
+         (erase-buffer)
+         ;; Use the originating buffer's working directory instead of
+         ;; that of the pipe buffer.
+         (cd cwd)
+         (let ((exit-code (call-process-shell-command shell-command nil buf)))
+           (goto-char (point-max))
+           (set-buffer-modified-p nil)
+           (unless (zerop exit-code)
+             (pop-to-buffer buf)
+             (message (format "Command '%s' exited abnormally with code %d"
+                              shell-command exit-code)))))))))
 
 (defun notmuch-show-tag-message (&rest tag-changes)
   "Change tags for the current message.
index ebccb5a089bf59394b6e17026d68bc8ca89c4147..e3a60441a0b51a86d527b1c61fa6e9bd9a64a018 100644 (file)
@@ -553,7 +553,7 @@ and vice versa."
                                name)
                            (mapconcat #'identity tag-change " "))))
        (push (list key name-string
-                   `(lambda () (,tag-function ',tag-change)))
+                   (lambda () (funcall tag-function tag-change)))
              action-map)))
     (push (list notmuch-tag-jump-reverse-key
                (if reverse
index 2f508128cc78f2cbab0f146e4acb6c33fe2336e2..b48a132dd5aa9e1af74368cb6949bb8d83258fec 100644 (file)
 (defcustom notmuch-tree-result-format
   `(("date" . "%12s  ")
     ("authors" . "%-20s")
-    ((("tree" . "%s")("subject" . "%s")) ." %-54s ")
+    ((("tree" . "%s")
+      ("subject" . "%s"))
+     . " %-54s ")
     ("tags" . "(%s)"))
-  "Result formatting for tree view. Supported fields are: date,
-authors, subject, tree, tags.  Tree means the thread tree
-box graphics. The field may also be a list in which case
-the formatting rules are applied recursively and then the
-output of all the fields in the list is inserted
-according to format-string.
-
-Note the author string should not contain
-whitespace (put it in the neighbouring fields instead).
-For example:
-        (setq notmuch-tree-result-format \(\(\"authors\" . \"%-40s\"\)
-                                          \(\"subject\" . \"%s\"\)\)\)"
-  :type '(alist :key-type (string) :value-type (string))
+  "Result formatting for tree view.
+
+Supported fields are: date, authors, subject, tree, tags.
+
+Tree means the thread tree box graphics. The field may
+also be a list in which case the formatting rules are
+applied recursively and then the output of all the fields
+in the list is inserted according to format-string.
+
+Note that the author string should not contain whitespace
+\(put it in the neighbouring fields instead). For example:
+    (setq notmuch-tree-result-format
+          '((\"authors\" . \"%-40s\")
+            (\"subject\" . \"%s\")))"
+  :type '(alist :key-type (choice string
+                                 (alist :key-type string
+                                        :value-type string))
+               :value-type string)
   :group 'notmuch-tree)
 
 (defcustom notmuch-unthreaded-result-format
@@ -99,19 +106,24 @@ For example:
     ("authors" . "%-20s")
     ((("subject" . "%s")) ." %-54s ")
     ("tags" . "(%s)"))
-  "Result formatting for unthreaded tree view. Supported fields are: date,
-authors, subject, tree, tags.  Tree means the thread tree
-box graphics. The field may also be a list in which case
-the formatting rules are applied recursively and then the
-output of all the fields in the list is inserted
-according to format-string.
-
-Note the author string should not contain
-whitespace (put it in the neighbouring fields instead).
-For example:
-        (setq notmuch-tree-result-format \(\(\"authors\" . \"%-40s\"\)
-                                          \(\"subject\" . \"%s\"\)\)\)"
-  :type '(alist :key-type (string) :value-type (string))
+  "Result formatting for unthreaded tree view.
+
+Supported fields are: date, authors, subject, tree, tags.
+
+Tree means the thread tree box graphics. The field may
+also be a list in which case the formatting rules are
+applied recursively and then the output of all the fields
+in the list is inserted according to format-string.
+
+Note that the author string should not contain whitespace
+\(put it in the neighbouring fields instead). For example:
+    (setq notmuch-unthreaded-result-format
+          '((\"authors\" . \"%-40s\")
+            (\"subject\" . \"%s\")))"
+  :type '(alist :key-type (choice string
+                                 (alist :key-type string
+                                        :value-type string))
+               :value-type string)
   :group 'notmuch-tree)
 
 (defun notmuch-tree-result-format ()
index 739cb93bafe47db0df98bbea3299f05f2ec989c0..9802e2ecbddca4296957d0801b3c18f61595ae61 100644 (file)
     ("authors" . "%-20s ")
     ("subject" . "%s ")
     ("tags" . "(%s)"))
-  "Search result formatting. Supported fields are:
-       date, count, authors, subject, tags
+  "Search result formatting.
+
+Supported fields are: date, count, authors, subject, tags.
 For example:
-       (setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\)
-                                            \(\"subject\" . \"%s\"\)\)\)
+    (setq notmuch-search-result-format
+          '((\"authors\" . \"%-40s\")
+            (\"subject\" . \"%s\")))
+
 Line breaks are permitted in format strings (though this is
 currently experimental).  Note that a line break at the end of an
 \"authors\" field will get elided if the authors list is long;
 place it instead at the beginning of the following field.  To
 enter a line break when setting this variable with setq, use \\n.
 To enter a line break in customize, press \\[quoted-insert] C-j."
-  :type '(alist :key-type (string) :value-type (string))
+  :type '(alist :key-type string :value-type string)
   :group 'notmuch-search)
 
 ;; The name of this variable `notmuch-init-file' is consistent with the
index 647ccf3abedaaf52f95bcc44e9a3199de8d4b42d..68f646a4e56d878459d37a665ca0298621e0c1d9 100644 (file)
@@ -291,11 +291,16 @@ _notmuch_message_file_get_header (notmuch_message_file_t *message,
     if (value)
        return value;
 
-    if (strcasecmp (header, "received") == 0) {
+    if (strcasecmp (header, "received") == 0 ||
+       strcasecmp (header, "delivered-to") == 0) {
        /*
-        * The Received: header is special. We concatenate all
-        * instances of the header as we use this when analyzing the
-        * path the mail has taken from sender to recipient.
+        * The Received: header is special. We concatenate all instances of the
+        * header as we use this when analyzing the path the mail has taken
+        * from sender to recipient.
+        *
+        * Similarly, multiple instances of Delivered-To may be present. We
+        * concatenate them so the one with highest priority may be picked (eg.
+        * primary_email before other_email).
         */
        decoded = _notmuch_message_file_get_combined_header (message, header);
     } else {
index 08140799e2b965967ac2496883d091b1fb3a3032..ebb621e08670e6e799416b5ddf74aa932e40144a 100644 (file)
@@ -464,8 +464,8 @@ guess_from_in_received_by (notmuch_database_t *notmuch, const char *received)
  * (last Received: header added) and try to extract from them
  * indications to which email address this message was delivered.
  *
- * The Received: header is special in our get_header function and is
- * always concatenated.
+ * The Received: header is among special ones in our get_header function
+ * and is always concatenated.
  *
  * Return the address that was found, if any, and NULL otherwise.
  */
@@ -499,6 +499,9 @@ guess_from_in_received_headers (notmuch_message_t *message)
  * headers: Envelope-To, X-Original-To, and Delivered-To (searched in
  * that order).
  *
+ * The Delivered-To: header is among special ones in our get_header
+ * function and is always concatenated.
+ *
  * Return the address that was found, if any, and NULL otherwise.
  */
 static const char *
index b6d8f42a933f3fd36e615255e4871c229d4ba1ff..2db36fef1b26d8e7a2f57c114bd582c1e0c76322 100755 (executable)
@@ -245,6 +245,26 @@ On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > From guessing
 OK"
 
+test_begin_subtest "From guessing: multiple Delivered-To"
+add_message '[from]="Sender <sender@example.com>"' \
+           '[to]="Recipient <recipient@example.com>"' \
+           '[subject]="From guessing"' \
+           '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
+           '[body]="From guessing"' \
+           '[header]="Delivered-To: test_suite_other@notmuchmail.org
+Delivered-To: test_suite@notmuchmail.org"'
+
+output=$(notmuch reply id:${gen_msg_id} 2>&1 && echo OK)
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: From guessing
+To: Sender <sender@example.com>, Recipient <recipient@example.com>
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
+> From guessing
+OK"
+
 test_begin_subtest "Reply with RFC 2047-encoded headers"
 add_message '[subject]="=?iso-8859-1?q?=e0=df=e7?="' \
            '[from]="=?utf-8?q?=e2=98=83?= <snowman@example.com>"' \
@@ -281,7 +301,7 @@ test_expect_equal_json "$output" '
         "crypto": {},
         "date_relative": "2010-01-05",
         "excluded": false,
-        "filename": ["'${MAIL_DIR}'/msg-014"],
+        "filename": ["'${MAIL_DIR}'/msg-015"],
         "headers": {
             "Date": "Tue, 05 Jan 2010 15:43:56 +0000",
             "From": "\u2603 <snowman@example.com>",
index a96c1b5e930f59fa8a6f83242bd76158122805a9..a7497489293b6d9e7df7d835385dbef0d9d92e41 100755 (executable)
@@ -226,6 +226,7 @@ output=$(notmuch dump | LC_ALL=C sort)
 expected='#= simple-encrypted@crypto.notmuchmail.org index.decryption=failure
 #notmuch-dump batch-tag:3 config,properties,tags
 +encrypted +inbox +unread -- id:basic-encrypted@crypto.notmuchmail.org
++encrypted +inbox +unread -- id:encrypted-rfc822-attachment@crypto.notmuchmail.org
 +encrypted +inbox +unread -- id:encrypted-signed@crypto.notmuchmail.org
 +encrypted +inbox +unread -- id:simple-encrypted@crypto.notmuchmail.org'
 test_expect_equal \
index a750cc4dd6984173a25e3e7351e3d45ae733ee24..5bb5b201a53faa1d0c11fbaa0319b3a085b2b0b6 100755 (executable)
@@ -219,6 +219,12 @@ test_emacs '(notmuch-show "id:basic-encrypted@crypto.notmuchmail.org")
             (test-visible-output)'
 test_expect_equal_file $EXPECTED/notmuch-show-decrypted-message OUTPUT
 
+test_begin_subtest "show encrypted rfc822 message"
+test_subtest_known_broken
+test_emacs '(notmuch-show "id:encrypted-rfc822-attachment@crypto.notmuchmail.org")
+            (test-visible-output)'
+test_expect_code 1 'fgrep "!!!" OUTPUT'
+
 test_begin_subtest "show undecryptable message"
 test_emacs '(notmuch-show "id:simple-encrypted@crypto.notmuchmail.org")
             (test-visible-output)'
diff --git a/test/corpora/crypto/encrypted-rfc822-attachment b/test/corpora/crypto/encrypted-rfc822-attachment
new file mode 100644 (file)
index 0000000..56fe316
--- /dev/null
@@ -0,0 +1,52 @@
+Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; boundary="===============9060418334135509864=="
+MIME-Version: 1.0
+From: Notmuch test suite <test_suite@notmuchmail.org>
+To: test_suite@notmuchmail.org
+Subject: testing encrypted rfc822 attachments
+Date: Sat, 03 Jul 2021 16:00:02 -0300
+Message-ID: <encrypted-rfc822-attachment@crypto.notmuchmail.org>
+User-Agent: alot/0.9.1
+
+--===============9060418334135509864==
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Type: application/pgp-encrypted; charset="us-ascii"
+
+Version: 1
+--===============9060418334135509864==
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Type: application/octet-stream; charset="us-ascii"
+
+-----BEGIN PGP MESSAGE-----
+
+hIwDxE023q1UqxYBBACGKSDv5/rcwScSf9n33cZZPPxltQgxkDaClMGY2DARgebE
+9rpE2O/4eoaEbdu+2shahPLIbD0wuRiGVpMIIloNNucl3f15h1wXPZbTwK7sNxJq
+HycSf8sT1fkolmC9s9X0r5xHgk0G4klAqr5C3GOk7Y6wsHTYGqzDvBFEB0LvaoUC
+DANw48DehwaEUQEP/iaiYeMDUsOzFZodKZOlQWese2JPTsRwF7KrTl8C93MrZqAh
+A1pQjUH9cafj8mwDXA9ZCsYZs7r84IxShI+dUhinBSCq8F61OlLP859wq+wpKU7n
+PNVA5bfd//4hRFvDT33ZlgeeeCcRo7h4IDjJwFDYsf0Ysqvo+IKipVNXXlAcGYYI
+DVBucB0fYaVHWRKxw50mo02zKP2/GW6K3p1nxGTf73cKjc9of+VOvvMByODaJ+ne
+WIuzZMqz0vfQ0UvRVBjlsXtB7VpCqJZWkubqqwwP6+2WOCA/c5LC3z2f/BK90EQh
+/JrKfDR083UNhu4SjNwL/TF4ET33JHf1u5Gmzqx+eO00pfhVvkyz6LYImkE8ky/+
+bXyJY8iDq7dxtfqhzZbeNe4fafU/avXxTA5UkWTnYhCqyd2bvAYH3Ep3L7lSv6SQ
+Tsy0jjTsWJoSq6jRIzJuo2mX2MBKPBfLZs4tH71/4RppECletNnS4ZlxiV4LNrWE
+LrXQvE1V+mJ82muucIe7w52nf3UWjQqTA73+Ml0aK+lIhbckRIovAw1sGzRrbTEX
+xLCgz7BYDMhs5mgtfiMAzGox4xGxi56Ge519vdbddan4G92mPlLl1IPOXkO8GyLO
+D4IiPp5ilPy6uThuxxIFemxxUREbPrfLJNA8W7aRPrHz4YcgZhrAV9I4C+xE0ukB
+i8MoJeFvbCGPyTwVDn8XfFKynlZYm1f8NIVMSj5JfV8J3Om9jzDp6hx+52iUQEbW
+C9g4kfPZY8h0RMggdOlZsaR8j26xuW+fEtz7ucJIqfJ/ElTH+4bm8MK2qPZniRWv
+ej2md4bP4Bo5DXydzxz7O7TBL6/Jsp7pJhHUUb36OnTWvInyg71LPT1QIxdRvXr9
+vNhrEBDX3MNf7RyXczvBcc+cLRo+zV+T4b8wd2kwXskWgKrGUJEe2TItdsafaQ9B
+BkuVGu6cIDa6STyCJiOB68KIXiDuADSWJiiR+gZr4eU6vzfhR27LMQt/g+oPW+U4
+1AvzUl9uXjTMC2vFuTQ4M2g0WmksCNpPpzOu/QlBmRqpP2Fg9UuLv6ITWeCxp439
+g5NT5KXE2IiruL/DS0KEpWVNe4ayGzRvMawFuU582xbIzXjvilUZrW+p6req+oeF
+QWTWHGDojTvULQPV2c91lWnLaNXVethfF4hrM5MIL+EwVs3sUXFMr1kX7VNrK0QH
+Uos7nc4G9xngpdvwF4ImldD83O8qxOVzIfk5Dhz+etTH4HbnnDvmQ/FIYvjzGviR
+ZeVwdCjv/9TC4yY3nJFKMwGp70jVa1vbmWL68HVNRyAVwnQnu2UlI8UR43iVZyUH
+ZY0Nr0rbse/pvZyX4//EVOFLUR7K4GG0N4Kz41q5ZB8rI4Fl6QJhgIFJds13iM77
+n+wqLQE7kllgI32E4U9B
+=YlXg
+-----END PGP MESSAGE-----
+
+--===============9060418334135509864==--