summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-10-15 11:32:19 +0200
committerWerner Koch <wk@gnupg.org>2018-10-15 11:45:14 +0200
commitf03928b16c4fb00077d22d8ec141575ef6d26913 (patch)
tree1221cf48e1a69591f8c3e8b0d6960ab9437a0fde
parentscd: Fix signing authentication status. (diff)
downloadgnupg2-f03928b16c4fb00077d22d8ec141575ef6d26913.tar.xz
gnupg2-f03928b16c4fb00077d22d8ec141575ef6d26913.zip
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>
-rw-r--r--tools/mime-maker.c47
-rw-r--r--tools/rfc822parse.c103
-rw-r--r--tools/rfc822parse.h2
3 files changed, 90 insertions, 62 deletions
diff --git a/tools/mime-maker.c b/tools/mime-maker.c
index 0edc14d78..91eab8258 100644
--- a/tools/mime-maker.c
+++ b/tools/mime-maker.c
@@ -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)
{
diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c
index e8cdb0215..0a4e2bc94 100644
--- a/tools/rfc822parse.c
+++ b/tools/rfc822parse.c
@@ -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)
+
+static int
+my_toupper (int c)
{
- int first = 1;
+ 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 (; *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';
+ 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;
diff --git a/tools/rfc822parse.h b/tools/rfc822parse.h
index 177d8271a..e2f2bedac 100644
--- a/tools/rfc822parse.h
+++ b/tools/rfc822parse.h
@@ -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);