- for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) {
- count++;
- switch (count) {
- case 2:
- /* ignore language specification a la RFC 2231 */
- t = pp1;
- if ((t1 = memchr (pp, '*', t - pp)))
- t = t1;
- charset = p_dupstr(pp, t - pp);
- break;
- case 3:
- if (toupper ((unsigned char) *pp) == 'Q')
- enc = ENCQUOTEDPRINTABLE;
- else if (toupper ((unsigned char) *pp) == 'B')
- enc = ENCBASE64;
- else {
- p_delete(&charset);
- p_delete(&d0);
- return (-1);
- }
- break;
- case 4:
- if (enc == ENCQUOTEDPRINTABLE) {
- for (; pp < pp1; pp++) {
- if (*pp == '_')
- *pd++ = ' ';
- else if (*pp == '=' && hexval(pp[1]) >= 0 && hexval(pp[2]) >= 0) {
- *pd++ = (hexval (pp[1]) << 4) | hexval (pp[2]);
- pp += 2;
- }
- else
- *pd++ = *pp;
- }
- *pd = 0;
+ t = strchr(p, '?');
+ if (!t)
+ return -1;
+ m_strncpy(charset, sizeof(charset), p, t - p);
+
+ switch (t[1]) {
+ case 'q': case 'Q':
+ enc = ENCQUOTEDPRINTABLE;
+ break;
+
+ case 'b': case 'B':
+ enc = ENCBASE64;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (t[2] != '?')
+ return -1;
+
+ p = t + 3; /* skip ?[QB]? */
+ d0 = q = p_new(char, end - p + 1); /* it's enough space to decode */
+
+ if (enc == ENCQUOTEDPRINTABLE) {
+ while (p < end - 2) {
+ if (*p == '=' && hexval(p[1]) >= 0 && hexval(p[2]) >= 0) {
+ *q++ = (hexval (p[1]) << 4) | hexval (p[2]);
+ p += 3;
+ } else
+ if (*p == '_') {
+ *q++ = ' ';
+ p++;
+ } else {
+ *q++ = *p++;