Skip to content

gh-148192: Fix Generator._make_boundary behavior with CRLF line endings.#148193

Open
henryivesjones wants to merge 3 commits intopython:mainfrom
henryivesjones:email-generator-crlf-boundary
Open

gh-148192: Fix Generator._make_boundary behavior with CRLF line endings.#148193
henryivesjones wants to merge 3 commits intopython:mainfrom
henryivesjones:email-generator-crlf-boundary

Conversation

@henryivesjones
Copy link
Copy Markdown

@henryivesjones henryivesjones commented Apr 7, 2026

The Generator._make_boundary regex does not match on boundary phrases correctly when using CRLF line endings due to re.MULTILINE not considering \r\n as a line ending.

Issue: #148192

The Generator._make_boundary regex does not match on boundary phrases correctly when using CRLF line endings due to re.MULTILINE not considering \r\n as a line ending.
@python-cla-bot
Copy link
Copy Markdown

python-cla-bot bot commented Apr 7, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

@henryivesjones
Copy link
Copy Markdown
Author

The failing test seems to just be flaky? I ran just that one test 4 times and 2 passed and 2 failed.

cpython % ./python.exe -m test -j 14 test_perf_profiler
Raised RLIMIT_NOFILE: 256 -> 1024
Using random seed: 1400475968
0:00:00 load avg: 4.26 Run 1 test in parallel using 1 worker process
0:00:00 load avg: 4.26 [1/1] test_perf_profiler passed

== Tests result: SUCCESS ==

1 test OK.

Total duration: 394 ms
Total tests: run=14 skipped=5
Total test files: run=1/1
Result: SUCCESS
cpython % ./python.exe -m test -j 14 test_perf_profiler
Raised RLIMIT_NOFILE: 256 -> 1024
Using random seed: 1646608690
0:00:00 load avg: 4.26 Run 1 test in parallel using 1 worker process
0:00:00 load avg: 4.26 [1/1/1] test_perf_profiler failed (1 failure)
test test_perf_profiler failed -- Traceback (most recent call last):
  File "/Users/hjones/git/forks/cpython/Lib/test/test_perf_profiler.py", line 145, in test_trampoline_works_with_forks
    self.assertEqual(process.returncode, 0)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 11 != 0


== Tests result: FAILURE ==

1 test failed:
    test_perf_profiler

Total duration: 393 ms
Total tests: run=14 failures=1 skipped=5
Total test files: run=1/1 failed=1
Result: FAILURE
cpython % ./python.exe -m test -j 14 test_perf_profiler
Raised RLIMIT_NOFILE: 256 -> 1024
Using random seed: 2888117323
0:00:00 load avg: 3.52 Run 1 test in parallel using 1 worker process
0:00:00 load avg: 3.52 [1/1/1] test_perf_profiler failed (1 failure)
test test_perf_profiler failed -- Traceback (most recent call last):
  File "/Users/hjones/git/forks/cpython/Lib/test/test_perf_profiler.py", line 145, in test_trampoline_works_with_forks
    self.assertEqual(process.returncode, 0)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 11 != 0


== Tests result: FAILURE ==

1 test failed:
    test_perf_profiler

Total duration: 388 ms
Total tests: run=14 failures=1 skipped=5
Total test files: run=1/1 failed=1
Result: FAILURE
cpython % ./python.exe -m test -j 14 test_perf_profiler
Raised RLIMIT_NOFILE: 256 -> 1024
Using random seed: 164762511
0:00:00 load avg: 3.52 Run 1 test in parallel using 1 worker process
0:00:00 load avg: 3.52 [1/1] test_perf_profiler passed

== Tests result: SUCCESS ==

1 test OK.

Total duration: 388 ms
Total tests: run=14 skipped=5
Total test files: run=1/1
Result: SUCCESS

msg = MIMEMultipart()
msg.attach(MIMEText(boundary_in_part))
self.genclass(self.ioclass()).flatten(msg, linesep=linesep)
# .0 is appended if the boundary was found.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be verbose and enhance this comment a bit to make things clearer. How about "Generator checks the message content for the string it is about to use as a boundary ('token' in this test) and when it finds it in our attachment appends .0 to make the boundary it uses unique."

@@ -0,0 +1,2 @@
``email.generator.Generator._make_boundary`` now correctly finds the
boundary when using CRLF linesep.
Copy link
Copy Markdown
Member

@bitdancer bitdancer Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description more about the bugfix implementation than the bug. How about "could fail to detect a duplicate boundary string if linesep was not \n. It now correctly detects boundary strings when linesep is \r\n as well."

And, having written that, it occurs to me we could have the same bug if linesep were set to something exotic. Which shouldn't be a problem in practice, but then, neither is this bug ;) I'm sure non-standard linesep would reveal lots of other bugs in the code in that regard as well, though, so let's just ignore that potential issue.

@bedevere-app
Copy link
Copy Markdown

bedevere-app bot commented Apr 11, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants