tools: Extend mime-maker.c:mime_maker_add_header.

* tools/mime-maker.c (add_header): Check header name and allow
name-value syntax.
(mime_maker_add_header): Add mode for a syntax check.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-07-02 18:55:22 +02:00
parent 442efa9b3f
commit 0e36a1d1fb
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 54 additions and 11 deletions

View File

@ -27,6 +27,11 @@
#include "mime-maker.h" #include "mime-maker.h"
/* All valid charachters in a header name. */
#define HEADER_NAME_CHARS ("abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"-01234567890")
/* An object to store an header. Also used for a list of headers. */ /* An object to store an header. Also used for a list of headers. */
struct header_s struct header_s
{ {
@ -294,12 +299,37 @@ add_header (part_t part, const char *name, const char *value)
{ {
gpg_error_t err; gpg_error_t err;
header_t hdr; header_t hdr;
size_t namelen;
const char *s;
hdr = xtrymalloc (sizeof *hdr + strlen (name)); if (!value)
{
s = strchr (name, '=');
if (!s)
return gpg_error (GPG_ERR_INV_ARG);
namelen = s - name;
value = s+1;
}
else
namelen = strlen (name);
hdr = xtrymalloc (sizeof *hdr + namelen);
if (!hdr) if (!hdr)
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
hdr->next = NULL; hdr->next = NULL;
strcpy (hdr->name, name); memcpy (hdr->name, name, namelen);
hdr->name[namelen] = 0;
/* Check that the header name is valid. We allow all lower and
* uppercase letters and, except for the first character, digits and
* the dash. */
if (strspn (hdr->name, HEADER_NAME_CHARS) != namelen
|| strchr ("-0123456789", *hdr->name))
{
xfree (hdr);
return gpg_error (GPG_ERR_INV_NAME);
}
capitalize_header_name (hdr->name); capitalize_header_name (hdr->name);
hdr->value = xtrystrdup (value); hdr->value = xtrystrdup (value);
if (!hdr->value) if (!hdr->value)
@ -308,21 +338,30 @@ add_header (part_t part, const char *name, const char *value)
xfree (hdr); xfree (hdr);
return err; return err;
} }
*part->headers_tail = hdr;
part->headers_tail = &hdr->next; if (part)
{
*part->headers_tail = hdr;
part->headers_tail = &hdr->next;
}
else
xfree (hdr);
return 0; return 0;
} }
/* 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 no container has been * VALUE will be handled automagically. If NULL is used for VALUE it
* added, the header will be used for the regular mail headers and not * is expected that the NAME has the format "NAME=VALUE" and VALUE is
* for a MIME part. If the current part is in a container and a body * taken from there.
* has been added, we append a new part to the current container. *
* Thus for a non-MIME mail the caller needs to call this function * If no container has been added, the header will be used for the
* followed by a call to add a body. When adding a Content-Type the * regular mail headers and not for a MIME part. If the current part
* boundary parameter must not be included. * is in a container and a body has been added, we append a new part
* to the current container. Thus for a non-MIME mail the caller
* needs to call this function followed by a call to add a body. When
* adding a Content-Type the boundary parameter must not be included.
*/ */
gpg_error_t gpg_error_t
mime_maker_add_header (mime_maker_t ctx, const char *name, const char *value) mime_maker_add_header (mime_maker_t ctx, const char *name, const char *value)
@ -330,6 +369,10 @@ mime_maker_add_header (mime_maker_t ctx, const char *name, const char *value)
gpg_error_t err; gpg_error_t err;
part_t part, parent; part_t part, parent;
/* Hack to use this fucntion for a synacx check of NAME and VALUE. */
if (!ctx)
return add_header (NULL, name, value);
err = ensure_part (ctx, &parent); err = ensure_part (ctx, &parent);
if (err) if (err)
return err; return err;