@@ -3277,6 +3277,28 @@ def test_unicode_address_raises_error(self):
32773277 self .assertRaises (UnicodeError , utils .formataddr , (None , addr ))
32783278 self .assertRaises (UnicodeError , utils .formataddr , ("Name" , addr ))
32793279
3280+ def test_crlf_in_parts_raises_error (self ):
3281+ # formataddr() must reject CR and LF in either part so that the
3282+ # returned header value cannot be used to inject extra headers,
3283+ # matching email.headerregistry.Address.
3284+ for name , addr in [
3285+ ('Real\r Name' , 'person@dom.ain' ),
3286+ ('Real\n Name' , 'person@dom.ain' ),
3287+ ('Real Name' , 'person@dom.ain\r \n Bcc: victim@dom.ain' ),
3288+ ('Real Name' , 'person@dom.ain\n Subject: spoofed' ),
3289+ ]:
3290+ with self .subTest (name = name , addr = addr ):
3291+ self .assertRaises (ValueError , utils .formataddr , (name , addr ))
3292+
3293+ def test_crlf_in_parts_allowed_when_not_strict (self ):
3294+ # strict=False keeps the old behaviour and passes CR/LF through.
3295+ self .assertEqual (
3296+ utils .formataddr (('Real\r Name' , 'person@dom.ain' ), strict = False ),
3297+ 'Real\r Name <person@dom.ain>' )
3298+ self .assertEqual (
3299+ utils .formataddr (('Real Name' , 'person@dom.ain\n foo' ), strict = False ),
3300+ 'Real Name <person@dom.ain\n foo>' )
3301+
32803302 def test_name_with_dot (self ):
32813303 x = 'John X. Doe <jxd@example.com>'
32823304 y = '"John X. Doe" <jxd@example.com>'
0 commit comments