FreeCalypso > hg > falcon-mail-tools
view f-demime/header.c @ 2:1857d0d5a7bd
f-demime: fix parsing of Content-* headers
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 06 May 2023 06:33:26 +0000 |
parents | 7e0d08176f32 |
children | 612c4d0df768 |
line wrap: on
line source
/* * This module implements initial processing (pass-through and collection) * of message and body part headers. */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "defs.h" extern enum msg_hdr_state hdr_state; extern char cont_type_buf[HDR_BUF_SIZE], cont_te_buf[HDR_BUF_SIZE]; extern int got_cont_type, got_cont_te; static void error(line, msg) char *line, *msg; { if (got_cont_type) { fputs(cont_type_buf, stdout); got_cont_type = 0; } if (got_cont_te) { fputs(cont_te_buf, stdout); got_cont_te = 0; } printf("X-Fdemime-Error: %s\n", msg); puts(line); hdr_state = HDR_STATE_ERROR; } static void error_ct_cont(hdr_name) char *hdr_name; { printf("X-Fdemime-Error: %s header is too long\n", hdr_name); } static void cont_line(line) char *line; { unsigned prev_len; switch (hdr_state) { case HDR_STATE_BEGIN: error(line, "continuation line at the beginning of header"); return; case HDR_STATE_GOTSOME: puts(line); return; case HDR_STATE_CONT_TYPE: prev_len = strlen(cont_type_buf); if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { error_ct_cont("Content-Type"); fputs(cont_type_buf, stdout); puts(line); hdr_state = HDR_STATE_ERROR; got_cont_type = 0; return; } sprintf(cont_type_buf + prev_len, "%s\n", line); return; case HDR_STATE_CONT_TE: prev_len = strlen(cont_te_buf); if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { error_ct_cont("Content-Transfer-Encoding"); fputs(cont_te_buf, stdout); puts(line); hdr_state = HDR_STATE_ERROR; got_cont_te = 0; return; } sprintf(cont_te_buf + prev_len, "%s\n", line); return; default: fprintf(stderr, "f-demime internal error: bad state in cont_line()\n"); abort(); } } void header_input_line(line) char *line; { char *cp, savech; enum msg_hdr_state newhdr; if (!line[0]) { process_header_end(); return; } if (hdr_state == HDR_STATE_ERROR) { puts(line); return; } if (line[0] == ' ' || line[0] == '\t') { cont_line(line); return; } cp = index(line, ':'); if (!cp) { error(line, "header line has no colon"); return; } if (cp == line) { error(line, "null header field name"); return; } while (cp[-1] == ' ' || cp[-1] == '\t') cp--; savech = *cp; *cp = '\0'; if (!strcasecmp(line, "Content-Type")) newhdr = HDR_STATE_CONT_TYPE; else if (!strcasecmp(line, "Content-Transfer-Encoding")) newhdr = HDR_STATE_CONT_TE; else newhdr = HDR_STATE_GOTSOME; *cp = savech; switch (newhdr) { case HDR_STATE_CONT_TYPE: if (got_cont_type) { error(line, "duplicate Content-Type"); return; } sprintf(cont_type_buf, "%s\n", line); got_cont_type = 1; break; case HDR_STATE_CONT_TE: if (got_cont_te) { error(line, "duplicate Content-Transfer-Encoding"); return; } sprintf(cont_te_buf, "%s\n", line); got_cont_te = 1; break; default: puts(line); } hdr_state = newhdr; }