tools: Replace duplicated code in mime-maker.
authorWerner Koch <wk@gnupg.org>
Mon, 15 Oct 2018 09:32:19 +0000 (11:32 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 15 Oct 2018 09:45:14 +0000 (11:45 +0200)
* 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>
tools/mime-maker.c
tools/rfc822parse.c
tools/rfc822parse.h

index 0edc14d..91eab82 100644 (file)
 
 #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)
     {
index e8cdb02..0a4e2bc 100644 (file)
 
 #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;
index 177d827..e2f2bed 100644 (file)
@@ -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);