Skip to content
New issue

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

Fix crashes with large positive and negative list multipliers #2596

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ What's New in astroid 4.0.0?
============================
Release date: TBA

* Fix crashes with large positive and negative list multipliers.

Closes #2521
Closes #2523


What's New in astroid 3.3.5?
Expand Down
5 changes: 4 additions & 1 deletion astroid/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ def _multiply_seq_by_int(
context: InferenceContext,
) -> _TupleListNodeT:
node = self.__class__(parent=opnode)
if value > 1e8:
if value <= 0:
node.elts = []
return node
if len(self.elts) * value > 1e8:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks like there are cases where the length of filtered_elts could be less than the length of self.elts.

I wasn't sure if the length check should happen before or after filtering, given that the length max is already pretty large.

node.elts = [util.Uninferable]
return node
filtered_elts = (
Expand Down
17 changes: 17 additions & 0 deletions tests/test_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,23 @@ def test_uninferable_list_multiplication() -> None:
element = parsed.inferred()[0].elts[0]
assert element.value is Uninferable

@staticmethod
def test_uninferable_list_multiplication_with_multiple_operands() -> None:
"""Attempting to calculate the result is prohibitively expensive."""
parsed = extract_node("[0] * 825 * 16547118")
element = parsed.inferred()[0].elts[0]
assert element.value is Uninferable

@staticmethod
def test_list_multiplication_with_zero_multiplier() -> None:
parsed = extract_node("[0] * 0")
assert parsed.inferred()[0].elts == []

@staticmethod
def test_list_multiplication_with_negative_multiplier() -> None:
parsed = extract_node("[0] * -9223372036854775809")
assert parsed.inferred()[0].elts == []


def test_named_expr_inference() -> None:
code = """
Expand Down
Loading