652 Commits

Author SHA1 Message Date
Robin Jarry
767287718e workers: rework cancellable
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-09 09:18:18 +02:00
Robin Jarry
0211c9bf23 reload: fix crash when reloading via IPC
When reloading the configuration with :reload, global variables in the
config package are reset to their startup values and then, the config is
parsed from disk. While the parsing is done, these variables are
temporarily in an inconsistent and possibly invalid state.

When commands are executed interactively from aerc, they are handled by
the main goroutine which also deals with UI rendering. No UI render will
be done while :reload is in progress.

However, the IPC socket handler runs in an independent goroutine. This
has the unfortunate side effect to let the UI goroutine to run while
config parsing is in progress and causes crashes:

[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6bb142]

goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/lib/log.PanicHandler()
	lib/log/panic-logger.go:51 +0x6cf
panic({0xc1d960?, 0x134a6e0?})
	/usr/lib/go/src/runtime/panic.go:783 +0x132
git.sr.ht/~rjarry/aerc/config.(*StyleConf).getStyle(0xc00038b908?, 0x4206b7?)
	config/style.go:386 +0x42
git.sr.ht/~rjarry/aerc/config.StyleSet.Get({0x0, 0x0, 0x0, {0x0, 0x0, 0x0}}, 0x421a65?, 0x0)
	config/style.go:408 +0x8b
git.sr.ht/~rjarry/aerc/config.(*UIConfig).GetStyle(...)
	config/ui.go:379
git.sr.ht/~rjarry/aerc/lib/ui.(*TabStrip).Draw(0xc000314700, 0xc000192230)
	lib/ui/tab.go:378 +0x15b
git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc000186fc0, 0xc0002c25f0)
	lib/ui/grid.go:126 +0x28e
git.sr.ht/~rjarry/aerc/app.(*Aerc).Draw(0x14b9f00, 0xc0002c25f0)
	app/aerc.go:192 +0x1fe
git.sr.ht/~rjarry/aerc/lib/ui.Render()
	lib/ui/ui.go:155 +0x16b
main.main()
	main.go:310 +0x997

Make the reload operation safe by changing how config objects are
exposed and updated. Change all objects to be atomic pointers. Expose
public functions to access their value atomically. Only update their
value after a complete and successful config parse. This way the UI
thread will always have access to a valid configuration.

NB: The account configuration is not included in this change since it
cannot be reloaded.

Fixes: https://todo.sr.ht/~rjarry/aerc/319
Reported-by: Anachron <gith@cron.world>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-08 12:19:51 +02:00
Robin Jarry
fcf59fecb0 app: improve hook debug logs
Add extra debug logs.

Co-authored-by: Simon Martin <simon@nasilyan.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-08-28 10:19:57 +02:00
Robin Jarry
13e9ee3b40 lib: vendor-in the jwz library
The maintainer of this library has gone AWOL. We are depending on
a patch that has never been merged. Let's vendor the library to avoid
future issues.

This patch has been made with the following steps:

git clone https://github.com/konimarti/jwz lib/jwz
git -C lib/jwz checkout fix-missing-messages
mv lib/jwz/test/testdata/ham lib/jwz/testdata
sed -i 's#test/testdata#testdata#' lib/jwz/jwz_test.go
rm -rf lib/jwz/.* lib/jwz/docs lib/jwz/examples lib/jwz/test
sed -i 's#github.com/gatherstars-com/jwz#git.sr.ht/~rjarry/aerc/lib/jwz#' \
	lib/threadbuilder.go
go mod tidy
git add --intent-to-add lib/jwz
make fmt

Along with some manual adjustments to fix the linter warnings. Also, to
make the patch smaller, I only kept 93 test emails from the test data
fixture.

Changelog-changed: The JWZ library used for threading is now vendored.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
2025-08-28 09:28:16 +02:00
Moritz Poldrack
fc5b6896ff chore: switch to using stdlib helper functions
Go has evolved significantly over the years and has introduced some
handy helper functions that make the code easier to read.

Use helper functions like slices.Contains, map.Copy, and
strings.CutPrefix, when appropriate.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-04 12:47:05 +02:00
Simon Martin
7df7d31e40 imap: consistently fetch gmail labels and improve logging
The various handleFetchXYZ functions do not consistently request
X-GM-LABELS when interacting with GMail, and the in-memory "label state"
can easily get out-of-sync with the server.

This patch fixes this, and also ensures that we only log that we're
attaching a label to a message when we actually do (and if so, puts the
account name in the log line).

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-04 12:27:30 +02:00
GregTheMadMonk
d31995f1e2 ui: implement C-left/C-right cursor controls for textinput
When typing inside textinput, Ctrl+Left places the cursor at the start
of the current word, and Ctrl+Right goes to the start of the next one.

Ctrl+Left uses the same code `deleteWord()` function used (which is now
split into a separate function), and Ctrl+Right uses similar lookup in
the other direction.

Implements: https://todo.sr.ht/~rjarry/aerc/231
Signed-off-by: GregTheMadMonk <yagreg7@gmail.com>
Tested-by: skejg <grolleman@zoho.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-30 11:05:30 +02:00
Jan Černohorský
0fc3481862 imap: add rudimentary readonly support for labels in gmail
Use the GMail IMAP extension to fetch labels for messages when
use-gmail-ext is enabled. Labels are automatically fetched when fetching
headers for a message and when fetching flags for a message. They should
be correctly cached.

Link: https://developers.google.com/workspace/gmail/imap/imap-extensions
Changelog-added: Readonly support for GMail labels.
Signed-off-by: Jan Černohorský <jan@grsc.cz>
Tested-by: Vojtěch Káně <vojta001@vkane.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-20 09:30:44 +02:00
Simon Martin
63e6a018ae grid: fix possible crash on startup due to unsynchronized access
I've encountered a few crashes when starting aerc while also playing
with the mouse; see for instance
  https://paste.sr.ht/~simartin/e71203c56daebec1dd6e96916f88a229d8b41b2b

This is due to a race between Grid.MouseEvent and grid.reflow: the
latter modifies the grid without taking the associated mutex, while it
should.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-19 12:23:32 +02:00
Simon Martin
f2641cd989 ui: properly trim spaces from addresses
My kids' school has put a leading space in their name, which breaks the
visual alignment in the message list and viewer.

This patch calls TrimSpace when displaying addresses and fixes both
views.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-21 18:30:55 +02:00
Simon Martin
80f3fb4325 ui: update tab title when replacing by with another
When navigating between messages in the Message Viewer, the whole tab is
updated except its title: it remains set to the subject of the message
that was initially opened in that tab.

Tabs.Replace needs to update both the content *and* the title; this is
what this patch does.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-21 18:28:56 +02:00
Robin Jarry
f5b8c32f5e rfc822: try harder to decode invalid address headers
Some address names may be quoted AND partially encoded. That is only
a word in the middle of the name could be encoded (and be surrounded by
=? and ?= delimiters).

Just check if the address name contains these two delimiters (regardless
of their position) to determine if we should re-decode the name.

Fixes: 44b14ebdff ("rfc822: be liberal with invalid address headers")
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-05-07 17:13:23 +02:00
Karel Balej
5919e9dfda term: allow setting custom title for the terminal tab
Add a template for the terminal tab title and define two
terminal-specific properties: Title which expands to whatever the
underlying application requests via OSC and defaults to the command name
and Bell which is a boolean indicating whether the application has
emitted bell, the flag is cleared when the corresponding tab gains focus
and is not set at all if it currently has it.

This can among other things be used to highlight the terminal tab when
the underlying process prints the bell, such as by setting the template
as such:

	tab-title-terminal={{if .Bell}}[BELL] {{end}}{{.Title}}

Implements: https://todo.sr.ht/~rjarry/aerc/138
Changelog-added: A tab-title-terminal setting for customizing the
 title of tabs in which the terminal widget is run.
Requested-by: Drew DeVault <drew@ddevault.org>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-05 13:49:04 +02:00
Simon Martin
7cb8e0e7ce imap: properly handle out-of-band Unseen flag updates
I noticed that the fix I made via b576ab28 (and the general idea to get
rid of materialized RUE counters) does not work, because we're extremely
unlikely to have all the messages' flags in memory. So the patch worked
"by chance" when updating messages that are in the active message list
(e.g. their headers are already fetched) but not for "out of view"
messages.

This alternative patch "just" captures unsolicited MessageUpdate
messages from the server, and updates the Unseen counter according to
the status reported by the server for that message. This allows to
synchronize our view with the server's.

Fixes: b576ab28 ("properly update UI upon message (un)read in [...]")
Fixes: https://todo.sr.ht/~rjarry/aerc/307
Signed-off-by: Simon Martin <simon@nasilyan.com>
Tested-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-07 10:51:38 +02:00
Karel Balej
f0ec95d7dd account: allow indicating new messages in the tab title
Add a flag to indicate whether the account has received new messages
since it last had focus and allow its use in the templates.

Changelog-added: A `.HasNew` flag indicating whether the account has
 received new messages to be used in the templates.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-07 10:51:14 +02:00
Robin Jarry
0ca8087ec9 treewide: replace interface{} with any
Since go 1.18, interface{} can be replaced with any.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Karel Balej <balejk@matfyz.cz>
2025-04-07 10:51:05 +02:00
Robin Jarry
d35e77d256 msglist: honor threading-by-subject when sort-thread-siblings is false
When sort-thread-siblings = false and threading-by-subject = true, do
not order siblings by ascending UID. Instead, use the message Subject
headers to order siblings.

Changelog-changed: Thread siblings will now be ordered by subject if
 `[ui].sort-thread-siblings = false` and `[ui].threading-by-subject
 = true`.
Reported-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Brendan Jackman <jackmanb@google.com>
2025-04-07 10:48:17 +02:00
inwit
a6220d025a tag: allow to toggle tags
So far, the :tag command in the notmuch and jmap workers allows adding a
tag (by prefixing it with '+') and removing it (by prefixing it with
'-'). Add a new functionality to this command, allowing it to toggle a
tag by prefixing it with '!'.

Fixes: https://todo.sr.ht/~rjarry/aerc/292
Changelog-added: It is now possible to toggle notmuch and JMAP tags.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 22:10:58 +02:00
Simon Martin
7153e257b4 watchers: fix checking error on darwin
After "gmake config", git-send-email currently fails on Darwin with the
following:
>  lib/watchers/fsevents.go:67:11: Error return value of `w.w.Start` is
>  not checked (errcheck)

This patch fixes this by checking the return code and bubbling it up in
case of error.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 21:33:20 +02:00
Bryce Vandegrift
b457f80470 gpg: fix decrypt emails with invalid signature
This patch fixes an error that occurs when decrypting an email with an
invalid gpg signature. The error "gpg-exit 33554433" will be thrown and
the email will not be opened.

Signed-off-by: Bryce Vandegrift <bryce@brycevandegrift.xyz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 21:31:56 +02:00
Moritz Poldrack
731b0a2a16 ui: map number block to regular counterparts
Due to vaxis low-level design, the enter key of the number block has
a different key code that a regular carriage return. Since most people
do not care which of the two they are hitting, remap the former and
up/down/left/right to act like the latter.

Changelog-added: Support for number block enter to act as <Cr>
 in mappings.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-20 15:15:22 +01:00
Moritz Poldrack
c460e0e6f1 template: fix mailto on startup failing to open
During startup, d.account and d.folder are not set and thus not
lead to a segmentation fault when running a signature command.

Only set these values if they are available.

Fixes: da5ca1a5 ("template: pass account and folder names to signature command")
Changelog-fixed: Fix an error when starting aerc through a `mailto:`
 link when the `new_message` template runs a signature command.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-19 00:35:48 +01:00
Moritz Poldrack
1d6eb2dc58 smtp: add option to request DSN for successful deliveries
In some cases it can be desirable to receive a success notification for
a message from the server. This currently only works on SMTP.

Changelog-added: Add option to request full DSN for SMTP sent messages.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-09 00:40:38 +01:00
Moritz Poldrack
9ad1e1e1ac lib/marker: fix crash caused by concurrent map access
lib/marker makes extensive uses of maps, but does not guard against
concurrent accesses. Add two mutexes to ensure read and write access do
not happen simultaneously.

Changelog-fixed: Fixed an unguarded concurrent map access leading
 to crashes.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Tested-by: Terrance <srht@terrance.allofti.me>
2025-02-24 20:48:04 +01:00
Moritz Poldrack
932d9a44d5 autoconfig: fix spelling
This commit fixes a critical bug found by the CI where import was
allegedly misspelled

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-19 12:01:18 +01:00
Moritz Poldrack
e7e0421015 autoconf: add MX record checking
Add a direct mailserver poker that tries to connect to the mailserver
with the highest priority retrieved from via DNS.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Moritz Poldrack
8ea549917a autoconf: add educated guesses for config
Add a fallback to the autoconfig module that performs some educated
guesses regarding hostname, port, and encryption.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Moritz Poldrack
d771c49e74 autoconf: add Mozilla lookup
Add config retrieval from Mozilla's Thunderbird Provider index.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Moritz Poldrack
b3c5b6bb70 autoconf: add config retrieval from SRV records
Add the capability to parse DNS entries to infer mailserver settings.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Moritz Poldrack
e1a5faa521 autoconf: add config retrieval using HTTP-based autoconfig
Add a function to retrieve configurations from the autoconfig-subdomain
or a .well-known file.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Karel Balej
dbe350a585 msgview: add copy-link command
Add a command to copy links to the system clipboard. This can be useful
for instance when the URL should be handled in some other way than
opened (e. g. resent via some other communication channel or saved to a
file). It also improves security for situations where it's not desirable
for the URL to be visible on the process command line, such as when it
contains sensitive information such as an access token.

Adapted from open-link.

Changelog-added: If supported by the terminal, links from a message
 can now be copied to the system clipboard with the :copy-link command
 of the message viewer.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-06 13:59:24 +01:00
Karel Balej
02324e9d9c lib: disallow < in URLs when parsing HTML
Make sure that links placed verbatim inside HTML elements' bodies are
not parsed along with adjacent HTML tags as illustrated in the new test
case.

Also change the existing code to use the idiomatic Go way to get a
set-like functionality.

Changelog-fixed: Parsed links in HTML message parts now do not include
 trailing HTML tags.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Tested-by: Jakub Růžička <jakub.ruzicka@matfyz.cz>
2025-02-04 15:18:01 +01:00
Tim Culverhouse
bfe62ef006 codespell: fix lib/notmuch/directory.go: firs => first
Fix a spelling mistake in lib/notmuch/directory.go.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-01 10:06:41 +01:00
Karel Balej
1d5551bcd9 msgstore: fix new-message bell for threaded directories
Threaded directories were never marked as loaded and thus the terminal
bell was never rung when a new message arrived in them. Add the missing
directive to mark them as loaded when appropriate.

Fixes: 8d4704775b ("msgstore: do not trigger notification on initial load")
Changelog-fixed: The new-message bell is now rung again for threaded
 directories as well.
Cc: Remko Tronçon <remko@el-tramo.be>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-01-23 22:11:39 +01:00
Robin Jarry
4e545d45fa treewide: fix English spelling
Use codespell to fix typos in code, comments and man pages.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: inwit <inwit@sindominio.net>
2025-01-21 13:39:01 +01:00
Karel Balej
fae4a0a1e8 ui: fix the position of the address-book completion popovers
When composing a message, the location of the popovers was not offset by
the location of the field that was being completed (To, Cc,...)
resulting in them appearing always at the same position near the top
left corner of the window. Restore the offset to have them appear right
underneath the active field again.

Fixes: 787cfbd9a9 ("ui: remove screen and viewports")
Changelog-fixed: The address-book completion popovers now again appear
 under the field being completed.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-01-18 11:17:20 +01:00
Robin Jarry
3d509bbc0d tests: fix error with go 1.24
Fix the following error when running tests with go 1.24:

lib/iterator/iterator_test.go:58:12: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:62:13: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:66:12: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:69:12: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:83:12: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:87:13: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:91:12: non-constant format string in call to (*testing.common).Errorf
lib/iterator/iterator_test.go:94:12: non-constant format string in call to (*testing.common).Errorf

Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-01-16 21:00:38 +01:00
Robin Jarry
c48a9144b1 templates: add filters folders to exec path
Add the filters folders to the exec search path when calling the "exec"
template function. This is to allow executing filters by name.

Changelog-changed: The templates `exec` commands is now executed with
 the `filters` exec `$PATH` similar to filter commands.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
2025-01-14 21:48:24 +01:00
Robin Jarry
3ff25aeaa1 pgp: ensure mime-version header is in the right place
Update go-pgpmail which has a similar fix to the one we had in place.
Update our fix to use the same implementation: do not parse the whole
signed part. Only parse the part header, remove the mime-version header
from it if any and re-write it, followed the part body verbatim without
any decoding/re-encoding.

Fixes: 7346d20343 ("gpg: fix signed message encoding")
Fixes: 7b8fbe2a3d ("gpg: fix mime-version header position")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Simon Ser <contact@emersion.fr>
2025-01-14 15:01:10 +01:00
Robin Jarry
6b97085ae5 tab: fix broken history on removal
Given the following tab layout: name(index). The current index is 2 and
history is considered empty:

    MessageList       TermFoo      [TermBar]       Viewer
    0                 1             2              3

If we focus TermFoo, index 2 is added to history and current index
becomes 1:

    MessageList      [TermFoo]      TermBar        Viewer
    0                 1             2              3

Now, if we close TermFoo, the last item in the history (2) is popped and
selected:

    MessageList      TermBar      [Viewer]
    0                1             2

This leads to selecting the message viewer whereas TermBar should have
been selected.

A different issue happens when the tab history index is out of bounds.
For example:

    MessageList       TermFoo      [TermBar]
    0                 1             2

Move to TermFoo, 2 is pushed to history:

    MessageList      [TermFoo]      TermBar
    0                 1             2

Close TermFoo, last index in history (2) is invalid, current index
remains selected but not completely:

    MessageList      [TermBar]
    0                 1

The widget/terminal in TermBar will not be focused or made visible to
the ui (via (Visible).Show(true)) until one key is pressed. Effectively
delaying interaction with the program running in it.

Replace a list of index with a list of pointers to *Tab objects for the
history. This makes it impervious to removal, reordering and removes
the need to recompute the history indexes.

Limit the history to 256 items to avoid memory hog after a long time.

When removing the current tab, ensure "something" is selected. If the
history is empty, select the next best thing.

Suggested-by: Koni Marti <koni.marti@gmail.com>
Reported-by: Brandon Sprague <brandon@sprague.mx>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
2025-01-10 17:07:33 +01:00
Robin Jarry
cb1c4c9c62 send: ensure crlf line endings
RFC 5322 states that messages should only use CRLF line endings. Here
are two important excerpts:

> 2.1. General Description
>
>  Messages are divided into lines of characters.  A line is a series of
>  characters that is delimited with the two characters carriage-return
>  and line-feed; that is, the carriage return (CR) character (ASCII
>  value 13) followed immediately by the line feed (LF) character (ASCII
>  value 10).  (The carriage return/line feed pair is usually written in
>  this document as "CRLF".)

> 2.3.  Body
>
>  The body of a message is simply lines of US-ASCII characters.  The
>  only two limitations on the body are as follows:
>
>  o  CR and LF MUST only occur together as CRLF; they MUST NOT appear
>     independently in the body.
>  o  Lines of characters in the body MUST be limited to 998 characters,
>     and SHOULD be limited to 78 characters, excluding the CRLF.

Most MTA are tolerant to invalid messages but some others are more
pedantic. Ensure we only send valid line endings.

Link: https://www.rfc-editor.org/rfc/rfc5322.html#section-2.1
Link: https://www.rfc-editor.org/rfc/rfc5322.html#section-2.3
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Matěj Cepl <mcepl@cepl.eu>
2025-01-07 19:20:44 +01:00
Robin Jarry
7356be2be5 gpg: force crlf on base64 blobs
When sending signed messages with outgoing = jmap://, the following
error is returned by the server (provider=Fastmail):

	Message contains bare newlines

RFC 5322 section 2.3 states that:

> CR and LF MUST only occur together as CRLF; they MUST NOT appear
> independently in the body.

Most MTA handle invalid messages without warnings, but some others
reject them.

Ensure GPG generated parts use CRLF to comply with the RFC.

Fixes: 57699b1fa6 ("feat: add gpg integration")
Link: https://www.rfc-editor.org/rfc/rfc5322.html#section-2.3
Changelog-fixed: GPG signatures and encrypted parts now use CRLF line
 endings as required by RFC 5322.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Matěj Cepl <mcepl@cepl.eu>
2025-01-07 19:20:33 +01:00
Robin Jarry
553fabbc2e jmap: handle copy-to and :send -t
The jmap:// outgoing backend always copies (actually, just tags) the
sent emails with the mailbox that has the "sent" role. Regardless of the
copy-to or :send -t <folder> argument. Only the copy-to-replied setting
is effective.

Change the CopyTo parameter of the StartSendingMessage backend operation
to hold a list of folder names.

In the JMAP worker, label the sent message with the list of folders,
eliminating duplicates (e.g. do not label with "sent" role twice).

Reported-by: Matěj Cepl <mcepl@cepl.eu>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Matěj Cepl <mcepl@cepl.eu>
2024-12-21 17:02:31 +01:00
Remko Tronçon
8d4704775b msgstore: do not trigger notification on initial load
There currently is no difference between updating the store of
a directory that was already loaded, and a directory that has not yet
been initialized. When a directory is opened, and the initial update
request is processed, all messages are therefore treated as new, and the
directory change notification (i.e. bell) is triggered.

To prevent triggering this update, track whether the directory was
already initialized, and if not, don't send out any change
notifications.

Signed-off-by: Remko Tronçon <remko@el-tramo.be>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-12-19 16:42:52 +01:00
Koni Marti
c2048ef304 rfc822: parse multipart messages on a best efforts basis
Parse multipart messages on a best-efforts basis. Allow the user to see
as much of the message as possible, but log the errors.

If a charset or encoding error is encountered for a message part of a
multipart message, the error is logged and ignored. In those cases, we
still get a valid message body but the content is just not decoded or
converted. No error will be propagated.

If a multipart message cannot be parsed, ParseEntityStructure will
return a multipart error. This error indicates that the message is
malformed and there is nothing more we can do. The caller is then
advised to use a single text/plain body structure using
CreateTextPlainPart() to provide the entire message content to the user.

Fixes: https://todo.sr.ht/~rjarry/aerc/288
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-11-21 22:27:19 +01:00
Marcin Serwin
5ccd2d0d51 gpg: redirect status-fd from stdout to stderr
By preparing a maliciously crafted message an attacker could send an
encrypted message without signature that would appear as signed within
the aerc client. It is caused by the fact that the gpg status messages,
which are used for determining the validity signature, are interspered
with message contents. An example of such malicious message was added to
the `reader_test.go`.

This change redirects the satus-fd to stderr, while the usual stderr
logs are discarded to /dev/null. In addition to fixing the vulnerability
described above, this has the added benefit of stdout containing only
useful output which does not need to be filtered. This simplifies the
logic and avoids needless copies.

Previous stderr parsing logic which detected when no valid OpenPGP data
was present is replaced with detecting `NODATA 1` in status-fd messages.
The stderr logs are different depending on user locale, thus, they
should not be parsed. On the other hand, the status-fd are relatively
stable. The previous method of detecting invalid OpenPGP data would fail
on systems with non-English locale.

Signed-off-by: Marcin Serwin <marcin@serwin.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-10-27 10:15:08 +01:00
Koni Marti
fc31a5c200 attach: fix content-transfer-encoding for rfc822 attachments
Fix the content-transfer-encoding for attachments with message/rfc822
mime types.

It's not allowed by RFC2046 to set any other content-transfer-encoding
than 7bit, 8bit, or binary for message/rfc822 mime types (see RFC2046,
section 5.2.1).

We can enforce this by setting a content-transfer-encoding header for
attachments to 'binary' explicitly. 'binary' is more lenient than '8bit'
with respect to line length and CRLF semantics and thus seems more
suitable.

Link: https://datatracker.ietf.org/doc/html/rfc2046#section-5.2.1
Link: https://lists.sr.ht/~rjarry/aerc-devel/%3CD48A6YOQOXRG.3KKB6UTGMT8LY@maslowski.xyz%3E
Reported-by: Piotr Masłowski <piotr@maslowski.xyz>
Reported-by: inwit <inwit@sindominio.net>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-10-24 22:13:51 +02:00
Tim Culverhouse
5b57d24afd textinput: make completions run async with cancellation
Make the Completer interface accept a context.Context. Provide a
cancellation feature on text input tab completion to cancel an inflight
completion command. This is particularly useful for address book
completion if the user has specified a network-accessing command, eg
carddav-query. The command is started according to the completion delay,
but is cancellable if another request comes in. We also check for
cancellation after the request is complete to ensure we only show valid
completion results.

Changelog-changed: Tab completions for text fields are run
 asynchronously. In-flight requests are cancelled when new input
 arrives.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-10-24 22:13:51 +02:00
Tristan Partin
1be64ef751 history: read the history file from XDG_STATE_HOME
History is more like application state than a cache you would just want
to blow away. Let's reflect that in the path for the history file.

Changelog-changed: The location of the command history file has
 changed to ${XDG_STATE_HOME:-$HOME/.local/state}/aerc/history.
Signed-off-by: Tristan Partin <tristan@partin.io>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-10-24 22:13:51 +02:00
Robin Jarry
3c9ad93801 completion: display descriptions next to choices
Use go-opt v2 new completion API which returns items descriptions along
with their text values.

Display the descriptions after the items separated by two spaces. Wrap
the descriptions in parentheses to better indicate that they are not
part of the completion choices. Limit the description length to 80
characters to avoid display issues.

Add a new style object completion_description in stylesets. By default,
the object will be rendered with a dimmed terminal attribute. Update all
stylesets and documentation accordingly.

Implements: https://todo.sr.ht/~rjarry/aerc/271
Link: https://git.sr.ht/~rjarry/go-opt/commit/ebeb82538395a
Changelog-added: Command completion now displays descriptions next
 to completion items.
Changelog-added: New `completion_description` style object in style
 sets used for rendering completion item descriptions.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bojan Gabric <bojan@bojangabric.com>
Tested-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2024-10-23 10:22:51 +02:00