python / python/mypy

Overflow errors in `constant_fold_binary_float_op` and `constant_fold_binary_int_op`

Open
#17,008 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

crash
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Hello mypy team,

I am working as part of a research team developing a code analysis tool for Python. One of the issues the tool discovered in mypy's codebase is that there is potential for uncaught OverflowErrors to be thrown in both constant_fold_binary_float_op and constant_fold_binary_int_op. The cause of these errors is mypy attempting to evaluate constant expressions in python files with extremely large integer constants.

Having extremely large integer constants in Python source code is probably unlikely, but could be more likely in situations where Python programs are getting generated programmatically, and such a crash causes a bad user experience, which leads us to believe that this is an error worth fixing.

If you are interested in learning more about the tool and how it found this issue, let me know down in the comments, or you can contact me at xifaras.s@northeastern.edu. If you find that this issue is not legitimate, I would be interested in understanding why.

If you find that this is a legitimate issue worth fixing, I am happy to submit a pull request with a fix!

Thank you for your consideration!

-Sam

Crash Report

For constant_fold_binary_float_op:
This occurs for the +, -, *, /, //, and % cases (it looks like the ** case accounts for OverflowError already).
When one of the binary operands is a float, using a sufficiently large integer for the other operand triggers an overflow error when attempting to convert that integer into a float. repro1.py, attached, reproduces an example of a crash.

For constant_fold_binary_int_op:
An error occurs for the left shift << and float division / cases. The OverflowError for the left shift << is caused when the second operand is extremely large, causing a "too many digits in integer" error. The OverflowError for the float division is caused when the result of the division would be too large to store in a float, as in the case of an extremely large int divided by a small one. repro2.py and repro3.py, attached, reproduce these crashes.

Traceback

For constant_fold_binary_float_op:

repro.py:7: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.8.0
Traceback (most recent call last):
  File "mypy/semanal.py", line 6539, in accept
  File "mypy/nodes.py", line 1310, in accept
  File "mypy/semanal.py", line 2889, in visit_assignment_stmt
  File "mypy/semanal.py", line 3425, in process_type_annotation
  File "mypy/semanal.py", line 3452, in analyze_simple_literal_type
  File "mypy/constant_fold.py", line 71, in constant_fold_expr
  File "mypy/constant_fold.py", line 91, in constant_fold_binary_op
  File "mypy/constant_fold.py", line 160, in constant_fold_binary_float_op
OverflowError: int too large to convert to float
repro.py:7: : note: use --pdb to drop into pdb

For constant_fold_binary_int_op:
For left shift:

repro.py:7: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.8.0
Traceback (most recent call last):
  File "mypy/semanal.py", line 6539, in accept
  File "mypy/nodes.py", line 1310, in accept
  File "mypy/semanal.py", line 2889, in visit_assignment_stmt
  File "mypy/semanal.py", line 3425, in process_type_annotation
  File "mypy/semanal.py", line 3452, in analyze_simple_literal_type
  File "mypy/constant_fold.py", line 71, in constant_fold_expr
  File "mypy/constant_fold.py", line 83, in constant_fold_binary_op
  File "mypy/constant_fold.py", line 138, in constant_fold_binary_int_op
OverflowError: too many digits in integer
repro.py:7: : note: use --pdb to drop into pdb

For float division:

repro2.py:7: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.8.0
Traceback (most recent call last):
  File "mypy/semanal.py", line 6539, in accept
  File "mypy/nodes.py", line 1310, in accept
  File "mypy/semanal.py", line 2889, in visit_assignment_stmt
  File "mypy/semanal.py", line 3425, in process_type_annotation
  File "mypy/semanal.py", line 3452, in analyze_simple_literal_type
  File "mypy/constant_fold.py", line 71, in constant_fold_expr
  File "mypy/constant_fold.py", line 83, in constant_fold_binary_op
  File "mypy/constant_fold.py", line 123, in constant_fold_binary_int_op
OverflowError: integer division result too large for a float
repro2.py:7: : note: use --pdb to drop into pdb

To Reproduce

See attached repro1.py for an example of the constant_fold_binary_float_op error which occurs in multiple branches,
and repro2.py/repro3.py for the two constant_fold_binary_int_op errors.

Simply run mypy on these files to reproduce the crashes.

repro1.py.txt
repro2.py.txt
repro3.py.txt
(github wouldn't allow python files so I added .txt extensions)

Your Environment

  • Mypy version used: 1.8.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): default configuration
  • Python version used: 3.8.3
  • Operating system and version: macos Big Sur 11.7.10

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mypy/constant_fold.py at constant_fold_binary_float_op and constant_fold_binary_int_op, then run mypy on the attached repro1.py, repro2.py, and repro3.py files. Done means these extremely large constant expressions no longer cause mypy to terminate with an OverflowError or INTERNAL ERROR.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.