don't decode base64 non-text parts

This commit is contained in:
revsuine 2024-11-16 15:44:27 +00:00
parent 52405bf067
commit 638f622f24
Signed by: revsuine
GPG key ID: 3F257B68F5BC9339

View file

@ -87,7 +87,7 @@ def decode_email(message: email.message.Message) -> email.message.Message:
decoded_bytes = message.as_string().encode()
# if email doesn't need decoding
has_quopri = b'Content-Transfer-Encoding: quoted-printable' in decoded_bytes
has_base64 = b'Content-Transfer-Encoding: base64' in decoded_bytes
has_base64 = is_base64_text(message) # we don't want to decode non-text
if not (has_quopri or has_base64):
return message
decoded_bytes = quopri.decodestring(decoded_bytes)
@ -117,7 +117,7 @@ def decode_email(message: email.message.Message) -> email.message.Message:
) -> bytes:
"""
change decoded_bytes such that part is decoded if base64 (unchanged if
not)
not) and text (so will not decode base64 images etc)
see usage below for examples
@ -128,7 +128,8 @@ def decode_email(message: email.message.Message) -> email.message.Message:
don't overwrite this
:return: bytes of decoded_bytes with part decoded if base64
"""
if part.get("Content-Transfer-Encoding") == "base64":
if part.get("Content-Transfer-Encoding") == "base64" and \
part.get_content_maintype() == "text":
b64_str = part.get_payload()
# remove the boundary as we don't want to change this
if most_recent_boundary:
@ -197,6 +198,25 @@ def set_email_header(
else:
message.add_header(name, value)
def is_base64_text(message: email.message.Message) -> bool:
"""
Return whether or not there is base64-encoded text in a multipart
message, i.e. will be False if it's only e.g. images that are encoded as
base64.
:param message: the email Message to check
:return: True if there is a text part that's base64 encoded, False if not
"""
if message.is_multipart():
for part in message.walk():
if part.get('Content-Transfer-Encoding') == "base64" and \
part.get_content_maintype() == "text":
return True
return False
else:
return message.get('Content-Transfer-Encoding') == "base64" and \
message.get_content_maintype() == "text"
def encrypt(
message: email.message.Message,
recipients: typing.List[str],
@ -236,7 +256,7 @@ def encrypt(
if is_message_encrypted(message):
return message.as_string()
# bc i just have a bunch of issues w b64
if "Content-Transfer-Encoding: base64" in message.as_string():
if is_base64_text(message):
return message.as_string()
# make necessary changes to message