From b043cfc6a5b6d42303c334f027d0d68d7461bc12 Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Thu, 25 Sep 2014 15:46:24 +0200 Subject: [PATCH] Really fix QP size calculation (Peter Hofmann).. Tweaks [c299c45] (Fix QP encoding canary violation, 2014-09-22), of course adding soft NLs adds data which must be taken into account itself. --- mime_cte.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/mime_cte.c b/mime_cte.c index 561de0d9..7e72b972 100644 --- a/mime_cte.c +++ b/mime_cte.c @@ -330,21 +330,29 @@ mime_cte_mustquote(char const *ln, size_t lnlen, bool_t ishead) FL size_t qp_encode_calc_size(size_t len) { - size_t i; + size_t bytes, lines; NYD_ENTER; + /* The worst case sequence is 'CRLF' -> '=0D=0A=\n\0'. * However, we must be aware that (a) the output may span multiple lines * and (b) the input does not end with a newline itself (nonetheless): - * LC_ALL=C PERL5OPT= perl -CS -e 'print "\x{101D0}" x 100' | + * LC_ALL=C awk 'BEGIN{ + * for(i = 0; i < 100000; ++i) printf "\xC3\xBC" + * }' | * MAILRC=/dev/null LC_ALL=en_US.UTF-8 s-nail -nvvd \ * -Ssendcharsets=utf8 -s testsub ./LETTER */ - /* TODO This example shows two things: 1. as stated in TODO this must - * TODO be sequentialised! and 2. this shouldn't end up QP-encoded! */ - len *= 3; - i = (len / QP_LINESIZE) + 1; - i <<= 1; /* Double: soft and embedded NL.. */ - ++i; /* \0 */ - len += ++i; /* ..and \0 */ + bytes = len * 3; + lines = bytes / QP_LINESIZE; + len += lines; + + bytes = len * 3; + /* Trailing hard NL may be missing, so there may be two lines. + * Thus add soft + hard NL per line and a trailing NUL */ + lines = (bytes / QP_LINESIZE) + 1; + lines <<= 1; + bytes += lines; + len = ++bytes; + NYD_LEAVE; return len; } -- 2.11.4.GIT