From c9076497c235510f9358f9e3eadfe91fbfa9d5e3 Mon Sep 17 00:00:00 2001 From: Philipp Takacs Date: Fri, 25 Aug 2023 20:28:55 +0200 Subject: [PATCH] mhbuild implement header folding --- h/mh.h | 2 ++ h/prototypes.h | 1 + sbr/Makefile.in | 3 +- sbr/fold.c | 61 +++++++++++++++++++++++++++++++++++++++ test/tests/mhbuild/test-folding | 35 ++++++++++++++++++++++ uip/mhoutsbr.c | 5 +++- 6 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 sbr/fold.c create mode 100644 test/tests/mhbuild/test-folding diff --git a/h/mh.h b/h/mh.h index 3326185..280249e 100644 --- a/h/mh.h +++ b/h/mh.h @@ -221,6 +221,8 @@ struct msgs { ** terminating NULL. */ +#define MAXTEXTPERLN 78 + /* m_getfld2() returned data */ struct field { char name[NAMESZ]; diff --git a/h/prototypes.h b/h/prototypes.h index fad1af4..182cf1c 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -114,6 +114,7 @@ void unquote_string(const char *input, char *output); int uprf(char *, char *); int vfgets(FILE *, char **); char *write_charset_8bit(void); +void fold(charstring_t, size_t, const char *restrict); diff --git a/sbr/Makefile.in b/sbr/Makefile.in index cee1c45..ca8b20d 100644 --- a/sbr/Makefile.in +++ b/sbr/Makefile.in @@ -54,7 +54,8 @@ SRCS = addrsbr.c ambigsw.c brkstring.c \ cpydata.c crawl_folders.c \ charstring.c \ dtime.c dtimep.c \ - error.c execprog.c ext_hook.c folder_addmsg.c folder_delmsgs.c \ + error.c execprog.c ext_hook.c fold.c \ + folder_addmsg.c folder_delmsgs.c \ folder_free.c folder_read.c \ folder_realloc.c gans.c getans.c getanswer.c \ getarguments.c \ diff --git a/sbr/fold.c b/sbr/fold.c new file mode 100644 index 0000000..0189382 --- /dev/null +++ b/sbr/fold.c @@ -0,0 +1,61 @@ +/* fold.c -- fold a mail header field + * + * This code is Copyright (c), by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. */ + +#include +#include + +void +fold(charstring_t dst, size_t namelen, const char *restrict body) +{ + const char *restrict body_next; + const char *restrict wsp; + const char *restrict wsp_next; + const int crlf = strchr(body, '\r') != NULL; + charstring_clear(dst); + namelen++; + + while (*body) { + body_next = strchr(body, '\n'); + if ((unsigned long) (body_next - body) <= MAXTEXTPERLN - namelen) { + charstring_push_back_chars(dst, body, body_next - body + 1); + namelen = 0; + body = body_next + 1; + continue; + } + wsp = body; + while (namelen == 0 && (*wsp == ' ' || *wsp == '\t')) { + wsp++; + } + wsp = wsp_next = strpbrk(wsp, " \t"); + + /* if now whitespace is in the current line just print the curret line as is */ + if (!wsp_next || wsp_next > body_next) { + charstring_push_back_chars(dst, body, body_next - body + 1); + namelen = 0; + body = body_next + 1; + continue; + } + + while ((unsigned long)(wsp_next - body) <= MAXTEXTPERLN - namelen) { + wsp = wsp_next; + wsp_next = strpbrk(wsp+1, " \t"); + if (!wsp_next) { + break; + } + if (wsp_next > body_next) { + break; + } + } + + charstring_push_back_chars(dst, body, wsp - body); + if (crlf) { + charstring_push_back(dst, '\r'); + } + charstring_push_back(dst, '\n'); + namelen = 0; + body = wsp; + } +} diff --git a/test/tests/mhbuild/test-folding b/test/tests/mhbuild/test-folding new file mode 100644 index 0000000..366f82b --- /dev/null +++ b/test/tests/mhbuild/test-folding @@ -0,0 +1,35 @@ +# test mhbuild linebreak for quoted-printable + +. "$MH_TEST_COMMON" + + +draft="$MH_TEST_DIR/mhbuild-$$.draft" + +cat >"$draft" < +---------------- +Das ist ein test +! + + + +runandcheck 'mhbuild "$draft"' </" "$draft"' < + +MIME-Version: 1.0 +Content-Type: text/plain; charset="us-ascii" +Content-ID: + +Das ist ein test +! diff --git a/uip/mhoutsbr.c b/uip/mhoutsbr.c index 87e7943..2915afe 100644 --- a/uip/mhoutsbr.c +++ b/uip/mhoutsbr.c @@ -161,12 +161,15 @@ static void output_headers(CT ct, FILE *out) { HF hp; + charstring_t body = charstring_create(0); hp = ct->c_first_hf; while (hp) { - fprintf(out, "%s:%s", hp->name, hp->value); + fold(body, strlen(hp->name), hp->value); + fprintf(out, "%s:%s", hp->name, charstring_buffer(body)); hp = hp->next; } + charstring_free(body); } -- 1.7.10.4