mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
tools: Replace duplicated code in mime-maker.
* tools/rfc822parse.c (HEADER_NAME_CHARS): New. Taken from mime-maker.c. (rfc822_valid_header_name_p): New. Based on code from mime-maker.c. (rfc822_capitalize_header_name): New. Copied from mime-maker.c. (capitalize_header_name): Remove. Replace calls by new func. (my_toupper, my_strcasecmp): New. * tools/mime-maker.c: Include rfc822parse.h. (HEADER_NAME_CHARS, capitalize_header_name): Remove. (add_header): Replace check and capitalization by new functions. -- This is a straightforward change with two minor chnages: - In rfc822parse.c the capitalization handles MIME-Version special. - The check in mime-maker bow detects a zero-length name as invalid. my_toupper and my_strcasecmp are introduced to allow standalone use of that file. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
78f542e1f4
commit
f03928b16c
@ -25,14 +25,10 @@
|
||||
|
||||
#include "../common/util.h"
|
||||
#include "../common/zb32.h"
|
||||
#include "rfc822parse.h"
|
||||
#include "mime-maker.h"
|
||||
|
||||
|
||||
/* All valid characters in a header name. */
|
||||
#define HEADER_NAME_CHARS ("abcdefghijklmnopqrstuvwxyz" \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
"-01234567890")
|
||||
|
||||
/* An object to store an header. Also used for a list of headers. */
|
||||
struct header_s
|
||||
{
|
||||
@ -269,38 +265,6 @@ ensure_part (mime_maker_t ctx, part_t *r_parent)
|
||||
}
|
||||
|
||||
|
||||
/* Transform a header name into a standard capitalized format.
|
||||
* "Content-Type". Conversion stops at the colon. */
|
||||
static void
|
||||
capitalize_header_name (char *name)
|
||||
{
|
||||
unsigned char *p = name;
|
||||
int first = 1;
|
||||
|
||||
/* Special cases first. */
|
||||
if (!ascii_strcasecmp (name, "MIME-Version"))
|
||||
{
|
||||
strcpy (name, "MIME-Version");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Regular cases. */
|
||||
for (; *p && *p != ':'; p++)
|
||||
{
|
||||
if (*p == '-')
|
||||
first = 1;
|
||||
else if (first)
|
||||
{
|
||||
if (*p >= 'a' && *p <= 'z')
|
||||
*p = *p - 'a' + 'A';
|
||||
first = 0;
|
||||
}
|
||||
else if (*p >= 'A' && *p <= 'Z')
|
||||
*p = *p - 'A' + 'a';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check whether a header with NAME has already been set into PART.
|
||||
* NAME must be in canonical capitalized format. Return true or
|
||||
* false. */
|
||||
@ -344,17 +308,14 @@ add_header (part_t part, const char *name, const char *value)
|
||||
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))
|
||||
/* Check that the header name is valid. */
|
||||
if (!rfc822_valid_header_name_p (hdr->name))
|
||||
{
|
||||
xfree (hdr);
|
||||
return gpg_error (GPG_ERR_INV_NAME);
|
||||
}
|
||||
|
||||
capitalize_header_name (hdr->name);
|
||||
rfc822_capitalize_header_name (hdr->name);
|
||||
hdr->value = xtrystrdup (value);
|
||||
if (!hdr->value)
|
||||
{
|
||||
|
@ -41,6 +41,12 @@
|
||||
|
||||
#include "rfc822parse.h"
|
||||
|
||||
/* All valid characters in a header name. */
|
||||
#define HEADER_NAME_CHARS ("abcdefghijklmnopqrstuvwxyz" \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
"-01234567890")
|
||||
|
||||
|
||||
enum token_type
|
||||
{
|
||||
tSPACE,
|
||||
@ -131,28 +137,31 @@ lowercase_string (unsigned char *string)
|
||||
*string = *string - 'A' + 'a';
|
||||
}
|
||||
|
||||
/* Transform a header name into a standard capitalized format; i.e
|
||||
"Content-Type". Conversion stops at the colon. As usual we don't
|
||||
use the localized versions of ctype.h.
|
||||
*/
|
||||
static void
|
||||
capitalize_header_name (unsigned char *name)
|
||||
{
|
||||
int first = 1;
|
||||
|
||||
for (; *name && *name != ':'; name++)
|
||||
if (*name == '-')
|
||||
first = 1;
|
||||
else if (first)
|
||||
{
|
||||
if (*name >= 'a' && *name <= 'z')
|
||||
*name = *name - 'a' + 'A';
|
||||
first = 0;
|
||||
}
|
||||
else if (*name >= 'A' && *name <= 'Z')
|
||||
*name = *name - 'A' + 'a';
|
||||
static int
|
||||
my_toupper (int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
c &= ~0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* This is the same as ascii_strcasecmp. */
|
||||
static int
|
||||
my_strcasecmp (const char *a, const char *b)
|
||||
{
|
||||
if (a == b)
|
||||
return 0;
|
||||
|
||||
for (; *a && *b; a++, b++)
|
||||
{
|
||||
if (*a != *b && my_toupper(*a) != my_toupper(*b))
|
||||
break;
|
||||
}
|
||||
return *a == *b? 0 : (my_toupper (*a) - my_toupper (*b));
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_STPCPY
|
||||
static char *
|
||||
my_stpcpy (char *a,const char *b)
|
||||
@ -228,6 +237,62 @@ release_handle_data (rfc822parse_t msg)
|
||||
}
|
||||
|
||||
|
||||
/* Check that the header name is valid. We allow all lower and
|
||||
* uppercase letters and, except for the first character, digits and
|
||||
* the dash. The check stops at the first colon or at string end.
|
||||
* Returns true if the name is valid. */
|
||||
int
|
||||
rfc822_valid_header_name_p (const char *name)
|
||||
{
|
||||
const char *s;
|
||||
size_t namelen;
|
||||
|
||||
if ((s=strchr (name, ':')))
|
||||
namelen = s - name;
|
||||
else
|
||||
namelen = strlen (name);
|
||||
|
||||
if (!namelen
|
||||
|| strspn (name, HEADER_NAME_CHARS) != namelen
|
||||
|| strchr ("-0123456789", *name))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Transform a header NAME into a standard capitalized format.
|
||||
* Conversion stops at the colon. */
|
||||
void
|
||||
rfc822_capitalize_header_name (char *name)
|
||||
{
|
||||
unsigned char *p = name;
|
||||
int first = 1;
|
||||
|
||||
/* Special cases first. */
|
||||
if (!my_strcasecmp (name, "MIME-Version"))
|
||||
{
|
||||
strcpy (name, "MIME-Version");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Regular cases. */
|
||||
for (; *p && *p != ':'; p++)
|
||||
{
|
||||
if (*p == '-')
|
||||
first = 1;
|
||||
else if (first)
|
||||
{
|
||||
if (*p >= 'a' && *p <= 'z')
|
||||
*p = *p - 'a' + 'A';
|
||||
first = 0;
|
||||
}
|
||||
else if (*p >= 'A' && *p <= 'Z')
|
||||
*p = *p - 'A' + 'a';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new parsing context for an entire rfc822 message and
|
||||
return it. CB and CB_VALUE may be given to callback for certain
|
||||
events. NULL is returned on error with errno set appropriately. */
|
||||
@ -432,7 +497,7 @@ insert_header (rfc822parse_t msg, const unsigned char *line, size_t length)
|
||||
|
||||
/* Transform a field name into canonical format. */
|
||||
if (!hdr->cont && strchr (line, ':'))
|
||||
capitalize_header_name (hdr->line);
|
||||
rfc822_capitalize_header_name (hdr->line);
|
||||
|
||||
*msg->current_part->hdr_lines_tail = hdr;
|
||||
msg->current_part->hdr_lines_tail = &hdr->next;
|
||||
|
@ -48,6 +48,8 @@ typedef int (*rfc822parse_cb_t) (void *opaque,
|
||||
rfc822parse_event_t event,
|
||||
rfc822parse_t msg);
|
||||
|
||||
int rfc822_valid_header_name_p (const char *name);
|
||||
void rfc822_capitalize_header_name (char *name);
|
||||
|
||||
rfc822parse_t rfc822parse_open (rfc822parse_cb_t cb, void *opaque_value);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user