FreeCalypso > hg > falcon-mail-tools
annotate 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 |
rev | line source |
---|---|
0
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 /* |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 * This module implements initial processing (pass-through and collection) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 * of message and body part headers. |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 */ |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6 #include <ctype.h> |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
7 #include <stdio.h> |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 #include <stdlib.h> |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
9 #include <string.h> |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 #include <strings.h> |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 #include "defs.h" |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 extern enum msg_hdr_state hdr_state; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14 extern char cont_type_buf[HDR_BUF_SIZE], cont_te_buf[HDR_BUF_SIZE]; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 extern int got_cont_type, got_cont_te; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
16 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
17 static void |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
18 error(line, msg) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19 char *line, *msg; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 if (got_cont_type) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 fputs(cont_type_buf, stdout); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 got_cont_type = 0; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
24 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 if (got_cont_te) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26 fputs(cont_te_buf, stdout); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 got_cont_te = 0; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 printf("X-Fdemime-Error: %s\n", msg); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
31 hdr_state = HDR_STATE_ERROR; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
32 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 static void |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 error_ct_cont(hdr_name) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 char *hdr_name; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 printf("X-Fdemime-Error: %s header is too long\n", hdr_name); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 static void |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 cont_line(line) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
43 char *line; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 unsigned prev_len; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 switch (hdr_state) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 case HDR_STATE_BEGIN: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 error(line, "continuation line at the beginning of header"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 case HDR_STATE_GOTSOME: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
52 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 case HDR_STATE_CONT_TYPE: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 prev_len = strlen(cont_type_buf); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 error_ct_cont("Content-Type"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
58 fputs(cont_type_buf, stdout); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
59 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 hdr_state = HDR_STATE_ERROR; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 got_cont_type = 0; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 sprintf(cont_type_buf + prev_len, "%s\n", line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 case HDR_STATE_CONT_TE: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 prev_len = strlen(cont_te_buf); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 error_ct_cont("Content-Transfer-Encoding"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 fputs(cont_te_buf, stdout); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
72 hdr_state = HDR_STATE_ERROR; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
73 got_cont_te = 0; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
75 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
76 sprintf(cont_te_buf + prev_len, "%s\n", line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
77 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
78 default: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
79 fprintf(stderr, |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
80 "f-demime internal error: bad state in cont_line()\n"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
81 abort(); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
82 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
83 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
84 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
85 void |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
86 header_input_line(line) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
87 char *line; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
88 { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
89 char *cp, savech; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
90 enum msg_hdr_state newhdr; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
91 |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
92 if (!line[0]) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
93 process_header_end(); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
94 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
95 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
96 if (hdr_state == HDR_STATE_ERROR) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
97 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
98 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
99 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
100 if (line[0] == ' ' || line[0] == '\t') { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
101 cont_line(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
102 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
103 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
104 cp = index(line, ':'); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
105 if (!cp) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
106 error(line, "header line has no colon"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
107 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
108 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
109 if (cp == line) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
110 error(line, "null header field name"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
111 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
112 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
113 while (cp[-1] == ' ' || cp[-1] == '\t') |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
114 cp--; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
115 savech = *cp; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
116 *cp = '\0'; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
117 if (!strcasecmp(line, "Content-Type")) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
118 newhdr = HDR_STATE_CONT_TYPE; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
119 else if (!strcasecmp(line, "Content-Transfer-Encoding")) |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
120 newhdr = HDR_STATE_CONT_TE; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
121 else |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
122 newhdr = HDR_STATE_GOTSOME; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
123 *cp = savech; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
124 switch (newhdr) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
125 case HDR_STATE_CONT_TYPE: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
126 if (got_cont_type) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
127 error(line, "duplicate Content-Type"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
128 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
129 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
130 sprintf(cont_type_buf, "%s\n", line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
131 got_cont_type = 1; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
132 break; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
133 case HDR_STATE_CONT_TE: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
134 if (got_cont_te) { |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
135 error(line, "duplicate Content-Transfer-Encoding"); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
136 return; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
137 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
138 sprintf(cont_te_buf, "%s\n", line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
139 got_cont_te = 1; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
140 break; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
141 default: |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
142 puts(line); |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
143 } |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
144 hdr_state = newhdr; |
7e0d08176f32
f-demime starting code
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
145 } |