@@ -4354,6 +4354,165 @@ types, where they are relevant. Some of these are not reported by the
43544354 [<class 'bool'>]
43554355
43564356
4357+ .. _int_max_str_digits :
4358+
4359+ Integer string conversion length limitation
4360+ ===========================================
4361+
4362+ CPython has a global limit for converting between :class: `int ` and :class: `str `
4363+ to mitigate denial of service attacks. This limit *only * applies to decimal or
4364+ other non-power-of-two number bases. Hexadecimal, octal, and binary conversions
4365+ are unlimited. The limit can be configured.
4366+
4367+ The :class: `int ` type in CPython is an abitrary length number stored in binary
4368+ form (commonly known as a "bignum"). There exists no algorithm that can convert
4369+ a string to a binary integer or a binary integer to a string in linear time,
4370+ *unless * the base is a power of 2. Even the best known algorithms for base 10
4371+ have sub-quadratic complexity. Converting a large value such as ``int('1' *
4372+ 500_000) `` can take over a second on a fast CPU.
4373+
4374+ Limiting conversion size offers a practical way to avoid `CVE-2020-10735
4375+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735> `_.
4376+
4377+ The limit is applied to the number of digit characters in the input or output
4378+ string when a non-linear conversion algorithm would be involved. Underscores
4379+ and the sign are not counted towards the limit.
4380+
4381+ When an operation would exceed the limit, a :exc: `ValueError ` is raised:
4382+
4383+ .. doctest ::
4384+
4385+ >>> import sys
4386+ >>> sys.set_int_max_str_digits(4300 ) # Illustrative, this is the default.
4387+ >>> _ = int (' 2' * 5432 )
4388+ Traceback (most recent call last):
4389+ ...
4390+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit.
4391+ >>> i = int (' 2' * 4300 )
4392+ >>> len (str (i))
4393+ 4300
4394+ >>> i_squared = i* i
4395+ >>> len (str (i_squared))
4396+ Traceback (most recent call last):
4397+ ...
4398+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits; use sys.set_int_max_str_digits() to increase the limit.
4399+ >>> len (hex (i_squared))
4400+ 7144
4401+ >>> assert int (hex (i_squared), base = 16 ) == i* i # Hexadecimal is unlimited.
4402+
4403+ The default limit is 4300 digits as provided in
4404+ :data: `sys.int_info.default_max_str_digits <sys.int_info> `.
4405+ The lowest limit that can be configured is 640 digits as provided in
4406+ :data: `sys.int_info.str_digits_check_threshold <sys.int_info> `.
4407+
4408+ Verification:
4409+
4410+ .. doctest ::
4411+
4412+ >>> import sys
4413+ >>> assert sys.int_info.default_max_str_digits == 4300 , sys.int_info
4414+ >>> assert sys.int_info.str_digits_check_threshold == 640 , sys.int_info
4415+ >>> msg = int (' 578966293710682886880994035146873798396722250538762761564'
4416+ ... ' 9252925514383915483333812743580549779436104706260696366600'
4417+ ... ' 571186405732' ).to_bytes(53 , ' big' )
4418+ ...
4419+
4420+ .. versionadded :: 3.6.15-13
4421+
4422+ Affected APIs
4423+ -------------
4424+
4425+ The limitation only applies to potentially slow conversions between :class: `int `
4426+ and :class: `str ` or :class: `bytes `:
4427+
4428+ * ``int(string) `` with default base 10.
4429+ * ``int(string, base) `` for all bases that are not a power of 2.
4430+ * ``str(integer) ``.
4431+ * ``repr(integer) ``
4432+ * any other string conversion to base 10, for example ``f"{integer}" ``,
4433+ ``"{}".format(integer) ``, or ``b"%d" % integer ``.
4434+
4435+ The limitations do not apply to functions with a linear algorithm:
4436+
4437+ * ``int(string, base) `` with base 2, 4, 8, 16, or 32.
4438+ * :func: `int.from_bytes ` and :func: `int.to_bytes `.
4439+ * :func: `hex `, :func: `oct `, :func: `bin `.
4440+ * :ref: `formatspec ` for hex, octal, and binary numbers.
4441+ * :class: `str ` to :class: `float `.
4442+ * :class: `str ` to :class: `decimal.Decimal `.
4443+
4444+ Configuring the limit
4445+ ---------------------
4446+
4447+ Before Python starts up you can use an environment variable or an interpreter
4448+ command line flag to configure the limit:
4449+
4450+ * :envvar: `PYTHONINTMAXSTRDIGITS `, e.g.
4451+ ``PYTHONINTMAXSTRDIGITS=640 python3 `` to set the limit to 640 or
4452+ ``PYTHONINTMAXSTRDIGITS=0 python3 `` to disable the limitation.
4453+ * :option: `-X int_max_str_digits <-X> `, e.g.
4454+ ``python3 -X int_max_str_digits=640 ``
4455+ * :data: `sys.flags.int_max_str_digits ` contains the value of
4456+ :envvar: `PYTHONINTMAXSTRDIGITS ` or :option: `-X int_max_str_digits <-X> `.
4457+ If both the env var and the ``-X `` option are set, the ``-X `` option takes
4458+ precedence. A value of *-1 * indicates that both were unset, thus a value of
4459+ :data: `sys.int_info.default_max_str_digits ` was used during initilization.
4460+
4461+ From code, you can inspect the current limit and set a new one using these
4462+ :mod: `sys ` APIs:
4463+
4464+ * :func: `sys.get_int_max_str_digits ` and :func: `sys.set_int_max_str_digits ` are
4465+ a getter and setter for the interpreter-wide limit. Subinterpreters have
4466+ their own limit.
4467+
4468+ Information about the default and minimum can be found in :attr: `sys.int_info `:
4469+
4470+ * :data: `sys.int_info.default_max_str_digits <sys.int_info> ` is the compiled-in
4471+ default limit.
4472+ * :data: `sys.int_info.str_digits_check_threshold <sys.int_info> ` is the lowest
4473+ accepted value for the limit (other than 0 which disables it).
4474+
4475+ .. versionadded :: 3.6.15-13
4476+
4477+ .. caution ::
4478+
4479+ Setting a low limit *can * lead to problems. While rare, code exists that
4480+ contains integer constants in decimal in their source that exceed the
4481+ minimum threshold. A consequence of setting the limit is that Python source
4482+ code containing decimal integer literals longer than the limit will
4483+ encounter an error during parsing, usually at startup time or import time or
4484+ even at installation time - anytime an up to date ``.pyc `` does not already
4485+ exist for the code. A workaround for source that contains such large
4486+ constants is to convert them to ``0x `` hexadecimal form as it has no limit.
4487+
4488+ Test your application thoroughly if you use a low limit. Ensure your tests
4489+ run with the limit set early via the environment or flag so that it applies
4490+ during startup and even during any installation step that may invoke Python
4491+ to precompile ``.py `` sources to ``.pyc `` files.
4492+
4493+ Recommended configuration
4494+ -------------------------
4495+
4496+ The default :data: `sys.int_info.default_max_str_digits ` is expected to be
4497+ reasonable for most applications. If your application requires a different
4498+ limit, set it from your main entry point using Python version agnostic code as
4499+ these APIs were added in security patch releases in versions before 3.11.
4500+
4501+ Example::
4502+
4503+ >>> import sys
4504+ >>> if hasattr(sys, "set_int_max_str_digits"):
4505+ ... upper_bound = 68000
4506+ ... lower_bound = 4004
4507+ ... current_limit = sys.get_int_max_str_digits()
4508+ ... if current_limit == 0 or current_limit > upper_bound:
4509+ ... sys.set_int_max_str_digits(upper_bound)
4510+ ... elif current_limit < lower_bound:
4511+ ... sys.set_int_max_str_digits(lower_bound)
4512+
4513+ If you need to disable it entirely, set it to ``0 ``.
4514+
4515+
43574516.. rubric :: Footnotes
43584517
43594518.. [1 ] Additional information on these special methods may be found in the Python
0 commit comments