1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-10 21:38:50 +01:00

tools: Improve rfc822parse to allow access to headers for longer.

* tools/rfc822parse.c (struct rfc822parse_context): Add field
this_part.
(release_handle_data): Clear this_part.
(rfc822parse_open): Set this_part.
(set_current_part_to_parent): Ditto.
(insert_header): Ditto.
(rfc822parse_enum_header_lines): Replace current_part by this_part.
(find_header): Ditto.

* tools/rfc822parse.c (my_strcasecmp): Remove.
(same_header_name): New.
(rfc822_capitalize_header_name): Use new function instead.
--

With this change the header function can now be sued after the
transition to the body.  Thus up until thenext MIME block is reached
the headers of the former MIME block are returned.

This also fixes a problem with the "MIME-Version" header name
capitalization.
This commit is contained in:
Werner Koch 2024-08-29 17:42:19 +02:00
parent 80bd49224e
commit ac30449867
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -100,6 +100,8 @@ struct rfc822parse_context
int in_preamble; /* Whether we are before the first boundary. */ int in_preamble; /* Whether we are before the first boundary. */
part_t parts; /* The tree of parts. */ part_t parts; /* The tree of parts. */
part_t current_part; /* Whom we are processing (points into parts). */ part_t current_part; /* Whom we are processing (points into parts). */
part_t this_part; /* Same as current_part but kept until new
* headers are processed. */
const char *boundary; /* Current boundary. */ const char *boundary; /* Current boundary. */
}; };
@ -147,19 +149,21 @@ my_toupper (int c)
return c; return c;
} }
/* This is the same as ascii_strcasecmp. */ /* This is like ascii_strcasecmp but stops at the first colon and
* returns true if A and B are the same. */
static int static int
my_strcasecmp (const char *a, const char *b) same_header_name (const char *a, const char *b)
{ {
if (a == b) if (a == b)
return 0; return 1;
for (; *a && *b; a++, b++) for (; *a && *a != ':' && *b && *b != ':'
{ && (*a == *b || my_toupper(*a) == my_toupper(*b)); a++,b++)
if (*a != *b && my_toupper(*a) != my_toupper(*b)) ;
break; if ((!*a || *a == ':') && (!*b || *b == ':'))
} return 1;
return *a == *b? 0 : (my_toupper (*a) - my_toupper (*b));
return 0;
} }
@ -234,6 +238,7 @@ release_handle_data (rfc822parse_t msg)
release_part (msg->parts); release_part (msg->parts);
msg->parts = NULL; msg->parts = NULL;
msg->current_part = NULL; msg->current_part = NULL;
msg->this_part = NULL;
msg->boundary = NULL; msg->boundary = NULL;
} }
@ -279,9 +284,9 @@ rfc822_capitalize_header_name (char *name)
int first = 1; int first = 1;
/* Special cases first. */ /* Special cases first. */
if (!my_strcasecmp (name, "MIME-Version")) if (same_header_name (name, "MIME-Version"))
{ {
strcpy (name, "MIME-Version"); memcpy (name, "MIME-Version", 12);
return; return;
} }
@ -328,7 +333,7 @@ rfc822parse_open (rfc822parse_cb_t cb, void *cb_value)
rfc822parse_t msg = calloc (1, sizeof *msg); rfc822parse_t msg = calloc (1, sizeof *msg);
if (msg) if (msg)
{ {
msg->parts = msg->current_part = new_part (); msg->parts = msg->current_part = msg->this_part = new_part ();
if (!msg->parts) if (!msg->parts)
{ {
free (msg); free (msg);
@ -411,7 +416,7 @@ set_current_part_to_parent (rfc822parse_t msg)
assert (part); assert (part);
} }
#endif #endif
msg->current_part = parent; msg->current_part = msg->this_part = parent;
parent = find_parent (msg->parts, parent); parent = find_parent (msg->parts, parent);
msg->boundary = parent? parent->boundary: NULL; msg->boundary = parent? parent->boundary: NULL;
@ -559,6 +564,8 @@ insert_header (rfc822parse_t msg, const unsigned char *line, size_t length)
* every Received header. */ * every Received header. */
if (length >= 9 && !memcmp (line, "Received:", 9)) if (length >= 9 && !memcmp (line, "Received:", 9))
do_callback (msg, RFC822PARSE_RCVD_SEEN); do_callback (msg, RFC822PARSE_RCVD_SEEN);
msg->this_part = msg->current_part;
return 0; return 0;
} }
@ -718,14 +725,15 @@ const char *
rfc822parse_enum_header_lines (rfc822parse_t msg, void **context) rfc822parse_enum_header_lines (rfc822parse_t msg, void **context)
{ {
HDR_LINE l; HDR_LINE l;
part_t part;
if (!msg) /* Close. */ if (!msg) /* Close. */
return NULL; return NULL;
if (*context == msg || !msg->current_part) if (*context == msg || !msg->this_part)
return NULL; return NULL;
l = *context ? (HDR_LINE) *context : msg->current_part->hdr_lines; l = *context ? (HDR_LINE) *context : msg->this_part->hdr_lines;
if (l) if (l)
{ {
@ -759,7 +767,7 @@ find_header (rfc822parse_t msg, const char *name, int which, HDR_LINE *rprev)
int found = 0; int found = 0;
int glob = 0; int glob = 0;
if (!msg->current_part) if (!msg->this_part)
return NULL; return NULL;
namelen = strlen (name); namelen = strlen (name);
@ -769,7 +777,7 @@ find_header (rfc822parse_t msg, const char *name, int which, HDR_LINE *rprev)
glob = 1; glob = 1;
} }
hdr = msg->current_part->hdr_lines; hdr = msg->this_part->hdr_lines;
if (rprev && *rprev) if (rprev && *rprev)
{ {
/* spool forward to the requested starting place. /* spool forward to the requested starting place.