Skip to content

Raise TypeError when a stream's read() doesn't return a string - #1641

Open
buzztouniverse wants to merge 3 commits into
dateutil:masterfrom
buzztouniverse:fix-mock-stream-loop
Open

buzztouniverse wants to merge 3 commits into
dateutil:masterfrom
buzztouniverse:fix-mock-stream-loop

Conversation

@buzztouniverse

@buzztouniverse buzztouniverse commented Oct 24, 2026 •

Copy link
Copy Markdown

Summary of changes

_timelex only checks that the input has a read attribute, so a Mock gets through. Its read() never returns '', so the tokenizer never reaches EOF and keeps growing the token until it runs out of memory.

This raises TypeError when read() returns something other than str or bytes. bytes is still accepted so a BytesIO keeps raising ParserError like before.

An earlier attempt at this was #1553, closed by its author.

Closes #1428

Pull Request Checklist

  • Changes have tests
  • Authors have been added to AUTHORS.md
  • News fragment added in changelog.d. See CONTRIBUTING.md for details

Comment thread src/dateutil/parser/_parser.py Outdated
# The check in __init__ only looks for a read attribute, so
# something like a Mock gets through, and since its read()
# never returns an empty string we would never hit EOF.
if not isinstance(nextchar, (text_type, bytes)):

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.

We dropped six

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Rebased on master and switched it to str.

Comment thread tests/test_parser.py Outdated
def test_read_not_returning_string_invalid(self):
# GH #1428: A Mock passes the duck typing check, but its read() never
# returns an empty string, so this used to loop forever
try:

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.

Do not import in the test and don't make it conditional.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Moved from unittest import mock to the top of the file.

The tokenizer only checks that its input has a read attribute, so a Mock
gets through. Its read() never returns an empty string, so parse() never
reached EOF and kept allocating memory until the process ran out.

Fixes GH dateutil#1428

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

If a mock object reaches parse() during a unit test, unbounded memory allocation occurs

2 participants