From 5b52110399e991fa03480bfeb529e1fd0749fcc3 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Sun, 9 May 2021 16:23:18 +0200 Subject: mmime: do not duplicate Content* headers Do not add additional Content-Type and Content-Transfer-Encoding headers when using mmime on input already containing them. Do not reencode the message if Content-Transfer-Encoding is set. Based on a patch by Felix Van der Jeugt and duncaen. --- mmime.c | 28 +++++++++++++++++++++------- t/1000-mmime.t | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/mmime.c b/mmime.c index 4f06826..5c18171 100644 --- a/mmime.c +++ b/mmime.c @@ -387,6 +387,8 @@ gen_build() int inheader = 1; int intext = 0; int ret = 0; + char *contenttype = 0; + char *contenttransferenc = 0; while (1) { ssize_t read = getdelim(&line, &linelen, '\n', stdin); @@ -401,16 +403,24 @@ gen_build() inheader = 0; printf("MIME-Version: 1.0\n"); if (rflag) { - printf("Content-Type: text/plain; charset=UTF-8\n"); - printf("Content-Transfer-Encoding: quoted-printable\n\n"); - + printf("Content-Type:%s", contenttype ? contenttype : " text/plain; charset=UTF-8\n"); + printf("Content-Transfer-Encoding:%s", contenttransferenc ? contenttransferenc : " quoted-printable\n"); + printf("\n"); } else { printf("Content-Type: %s; boundary=\"%s\"\n", tflag, sep); printf("\n"); printf("This is a multipart message in MIME format.\n"); } } else { - print_header(line); + if (strncasecmp(line, "Content-Type:", 13) == 0) { + free(contenttype); + contenttype = strdup(line+13); + } else if (strncasecmp(line, "Content-Transfer-Encoding:", 26) == 0) { + free(contenttransferenc); + contenttransferenc = strdup(line+26); + } else { + print_header(line); + } } continue; } @@ -435,14 +445,18 @@ gen_build() if (!rflag && !intext) { printf("\n--%s\n", sep); - printf("Content-Type: text/plain; charset=UTF-8\n"); + printf("Content-Type:%s", contenttype ? contenttype : " text/plain; charset=UTF-8\n"); printf("Content-Disposition: inline\n"); - printf("Content-Transfer-Encoding: quoted-printable\n\n"); + printf("Content-Transfer-Encoding:%s", contenttransferenc ? contenttransferenc : " quoted-printable\n"); + printf("\n"); intext = 1; } - gen_qp((uint8_t *)line, strlen(line), 78, 0); + if (contenttransferenc) + printf("%s", line); + else + gen_qp((uint8_t *)line, strlen(line), 78, 0); } if (!rflag && !inheader) printf("\n--%s--\n", sep); diff --git a/t/1000-mmime.t b/t/1000-mmime.t index b0b0dc5..47ca63b 100755 --- a/t/1000-mmime.t +++ b/t/1000-mmime.t @@ -1,7 +1,7 @@ #!/bin/sh -e cd ${0%/*} . ./lib.sh -plan 8 +plan 12 cat <tmp References: @@ -42,3 +42,50 @@ Subject: inclusion test with other disposition EOF check 'include works, overriding filename' 'mmime tmp2 +Subject: message with content-type +Content-Type: text/plain; format=flowed + +This message has format-flowed. +EOF + +check 'content-type is respected if found in input' 'mmime -r tmp2 +Subject: message with content-transfer-encoding +Content-Transfer-Encoding: quoted-printable + +This message has already encoded. f=C3=B6=C3=B6. +EOF + + +check 'content-transfer-encoding is respected if found in input' 'mmime -r tmp2 +Subject: message with content-type +Content-Type: text/plain; format=flowed + +This message has format-flowed. + +#message/rfc822 $PWD/tmp + +This part too. +EOF + + +check 'content-type is respected if found in input, for multipart/mixed' 'mmime tmp2 +Subject: message with content-transfer-encoding +Content-Transfer-Encoding: Quoted-Printable + +This message has already encoded. f=C3=B6=C3=B6. + +#message/rfc822 $PWD/tmp + +This part too. +EOF + +check 'content-transfer-encoding is respected if found in input, for multipart/mixed' 'mmime