| 
									
										
										
										
											2007-08-30 01:15:14 +00:00
										 |  |  | # Copyright (C) 2001-2006 Python Software Foundation | 
					
						
							|  |  |  | # Author: Barry Warsaw | 
					
						
							|  |  |  | # Contact: email-sig@python.org | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """email package exception classes.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MessageError(Exception): | 
					
						
							|  |  |  |     """Base class for errors in the email package.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MessageParseError(MessageError): | 
					
						
							|  |  |  |     """Base class for message parsing errors.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HeaderParseError(MessageParseError): | 
					
						
							|  |  |  |     """Error while parsing headers.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BoundaryError(MessageParseError): | 
					
						
							|  |  |  |     """Couldn't find terminating boundary.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MultipartConversionError(MessageError, TypeError): | 
					
						
							|  |  |  |     """Conversion to a multipart is prohibited.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CharsetError(MessageError): | 
					
						
							|  |  |  |     """An illegal charset was given.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # These are parsing defects which the parser was able to work around. | 
					
						
							| 
									
										
										
										
											2012-05-25 18:42:14 -04:00
										 |  |  | class MessageDefect(ValueError): | 
					
						
							| 
									
										
										
										
											2007-08-30 01:15:14 +00:00
										 |  |  |     """Base class for a message defect.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, line=None): | 
					
						
							| 
									
										
										
										
											2012-06-08 22:45:46 -04:00
										 |  |  |         if line is not None: | 
					
						
							|  |  |  |             super().__init__(line) | 
					
						
							| 
									
										
										
										
											2007-08-30 01:15:14 +00:00
										 |  |  |         self.line = line | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NoBoundaryInMultipartDefect(MessageDefect): | 
					
						
							|  |  |  |     """A message claimed to be a multipart but had no boundary parameter.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class StartBoundaryNotFoundDefect(MessageDefect): | 
					
						
							|  |  |  |     """The claimed start boundary was never found.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-27 22:20:42 -04:00
										 |  |  | class CloseBoundaryNotFoundDefect(MessageDefect): | 
					
						
							|  |  |  |     """A start boundary was found, but not the corresponding close boundary.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-30 01:15:14 +00:00
										 |  |  | class FirstHeaderLineIsContinuationDefect(MessageDefect): | 
					
						
							|  |  |  |     """A message had a continuation line as its first header line.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MisplacedEnvelopeHeaderDefect(MessageDefect): | 
					
						
							|  |  |  |     """A 'Unix-from' header was found in the middle of a header block.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-27 20:45:01 -04:00
										 |  |  | class MissingHeaderBodySeparatorDefect(MessageDefect): | 
					
						
							|  |  |  |     """Found line with no leading whitespace and no colon before blank line.""" | 
					
						
							|  |  |  | # XXX: backward compatibility, just in case (it was never emitted). | 
					
						
							|  |  |  | MalformedHeaderDefect = MissingHeaderBodySeparatorDefect | 
					
						
							| 
									
										
										
										
											2007-08-30 01:15:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class MultipartInvariantViolationDefect(MessageDefect): | 
					
						
							|  |  |  |     """A message claimed to be a multipart but no subparts were found.""" | 
					
						
							| 
									
										
										
										
											2011-06-22 13:47:53 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class InvalidMultipartContentTransferEncodingDefect(MessageDefect): | 
					
						
							|  |  |  |     """An invalid content transfer encoding was set on the multipart itself.""" | 
					
						
							| 
									
										
										
										
											2012-05-25 18:42:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class UndecodableBytesDefect(MessageDefect): | 
					
						
							|  |  |  |     """Header contained bytes that could not be decoded""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InvalidBase64PaddingDefect(MessageDefect): | 
					
						
							|  |  |  |     """base64 encoded sequence had an incorrect length""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InvalidBase64CharactersDefect(MessageDefect): | 
					
						
							|  |  |  |     """base64 encoded sequence had characters not in base64 alphabet""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:46:22 +03:00
										 |  |  | class InvalidBase64LengthDefect(MessageDefect): | 
					
						
							|  |  |  |     """base64 encoded sequence had invalid length (1 mod 4)""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 18:42:14 -04:00
										 |  |  | # These errors are specific to header parsing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HeaderDefect(MessageDefect): | 
					
						
							|  |  |  |     """Base class for a header defect.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-08 22:45:46 -04:00
										 |  |  |     def __init__(self, *args, **kw): | 
					
						
							|  |  |  |         super().__init__(*args, **kw) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 18:42:14 -04:00
										 |  |  | class InvalidHeaderDefect(HeaderDefect): | 
					
						
							|  |  |  |     """Header is not valid, message gives details.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HeaderMissingRequiredValue(HeaderDefect): | 
					
						
							|  |  |  |     """A header that must have a value had none""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NonPrintableDefect(HeaderDefect): | 
					
						
							|  |  |  |     """ASCII characters outside the ascii-printable range found""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, non_printables): | 
					
						
							|  |  |  |         super().__init__(non_printables) | 
					
						
							|  |  |  |         self.non_printables = non_printables | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return ("the following ASCII non-printables found in header: " | 
					
						
							|  |  |  |             "{}".format(self.non_printables)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ObsoleteHeaderDefect(HeaderDefect): | 
					
						
							|  |  |  |     """Header uses syntax declared obsolete by RFC 5322""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NonASCIILocalPartDefect(HeaderDefect): | 
					
						
							|  |  |  |     """local_part contains non-ASCII characters""" | 
					
						
							|  |  |  |     # This defect only occurs during unicode parsing, not when | 
					
						
							|  |  |  |     # parsing messages decoded from binary. | 
					
						
							| 
									
										
											  
											
												bpo-30681: Support invalid date format or value in email Date header (GH-22090)
I am re-submitting an older PR which was abandoned but is still relevant, #10783 by @timb07.
The issue being solved () is still relevant. The original PR #10783 was closed as
the final request changes were not applied and since abandoned.
In this new PR I have re-used the original patch plus applied both comments from the review, by @maxking and @pganssle.
For reference, here is the original PR description:
In email.utils.parsedate_to_datetime(), a failure to parse the date, or invalid date components (such as hour outside 0..23) raises an exception. Document this behaviour, and add tests to test_email/test_utils.py to confirm this behaviour.
In email.headerregistry.DateHeader.parse(), check when parsedate_to_datetime() raises an exception and add a new defect InvalidDateDefect; preserve the invalid value as the string value of the header, but set the datetime attribute to None.
Add tests to test_email/test_headerregistry.py to confirm this behaviour; also added test to test_email/test_inversion.py to confirm emails with such defective date headers round trip successfully.
This pull request incorporates feedback gratefully received from @bitdancer, @brettcannon, @Mariatta and @warsaw, and replaces the earlier PR #2254.
Automerge-Triggered-By: GH:warsaw
											
										 
											2020-10-27 01:31:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class InvalidDateDefect(HeaderDefect): | 
					
						
							| 
									
										
										
										
											2021-10-07 01:13:48 +02:00
										 |  |  |     """Header has unparsable or invalid date""" |