mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-13 18:21: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
|
endif
|
||||||
|
|
||||||
|
if DISABLE_TESTS
|
||||||
|
TESTS =
|
||||||
|
else
|
||||||
|
TESTS = $(module_tests)
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
|
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
|
||||||
|
|
||||||
sbin_SCRIPTS = addgnupghome applygnupgdefaults
|
sbin_SCRIPTS = addgnupghome applygnupgdefaults
|
||||||
@ -76,7 +82,7 @@ if !HAVE_W32_SYSTEM
|
|||||||
libexec_PROGRAMS += gpg-auth
|
libexec_PROGRAMS += gpg-auth
|
||||||
endif
|
endif
|
||||||
|
|
||||||
noinst_PROGRAMS = clean-sat make-dns-cert
|
noinst_PROGRAMS = clean-sat make-dns-cert $(module_tests)
|
||||||
|
|
||||||
if BUILD_GPGTAR
|
if BUILD_GPGTAR
|
||||||
bin_PROGRAMS += gpgtar
|
bin_PROGRAMS += gpgtar
|
||||||
@ -216,6 +222,24 @@ gpg_auth_LDADD = $(common_libs) \
|
|||||||
$(GPG_ERROR_LIBS) \
|
$(GPG_ERROR_LIBS) \
|
||||||
$(LIBINTL) $(NETLIBS) $(LIBICONV)
|
$(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
|
# 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.
|
# gpg-wks-client location. We assume bin is a sibling of libexec.
|
||||||
install-exec-local:
|
install-exec-local:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* mime-maker.c - Create MIME structures
|
/* 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
|
* Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
@ -16,6 +16,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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/>.
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#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
|
/* 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
|
* 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
|
* 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);
|
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,
|
gpg_error_t mime_maker_add_header (mime_maker_t ctx,
|
||||||
const char *name, const char *value);
|
const char *name, const char *value);
|
||||||
gpg_error_t mime_maker_add_body (mime_maker_t ctx, const char *string);
|
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