Better support of misencoded headers.

This commit is contained in:
Antoine Nguyen
2013-09-05 20:45:43 +02:00
parent 4adcc28a0e
commit 3f53b75516
+31 -26
View File
@@ -1,45 +1,50 @@
#!/usr/bin/env python
# u2u_decode.py
# unstructured rfc2047 header to unicode
#
# coding: utf-8
"""
u2u_decode.py
unstructured rfc2047 header to unicode
"""
import re
from email.header import decode_header, make_header
# check spaces between encoded_words (and strip them)
sre = re.compile(r'\?=[ \t]+=\?')
# re pat for MIME encoded_word (without trailing spaces)
mre = re.compile(r'=\?[^?]*?\?[bq]\?[^? \t]*?\?=', re.I)
mre = re.compile(r'=\?[^?]*?\?[bq]\?[^?\t]*?\?=', re.I)
def clean_spaces(m):
"""Replace unencoded spaces in string
:param str m: a match object
:return: the cleaned string
"""
return m.group(0).replace(" ", "=20")
tre = re.compile('=\?[^?]*\?=')
def decode_mime(m):
# substitute matching encoded_word with unicode equiv.
h = decode_header(m.group(0))
"""substitute matching encoded_word with unicode equiv.
"""
h = decode_header(clean_spaces(m))
u = unicode(make_header(h))
return u
def clean_spaces(m):
return m.group(0).replace(" ", "=20")
def u2u_decode(s):
# utility function for (final) decoding of mime header
# note: resulting string is in one line (no \n within)
# note2: spaces between enc_words are stripped (see RFC2047)
ur"""utility function for (final) decoding of mime header
note: resulting string is in one line (no \n within)
note2: spaces between enc_words are stripped (see RFC2047)
>>> u2u_decode('=?ISO-8859-15?Q?=20Profitez de tous les services en ligne sur impots.gouv.fr?=')
u' Profitez de tous les services en ligne sur impots.gouv.fr'
>>> u2u_decode('=?ISO-8859-1?Q?Accus=E9?= de =?ISO-8859-1?Q?r=E9ception?= de votre annonce')
u'Accus\xe9 de r\xe9ception de votre annonce'
>>> u2u_decode('Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord')
u'Sm\xf6rg\xe5sbord'
"""
s = ''.join(s.splitlines())
s = sre.sub('?==?', s)
s = tre.sub(clean_spaces, s)
u = mre.sub(decode_mime, s)
return u
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
s = sys.argv[1]
else:
s = """[Apache-Users 7784] ServerAlias =?ISO-2022-JP?B?GyRAGyRCJEsbKEI=?=:(
=?ISO-2022-JP?B?GyRCJTMlbSVzGyhC?=)=?ISO-2022-JP?B?GyRCJHI7SBsoQg==?=
=?ISO-2022-JP?B?GyRAGyRCTVEkOSRrJEg1c0YwJCwkKiQrJDckJBsoQg==?="""
s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord'
u = u2u_decode(s)
print u