summaryrefslogtreecommitdiffstats
path: root/src/smtpd/smtpd.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:22:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:22:00 +0000
commit674d01f734ec6d2d348d8d08d0002de8ab473cf4 (patch)
treeaeaa6434cfd8492735bca8402ef3a15f81ffafda /src/smtpd/smtpd.c
parentAdding debian version 3.7.10-0+deb12u1. (diff)
downloadpostfix-674d01f734ec6d2d348d8d08d0002de8ab473cf4.tar.xz
postfix-674d01f734ec6d2d348d8d08d0002de8ab473cf4.zip
Merging upstream version 3.7.11.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/smtpd/smtpd.c')
-rw-r--r--src/smtpd/smtpd.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/smtpd/smtpd.c b/src/smtpd/smtpd.c
index 4f4aedd..c2aa428 100644
--- a/src/smtpd/smtpd.c
+++ b/src/smtpd/smtpd.c
@@ -4114,14 +4114,31 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
/*
* Read lines from the fragment. The last line may continue in the
* next fragment, or in the next chunk.
+ *
+ * If smtp_get_noexcept() stopped after var_line_limit bytes and did not
+ * emit a queue file record, then that means smtp_get_noexcept()
+ * stopped after CR and hit EOF as it tried to find out if the next
+ * byte is LF. In that case, read the first byte from the next
+ * fragment or chunk, and if that first byte is LF, then
+ * smtp_get_noexcept() strips off the trailing CRLF and returns '\n'
+ * as it always does after reading a complete line.
*/
do {
+ int can_read = var_line_limit - LEN(state->bdat_get_buffer);
+
if (smtp_get_noexcept(state->bdat_get_buffer,
state->bdat_get_stream,
- var_line_limit,
+ can_read > 0 ? can_read : 1, /* Peek one */
SMTP_GET_FLAG_APPEND) == '\n') {
/* Stopped at end-of-line. */
curr_rec_type = REC_TYPE_NORM;
+ } else if (LEN(state->bdat_get_buffer) > var_line_limit) {
+ /* Undo peeking, and output the buffer as REC_TYPE_CONT. */
+ vstream_ungetc(state->bdat_get_stream,
+ vstring_end(state->bdat_get_buffer)[-1]);
+ vstring_truncate(state->bdat_get_buffer,
+ LEN(state->bdat_get_buffer) - 1);
+ curr_rec_type = REC_TYPE_CONT;
} else if (!vstream_feof(state->bdat_get_stream)) {
/* Stopped at var_line_limit. */
curr_rec_type = REC_TYPE_CONT;