1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

tools: Add a quoted-printable encoding function.

* tools/mime-maker.c (mime_maker_qp_encode): New.
* tools/t-mime-maker.c: New.
* tools/Makefile.am (TESTS): New.
(module_tests): Add the first test.
This commit is contained in:
Werner Koch 2025-05-30 12:15:37 +02:00
parent 8d837279bc
commit 61514f7cd8
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 227 additions and 2 deletions

View file

@ -1,5 +1,5 @@
/* mime-maker.c - Create MIME structures
* Copyright (C) 2016 g10 Code GmbH
* Copyright (C) 2016, 2025 g10 Code GmbH
* Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* This file is part of GnuPG.
@ -16,6 +16,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include <config.h>
@ -348,6 +349,89 @@ add_header (part_t part, const char *name, const char *value)
}
/* Return a new string which is QP encoded. Also encodes the F in a
* leading "From " and a line with a single dot. Return NULL and sets
* ERRNO on error. */
char *
mime_maker_qp_encode (const char *string)
{
/* Check whether the current character is followed by a line ending.
* The end of the string also considered a line ending. */
#define nextislf(a) (*a && ((a[1] == '\r' && a[2] == '\n') \
|| a[1] == '\n' || !a[1]))
#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
char *buffer, *p;
const unsigned char *s;
int lastwaslf;
size_t n;
/* Count the required length. */
for (lastwaslf=1, n=0, s = string; *s; s++)
{
if (*s == '.' && nextislf (s))
{
n += 3;
}
else if (!strncmp (s, "From ", 5))
{
n += 3 + 4;
s += 4;
}
else if (*s == '=')
{
n += 3;
}
else if (strchr ("\r\n\t", *s) || (*s >= 0x20 && *s <= 0x7e))
n++;
else
n += 3;
}
n++;
/* Now encode. */
p = buffer = xtrymalloc (n);
if (!buffer)
return NULL;
for (lastwaslf=1, s = string; *s; s++)
{
if (lastwaslf && *s == '.' && nextislf (s))
{
*p++ = '=';
*p++ = '2';
*p++ = 'E';
}
else if (lastwaslf && !strncmp (s, "From ", 5))
{
memcpy (p, "=46rom ", 7);
p += 7;
s += 4;
}
else if (*s == '=')
{
*p++ = '=';
*p++ = '3';
*p++ = 'D';
}
else if (strchr ("\r\n\t", *s) || (*s >= 0x20 && *s <= 0x7e))
*p++ = *s;
else
{
*p++ = '=';
*p++ = tohex ((*s>>4)&15);
*p++ = tohex (*s&15);
}
lastwaslf = (*s == '\n');
}
*p = 0;
return buffer;
#undef tohex
#undef nextislf
}
/* Add a header with NAME and VALUE to the current mail. A LF in the
* VALUE will be handled automagically. If NULL is used for VALUE it
* is expected that the NAME has the format "NAME=VALUE" and VALUE is