36 |
char *buffer; |
char *buffer; |
37 |
size_t bufsize; |
size_t bufsize; |
38 |
size_t bufpos; |
size_t bufpos; |
39 |
|
size_t run_count = 0; |
40 |
|
|
41 |
if (!tocode || !input || !ptostr) |
if (!tocode || !input || !ptostr) |
42 |
return EINVAL; |
return EINVAL; |
62 |
|
|
63 |
while (*fromstr) |
while (*fromstr) |
64 |
{ |
{ |
65 |
char *fromcode = NULL; |
if (strncmp (fromstr, "=?", 2) == 0) |
|
char *encoding_type = NULL; |
|
|
char *encoded_text = NULL; |
|
|
stream_t filter = NULL; |
|
|
stream_t in_stream = NULL; |
|
|
const char *filter_type = NULL; |
|
|
size_t nbytes = 0, size; |
|
|
char *sp = NULL; |
|
|
|
|
|
start_position = strstr (fromstr, "=?"); |
|
|
if (!start_position) |
|
|
break; |
|
|
|
|
|
/* Copy the unencoded part */ |
|
|
nbytes = start_position - fromstr; |
|
|
if (bufpos + nbytes > bufsize) /* just in case */ |
|
66 |
{ |
{ |
67 |
status = MU_ERR_BAD_2047_INPUT; |
char *fromcode = NULL; |
68 |
break; |
char *encoding_type = NULL; |
69 |
} |
char *encoded_text = NULL; |
70 |
|
stream_t filter = NULL; |
71 |
memcpy (buffer + bufpos, fromstr, nbytes); |
stream_t in_stream = NULL; |
72 |
bufpos += nbytes; |
const char *filter_type = NULL; |
73 |
|
size_t nbytes = 0, size; |
74 |
fromcode = strtok_r (start_position + 2, "?", &sp); |
char *sp = NULL; |
75 |
encoding_type = strtok_r (NULL, "?", &sp); |
|
76 |
encoded_text = strtok_r (NULL, "?", &sp); |
start_position = fromstr; |
77 |
if (sp[0] != '=') |
|
78 |
{ |
fromcode = strtok_r (start_position + 2, "?", &sp); |
79 |
status = MU_ERR_BAD_2047_INPUT; |
encoding_type = strtok_r (NULL, "?", &sp); |
80 |
break; |
encoded_text = strtok_r (NULL, "?", &sp); |
81 |
} |
if (sp[0] != '=') |
82 |
|
{ |
83 |
|
status = MU_ERR_BAD_2047_INPUT; |
84 |
|
break; |
85 |
|
} |
86 |
|
|
87 |
if (fromcode == NULL || encoding_type == NULL || encoded_text == NULL) |
if (fromcode == NULL |
88 |
{ |
|| encoding_type == NULL |
89 |
status = MU_ERR_BAD_2047_INPUT; |
|| encoded_text == NULL) |
90 |
break; |
{ |
91 |
} |
status = MU_ERR_BAD_2047_INPUT; |
92 |
|
break; |
93 |
|
} |
94 |
|
|
95 |
|
size = strlen (encoded_text); |
96 |
|
|
97 |
|
switch (toupper (encoding_type[0])) |
98 |
|
{ |
99 |
|
case 'B': |
100 |
|
filter_type = "base64"; |
101 |
|
break; |
102 |
|
|
103 |
|
case 'Q': |
104 |
|
filter_type = "quoted-printable"; |
105 |
|
break; |
106 |
|
|
107 |
|
default: |
108 |
|
status = MU_ERR_BAD_2047_INPUT; |
109 |
|
break; |
110 |
|
} |
111 |
|
|
112 |
|
if (status != 0) |
113 |
|
break; |
114 |
|
|
115 |
size = strlen (encoded_text); |
memory_stream_create (&in_stream, 0, 0); |
116 |
|
stream_write (in_stream, encoded_text, size, 0, NULL); |
117 |
|
filter_create (&filter, in_stream, filter_type, MU_FILTER_DECODE, |
118 |
|
MU_STREAM_READ); |
119 |
|
|
120 |
|
while (stream_sequential_read (filter, buffer + bufpos, |
121 |
|
bufsize - bufpos, |
122 |
|
&nbytes) == 0 && nbytes) |
123 |
|
{ |
124 |
|
/* FIXME: Need to convert character set */ |
125 |
|
bufpos += nbytes; |
126 |
|
} |
127 |
|
|
128 |
switch (toupper (encoding_type[0])) |
stream_close (filter); |
129 |
|
stream_destroy (&filter, stream_get_owner (filter)); |
130 |
|
|
131 |
|
fromstr = sp + 1; |
132 |
|
run_count = 1; |
133 |
|
} |
134 |
|
else if (run_count) |
135 |
{ |
{ |
136 |
case 'B': |
if (*fromstr == ' ' || *fromstr == '\t') |
137 |
filter_type = "base64"; |
{ |
138 |
break; |
run_count++; |
139 |
|
fromstr++; |
140 |
case 'Q': |
continue; |
141 |
filter_type = "quoted-printable"; |
} |
142 |
break; |
else |
143 |
|
{ |
144 |
default: |
if (--run_count) |
145 |
status = MU_ERR_BAD_2047_INPUT; |
{ |
146 |
break; |
memcpy (buffer + bufpos, fromstr - run_count, run_count); |
147 |
|
bufpos += run_count; |
148 |
|
run_count = 0; |
149 |
|
} |
150 |
|
|
151 |
|
buffer[bufpos++] = *fromstr++; |
152 |
|
} |
153 |
} |
} |
154 |
|
else |
155 |
if (status != 0) |
buffer[bufpos++] = *fromstr++; |
|
break; |
|
|
|
|
|
memory_stream_create (&in_stream, 0, 0); |
|
|
stream_write (in_stream, encoded_text, size, 0, NULL); |
|
|
filter_create (&filter, in_stream, filter_type, MU_FILTER_DECODE, |
|
|
MU_STREAM_READ); |
|
|
|
|
|
while (stream_sequential_read (filter, buffer + bufpos, bufsize - bufpos, |
|
|
&nbytes) == 0 && nbytes) |
|
|
{ |
|
|
/* FIXME: Need to convert character set */ |
|
|
bufpos += nbytes; |
|
|
} |
|
|
|
|
|
stream_close (filter); |
|
|
stream_destroy (&filter, stream_get_owner (filter)); |
|
|
|
|
|
fromstr = sp + 1; |
|
156 |
} |
} |
157 |
|
|
158 |
if (*fromstr) |
if (*fromstr) |
159 |
{ |
{ |
160 |
size_t len = strlen (fromstr); |
size_t len = strlen (fromstr); |