Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-mail/message-header-decode.c @ 956:26cafa3dc09c HEAD
minor optimization
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 12 Jan 2003 01:49:45 +0200 |
parents | 411006be3c66 |
children | 60646878858e |
rev | line source |
---|---|
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (C) 2002 Timo Sirainen */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "base64.h" |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "buffer.h" |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "quoted-printable.h" |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "message-header-decode.h" |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 static int split_encoded(const unsigned char *data, size_t *size_p, |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 const char **charset, const char **encoding, |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 const unsigned char **text, size_t *text_size_r) |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 size_t size, pos, textpos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 size = *size_p; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 /* get charset */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 for (pos = 0; pos < size && data[pos] != '?'; pos++) ; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 if (data[pos] != '?') return FALSE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 *charset = t_strndup(data, pos); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 /* get encoding */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 pos++; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 if (pos+2 >= size || data[pos+1] != '?') |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 return FALSE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 if (data[pos] == 'Q' || data[pos] == 'q') |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 *encoding = "Q"; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 else if (data[pos] == 'B' || data[pos] == 'b') |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 *encoding = "B"; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 else |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 return FALSE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 /* get text */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 pos += 2; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 textpos = pos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 while (pos < size && data[pos] != '?') pos++; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 if (data[pos] != '?' || pos+1 >= size || data[pos+1] != '=') |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 return FALSE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 *text = data + textpos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 *text_size_r = pos - textpos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 *size_p = pos+2; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 return TRUE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 static int |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 message_header_decode_encoded(const unsigned char *data, size_t *size, |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
49 message_header_decode_callback_t callback, |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
50 void *context) |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 const unsigned char *text; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 const char *charset, *encoding; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
783
diff
changeset
|
54 buffer_t *decodebuf; |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 size_t text_size; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 int ret; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 t_push(); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 /* first split the string charset?encoding?text?= */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 if (!split_encoded(data, size, &charset, &encoding, |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 &text, &text_size)) { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 t_pop(); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 return TRUE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 decodebuf = buffer_create_static_hard(data_stack_pool, text_size); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 if (*encoding == 'Q') |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 quoted_printable_decode(text, text_size, NULL, decodebuf); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 else { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 if (base64_decode(text, text_size, NULL, decodebuf) < 0) { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 /* corrupted encoding */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 t_pop(); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 return TRUE; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
79 ret = callback(buffer_get_data(decodebuf, NULL), |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
80 buffer_get_used_size(decodebuf), charset, context); |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 t_pop(); |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 return ret; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 void message_header_decode(const unsigned char *data, size_t size, |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
87 message_header_decode_callback_t callback, |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
88 void *context) |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 size_t pos, start_pos, subsize; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 start_pos = pos = 0; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 while (pos < size) { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 if (data[pos] == '=' && pos+1 < size && data[pos+1] == '?') { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 /* encoded string beginning */ |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 if (pos != start_pos) { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 /* send the unencoded data so far */ |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
98 if (!callback(data + start_pos, pos - start_pos, |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
99 NULL, context)) |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 return; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 pos += 2; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 subsize = size - pos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 if (!message_header_decode_encoded(data + pos, &subsize, |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
106 callback, context)) |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 return; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 pos += subsize; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 start_pos = pos; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 } else { |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 pos++; |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 } |
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
116 (void)callback(data + start_pos, size - start_pos, NULL, context); |
783
d826ab8c8d62
Quoted-Printable decoding was buggy. Extracted RFC2047 header decoding into
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 } |