mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-12 18:11:03 +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:
parent
8d837279bc
commit
61514f7cd8
@ -51,6 +51,12 @@ gpg-wks-client-w32info.o : gpg-wks-client.w32-manifest \
|
||||
|
||||
endif
|
||||
|
||||
if DISABLE_TESTS
|
||||
TESTS =
|
||||
else
|
||||
TESTS = $(module_tests)
|
||||
endif
|
||||
|
||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
|
||||
|
||||
sbin_SCRIPTS = addgnupghome applygnupgdefaults
|
||||
@ -76,7 +82,7 @@ if !HAVE_W32_SYSTEM
|
||||
libexec_PROGRAMS += gpg-auth
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS = clean-sat make-dns-cert
|
||||
noinst_PROGRAMS = clean-sat make-dns-cert $(module_tests)
|
||||
|
||||
if BUILD_GPGTAR
|
||||
bin_PROGRAMS += gpgtar
|
||||
@ -216,6 +222,24 @@ gpg_auth_LDADD = $(common_libs) \
|
||||
$(GPG_ERROR_LIBS) \
|
||||
$(LIBINTL) $(NETLIBS) $(LIBICONV)
|
||||
|
||||
#
|
||||
# Module tests
|
||||
#
|
||||
module_tests = t-mime-maker
|
||||
|
||||
t_extra_src =
|
||||
t_common_cflags = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
|
||||
t_common_ldadd = $(libcommon) \
|
||||
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
|
||||
$(LIBINTL) $(LIBICONV)
|
||||
|
||||
t_mime_maker_SOURCES = t-mime-maker.c \
|
||||
rfc822parse.c rfc822parse.h \
|
||||
mime-maker.c mime-maker.h $(t_extra_src)
|
||||
t_mime_maker_LDADD = $(t_common_ldadd)
|
||||
|
||||
|
||||
|
||||
# Instead of a symlink we install a simple wrapper script for the new
|
||||
# gpg-wks-client location. We assume bin is a sibling of libexec.
|
||||
install-exec-local:
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,7 @@ void mime_maker_set_verbose (mime_maker_t ctx, int level);
|
||||
|
||||
void mime_maker_dump_tree (mime_maker_t ctx);
|
||||
|
||||
char *mime_maker_qp_encode (const char *string);
|
||||
gpg_error_t mime_maker_add_header (mime_maker_t ctx,
|
||||
const char *name, const char *value);
|
||||
gpg_error_t mime_maker_add_body (mime_maker_t ctx, const char *string);
|
||||
|
116
tools/t-mime-maker.c
Normal file
116
tools/t-mime-maker.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* t-mime-maker.c - Module test for mime-maker.c
|
||||
* Copyright (C) 2025 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../common/util.h"
|
||||
#include "../common/init.h"
|
||||
#include "mime-maker.h"
|
||||
|
||||
|
||||
static int verbose;
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_qp_encode (void)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char *plain;
|
||||
const char *encoded;
|
||||
} samples[] =
|
||||
{
|
||||
{ "",
|
||||
""
|
||||
},{
|
||||
"From someone\n"
|
||||
" I received this mail\n",
|
||||
"=46rom someone\n"
|
||||
" I received this mail\n"
|
||||
},{
|
||||
" From someone\n",
|
||||
" From someone\n"
|
||||
},{
|
||||
"Foo\n"
|
||||
".\n",
|
||||
"Foo\n"
|
||||
"=2E\n"
|
||||
},{
|
||||
"Foo\n"
|
||||
".",
|
||||
"Foo\n"
|
||||
"=2E"
|
||||
},{
|
||||
"Hello ÄÖܧäöüß my dear umlauts",
|
||||
"Hello =C3=84=C3=96=C3=9C=C2=A7=C3=A4=C3=B6=C3=BC=C3=9F "
|
||||
"my dear umlauts"
|
||||
},{
|
||||
"👀\tⒶ",
|
||||
"=F0=9F=91=80\t=E2=92=B6"
|
||||
}
|
||||
};
|
||||
int idx;
|
||||
char *result;
|
||||
int oops = 0;
|
||||
|
||||
for (idx=0; idx < DIM (samples); idx++)
|
||||
{
|
||||
result = mime_maker_qp_encode (samples[idx].plain);
|
||||
if (!result)
|
||||
{
|
||||
log_error ("%s:test %d: error: %s\n",
|
||||
__func__, idx, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
if (strcmp (samples[idx].encoded, result))
|
||||
{
|
||||
log_error ("%s:test %d: error\nwant ===>%s<===\n got ===>%s<===\n",
|
||||
__func__, idx, samples[idx].plain, result);
|
||||
oops = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (oops)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
log_set_prefix ("t-mime-maker", GPGRT_LOG_WITH_PREFIX);
|
||||
init_common_subsystems (&argc, &argv);
|
||||
|
||||
if (argc)
|
||||
{ argc--; argv++; }
|
||||
if (argc && !strcmp (argv[0], "--verbose"))
|
||||
{
|
||||
verbose = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
test_qp_encode ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user