--- sylpheed/libsylph/quoted-printable.c.alt-qpfix 2005-09-13 12:18:44 +0400 +++ sylpheed/libsylph/quoted-printable.c 2006-05-21 22:01:00 +0400 @@ -142,6 +142,28 @@ gint qp_decode_q_encoding(guchar *out, c return outp - out; } +/** + * Check if the character can be represented directly in a Q-encoded word. + * + * @param c Tested character + * + * @returns 1 if the character can be represented directly, 0 if it must be + * hex-encoded. + * + * @warning The argument is evaluated multiple times. + * + * @note This macro uses the most restrictive set of allowed characters + * (described in RFC 2047, section 5, (3)), so the word encoded + * according to these rules should be usable in all contexts where + * an encoded word may appear. + */ +#define IS_QP_SAFE_CHAR(c) \ + ( ((c) >= 'A' && (c) <= 'Z') || \ + ((c) >= 'a' && (c) <= 'z') || \ + ((c) >= '0' && (c) <= '9') || \ + ((c) == '!') || ((c) == '*') || ((c) == '+') || \ + ((c) == '-') || ((c) == '/') ) + gint qp_get_q_encoding_len(const guchar *str) { const guchar *inp = str; @@ -150,11 +172,10 @@ gint qp_get_q_encoding_len(const guchar while (*inp != '\0') { if (*inp == 0x20) len++; - else if (*inp == '=' || *inp == '?' || *inp == '_' || - *inp < 32 || *inp > 127 || g_ascii_isspace(*inp)) - len += 3; - else + else if (IS_QP_SAFE_CHAR(*inp)) len++; + else + len += 3; inp++; } @@ -170,13 +191,13 @@ void qp_q_encode(gchar *out, const gucha while (*inp != '\0') { if (*inp == 0x20) *outp++ = '_'; - else if (*inp == '=' || *inp == '?' || *inp == '_' || - *inp < 32 || *inp > 127 || g_ascii_isspace(*inp)) { + else if (IS_QP_SAFE_CHAR(*inp)) + *outp++ = *inp; + else { *outp++ = '='; get_hex_str(outp, *inp); outp += 2; - } else - *outp++ = *inp; + } inp++; }