diff --git a/ChangeLog b/ChangeLog index 6f1ee8969..ba5f0f595 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-06-15 Richard Frith-Macdonald + + * Source/Additions/GSMime.m: Be more tolerant of illegal data in + quoted printable words. + 2008-06-15 Adam Fedor * Version 1.16.0 diff --git a/Source/Additions/GSMime.m b/Source/Additions/GSMime.m index 898823f8f..5f0dcaa5c 100644 --- a/Source/Additions/GSMime.m +++ b/Source/Additions/GSMime.m @@ -151,19 +151,36 @@ decodeWord(unsigned char *dst, unsigned char *src, unsigned char *end, WE enc) { break; } - if (('\n' == *src) || ('\r' == *src)) - { - break; - } - c = isdigit(*src) ? (*src - '0') : (*src - 55); - c <<= 4; - src++; - if (*src == '\0') - { - break; - } - c += isdigit(*src) ? (*src - '0') : (*src - 55); - *dst = c; + if (('\n' == *src) || ('\r' == *src)) + { + break; + } + if (!isxdigit(src[0]) || !isxdigit(src[1])) + { + /* Strictly speaking the '=' must be followed by + * two hexadecimal characters, but RFC2045 says that + * 'A reasonable approach by a robust implementation might be + * to include the "=" character and the following character + * in the decoded data without any transformation' + */ + *dst++ = '='; + *dst = *src; + } + else + { + int h; + int l; + + /* Strictly speaking only uppercase characters are legal + * here, but we tolerate lowercase too. + */ + h = isdigit(*src) ? (*src - '0') : (*src - 55); + if (h > 15) h -= 32; // lowercase a-f + src++; + l = isdigit(*src) ? (*src - '0') : (*src - 55); + if (l > 15) l -= 32; // lowercase a-f + *dst = (h << 4) + l; + } } else if (*src == '_') {