fix: trim the body before signing it

The compose buffer was passed through verbatim, so whatever the author last
pressed ended up in the payload — usually a trailing newline. That is not
content, but it becomes content the moment it is signed, and nothing
downstream can remove it without invalidating the signature.

smolboid refuses any post whose text carries a line break, because a published
record is one line of a feed, so every post sent from carrier was rejected
with "contains TAB, LF, CR or U+2028". Trimming has to happen here, before the
seal, rather than at the receiver: stripping is not invertible, so a receiver
that trimmed could no longer rebuild the bytes the author signed.
This commit is contained in:
randogoth 2026-10-14 22:08:55 +03:00
parent 2dbf098c82
commit d9798a18f1

View file

@ -716,7 +716,14 @@ pub fn send(
.collect(); .collect();
let draft = client::SendDraft { let draft = client::SendDraft {
address: &addr, address: &addr,
text: body.to_string(), // Trimmed at the send site, before the payload is signed, so the
// signature covers exactly the text the author meant. A compose buffer
// ends with whatever the author last pressed, and a trailing newline
// is not content — but it is content once it has been signed, and
// nothing downstream can remove it without invalidating the
// signature. smolboid, for one, refuses a post whose text carries a
// line break, because a published record is one line of a feed.
text: body.trim().to_string(),
subject, subject,
reply_to, reply_to,
headers: &owned, headers: &owned,