[PATCH] gpg-interface: trim only CR characters that precede LF
From: Okhuomon Ajayi <hidden>
Date: 2025-10-16 18:44:42
Subsystem:
the rest · Maintainer:
Linus Torvalds
The current implementation of remove_cr_after() drops every carriage return (CR) it finds, even when the CR is not part of a CRLF sequence. This can damage data that legitimately contains standalone CR bytes, such as binary payloads or text formatted for older systems. Update remove_cr_after() to remove a CR only when it is immediately followed by an LF. This keeps Windows-style CRLF normalization intact while preserving lone CR characters that are part of the data itself. Signed-off-by: Okhuomon Ajayi <redacted> --- gpg-interface.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/gpg-interface.c b/gpg-interface.c
index 2f4f0e32cb..c961607444 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c@@ -965,19 +965,22 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig } /* - * Strip CR from the line endings, in case we are on Windows. - * NEEDSWORK: make it trim only CRs before LFs and rename + * Trim CR characters only when they appear before LF (\r\n) line endings. + * This avoids removing legitimate lone CRs from teh content. */ -static void remove_cr_after(struct strbuf *buffer, size_t offset) +static void trim_cr_before_lf(struct strbuf *buffer, size_t offset) { size_t i, j; for (i = j = offset; i < buffer->len; i++) { - if (buffer->buf[i] != '\r') { + /* skip CR only if it comes right before LF */ + if (buffer->buf[i] == '\r' && i + 1 < buffer->len && buffer->buf[i+1] == '\n') + continue; + if (i != j) buffer->buf[j] = buffer->buf[i]; j++; - } + } strbuf_setlen(buffer, j); }
@@ -1023,8 +1026,10 @@ static int sign_buffer_gpg(struct strbuf *buffer, struct strbuf *signature, } strbuf_release(&gpg_status); - /* Strip CR from the line endings, in case we are on Windows. */ - remove_cr_after(signature, bottom); + /* Trim carriage returns (CR) only when they appear before line feeds (LF),. + * mainly for handling Windows-style line endings + */ + trim_cr_before_lf(signature, bottom); return 0; }
@@ -1110,8 +1115,10 @@ static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature, ssh_signature_filename.buf); goto out; } - /* Strip CR from the line endings, in case we are on Windows. */ - remove_cr_after(signature, bottom); + /* Trim carriage returns (CR) only when they appear before line feeds (LF), + * mainly for handling Windows-style line endings. + */ + trim_cr_before_lf(signature, bottom); out: if (key_file)
--
2.43.0