diff options
author | Srinivas Reddy Thatiparthy (తాటిపర్తి శ్రీనివాస్ రెడ్డి) <thatiparthysreenivas@gmail.com> | 2025-03-30 17:59:29 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-30 12:29:29 +0000 |
commit | c432d0147bdf1a66604e7a3d6a71660ae79b5f45 (patch) | |
tree | 6ea2c74ba2ad5eb95074fe4accc91d014c27c7bd /Lib/email | |
parent | 55150a79cacbce44f50cea128c511782df0ab277 (diff) | |
download | cpython-c432d0147bdf1a66604e7a3d6a71660ae79b5f45.tar.gz cpython-c432d0147bdf1a66604e7a3d6a71660ae79b5f45.zip |
gh-127794: Validate email header names according to RFC 5322 (#127820)
`email.message.Message` objects now validate header names specified via `__setitem__`
or `add_header` according to RFC 5322, §2.2 [1].
In particular, callers should expect a ValueError to be raised for invalid header names.
[1]: https://datatracker.ietf.org/doc/html/rfc5322#section-2.2
---------
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: R. David Murray <rdmurray@bitdance.com>
Diffstat (limited to 'Lib/email')
-rw-r--r-- | Lib/email/_policybase.py | 10 | ||||
-rw-r--r-- | Lib/email/policy.py | 9 |
2 files changed, 18 insertions, 1 deletions
diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py index 4b63b97217a..95e79b8938b 100644 --- a/Lib/email/_policybase.py +++ b/Lib/email/_policybase.py @@ -4,6 +4,7 @@ Allows fine grained feature control of how the package parses and emits data. """ import abc +import re from email import header from email import charset as _charset from email.utils import _has_surrogates @@ -14,6 +15,14 @@ __all__ = [ 'compat32', ] +# validation regex from RFC 5322, equivalent to pattern re.compile("[!-9;-~]+$") +valid_header_name_re = re.compile("[\041-\071\073-\176]+$") + +def validate_header_name(name): + # Validate header name according to RFC 5322 + if not valid_header_name_re.match(name): + raise ValueError( + f"Header field name contains invalid characters: {name!r}") class _PolicyBase: @@ -314,6 +323,7 @@ class Compat32(Policy): """+ The name and value are returned unmodified. """ + validate_header_name(name) return (name, value) def header_fetch_parse(self, name, value): diff --git a/Lib/email/policy.py b/Lib/email/policy.py index 6e109b65011..4169150101a 100644 --- a/Lib/email/policy.py +++ b/Lib/email/policy.py @@ -4,7 +4,13 @@ code that adds all the email6 features. import re import sys -from email._policybase import Policy, Compat32, compat32, _extend_docstrings +from email._policybase import ( + Compat32, + Policy, + _extend_docstrings, + compat32, + validate_header_name +) from email.utils import _has_surrogates from email.headerregistry import HeaderRegistry as HeaderRegistry from email.contentmanager import raw_data_manager @@ -138,6 +144,7 @@ class EmailPolicy(Policy): CR or LF characters. """ + validate_header_name(name) if hasattr(value, 'name') and value.name.lower() == name.lower(): return (name, value) if isinstance(value, str) and len(value.splitlines())>1: |