| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Expand Up | @@ -3319,32 +3319,96 @@ def test_getaddresses(self): | |||||||||||||
| [('Al Person', 'aperson@dom.ain'), | ||||||||||||||
| ('Bud Person', 'bperson@dom.ain')]) | ||||||||||||||
|
|
||||||||||||||
| def test_getaddresses_comma_in_name(self): | ||||||||||||||
| """GH-106669 regression test.""" | ||||||||||||||
| self.assertEqual( | ||||||||||||||
| utils.getaddresses( | ||||||||||||||
| [ | ||||||||||||||
| '"Bud, Person" <bperson@dom.ain>', | ||||||||||||||
| 'aperson@dom.ain (Al Person)', | ||||||||||||||
| '"Mariusz Felisiak" <to@example.com>', | ||||||||||||||
| ] | ||||||||||||||
| ), | ||||||||||||||
| [ | ||||||||||||||
| ('Bud, Person', 'bperson@dom.ain'), | ||||||||||||||
| ('Al Person', 'aperson@dom.ain'), | ||||||||||||||
| ('Mariusz Felisiak', 'to@example.com'), | ||||||||||||||
| ], | ||||||||||||||
| ) | ||||||||||||||
| def test_getaddresses_parsing_errors(self): | ||||||||||||||
| """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" | ||||||||||||||
| eq = self.assertEqual | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org(<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org)<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org<<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org><bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org@<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org,<bob@example.com>']), | ||||||||||||||
| [('', 'alice@example.org'), ('', 'bob@example.com')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org;<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org:<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org.<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org"<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org[<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses(['alice@example.org]<bob@example.com>']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
|
Comment thread
Comment on lines
+3347
to
+3348
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityHowever, not a bad idea to add extra tests. That way if someone else changes this code in the future these other corner cases will be tested for.
Sorry, something went wrong.
All reactions
|
||||||||||||||
| eq(utils.getaddresses(['"Alice, alice@example.org" <bob@example.com>']), | ||||||||||||||
| [('Alice, alice@example.org', 'bob@example.com')]) | ||||||||||||||
|
|
||||||||||||||
| def test_parseaddr_parsing_errors(self): | ||||||||||||||
| """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" | ||||||||||||||
| eq = self.assertEqual | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org(<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org)<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org<<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org><bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org@<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org,<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org;<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org:<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org.<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org"<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org[<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['alice@example.org]<bob@example.com>']), | ||||||||||||||
| ('', '')) | ||||||||||||||
| eq(utils.parseaddr(['"Alice, alice@example.org" <bob@example.com>']), | ||||||||||||||
| ('Alice, alice@example.org', 'bob@example.com')) | ||||||||||||||
|
|
||||||||||||||
| def test_getaddresses_nasty(self): | ||||||||||||||
| eq = self.assertEqual | ||||||||||||||
| eq(utils.getaddresses(['"Sürname, Firstname" <to@example.com>']), | ||||||||||||||
| [('Sürname, Firstname', 'to@example.com')]) | ||||||||||||||
| eq(utils.getaddresses(['foo: ;']), [('', '')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['[]*-- =~$']), | ||||||||||||||
| [('', ''), ('', ''), ('', '*--')]) | ||||||||||||||
| eq(utils.getaddresses(['[]*-- =~$']), [('', '')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>']), | ||||||||||||||
| [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| [r'Pete(A nice \) chap) <pete(his account)@silly.test(his host)>']), | ||||||||||||||
| [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['(Empty list)(start)Undisclosed recipients :(nobody(I know))']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['Mary <@machine.tld:mary@example.net>, , jdoe@test . example']), | ||||||||||||||
| [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['John Doe <jdoe@machine(comment). example>']), | ||||||||||||||
| [('John Doe (comment)', 'jdoe@machine.example')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['"Mary Smith: Personal Account" <smith@home.example>']), | ||||||||||||||
| [('Mary Smith: Personal Account', 'smith@home.example')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| ['Undisclosed recipients:;']), | ||||||||||||||
| [('', '')]) | ||||||||||||||
| eq(utils.getaddresses( | ||||||||||||||
| [r'<boss@nil.test>, "Giant; \"Big\" Box" <bob@example.net>']), | ||||||||||||||
| [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]) | ||||||||||||||
|
|
||||||||||||||
| def test_getaddresses_embedded_comment(self): | ||||||||||||||
| """Test proper handling of a nested comment""" | ||||||||||||||
| Expand Down Expand Up | @@ -3712,16 +3776,6 @@ def test_bytes_header_parser(self): | |||||||||||||
| self.assertIsInstance(msg.get_payload(), str) | ||||||||||||||
| self.assertIsInstance(msg.get_payload(decode=True), bytes) | ||||||||||||||
|
|
||||||||||||||
| def test_header_parser_multipart_is_valid(self): | ||||||||||||||
| # Don't flag valid multipart emails as having defects | ||||||||||||||
| with openfile('msg_47.txt', encoding="utf-8") as fp: | ||||||||||||||
| msgdata = fp.read() | ||||||||||||||
|
|
||||||||||||||
| parser = email.parser.Parser(policy=email.policy.default) | ||||||||||||||
| parsed_msg = parser.parsestr(msgdata, headersonly=True) | ||||||||||||||
|
|
||||||||||||||
| self.assertEqual(parsed_msg.defects, []) | ||||||||||||||
|
|
||||||||||||||
| def test_bytes_parser_does_not_close_file(self): | ||||||||||||||
| with openfile('msg_02.txt', 'rb') as fp: | ||||||||||||||
| email.parser.BytesParser().parse(fp) | ||||||||||||||
| Expand Down | ||||||||||||||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis does not check )( or any other combination when ) proceeds (. Probably it could be better to iterate through the string and manually increment and decrement verifying that the counter never goes below 0 and it is exactly 0 at the end
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityLooks like this is not necessary. The fix already accounts for this and none of those are an issue.
My current solution works, because instead of trying to actually parse things I just detect an error has occurred by making sure that the resulting number of address 2-Tuples matches the number of Headers that were parsed. Which is why I went this direction. It's super hard to fix the actual parsing logic of RFC 2822 headers :P
./python Python 3.13.0a0 (heads/blah_1:a1cc74c4ee, Aug 21 2023, 18:40:57) [GCC 7.5.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> from email.utils import parseaddr, getaddresses >>> >>> >>> parseaddr('alice@example.org])(<bob@example.com>') ('', '') >>> >>> parseaddr('alice@example.org)(<bob@example.com>') ('', '') >>> >>> parseaddr('alice@example.org <bob@example.com>') ('', '') >>> parseaddr('alice@example.org..<bob@example.com>') ('', '') >>> >>> getaddresses(['alice@example.org..<bob@example.com>']) [('', '')] >>> >>> getaddresses(['alice@example.org])(<bob@example.com>']) [('', '')] >>> >>> getaddresses(['alice@example.org)(<bob@example.com>']) [('', '')]With the un-patched python your attack results in multiple Tuples being returned
>>> getaddresses(['alice@example.org])(<bob@example.com>']) [('', 'alice@example.org'), ('', ''), ('', '')]A cleaner way to say it is this. There are countless ways to trigger this parsing error but there is only one error e.g. the parser will return an abnormal number of output tuples. So, rather than trying to detect every possible input which could trigger the bug, I just detect the one error that they all result in.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAfter looking at this again, it is interesting that my solution works here… why do I check for matching parentheses at all ?
blah@example.com)(<bob&@example.com
I have ideas, but I’ll look into it.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.