@@ -622,6 +622,13 @@ class`. float also has the following additional methods.
622622 :exc: `OverflowError ` on infinities and a :exc: `ValueError ` on
623623 NaNs.
624624
625+ .. note ::
626+
627+ The values returned by ``as_integer_ratio() `` can be huge. Attempts
628+ to render such integers into decimal strings may bump into the
629+ :ref: `integer string conversion length limitation
630+ <int_max_str_digits>`.
631+
625632.. method :: float.is_integer()
626633
627634 Return ``True `` if the float instance is finite with integral
@@ -5460,6 +5467,165 @@ types, where they are relevant. Some of these are not reported by the
54605467 [<class 'bool'>]
54615468
54625469
5470+ .. _int_max_str_digits :
5471+
5472+ Integer string conversion length limitation
5473+ ===========================================
5474+
5475+ CPython has a global limit for converting between :class: `int ` and :class: `str `
5476+ to mitigate denial of service attacks. This limit *only * applies to decimal or
5477+ other non-power-of-two number bases. Hexadecimal, octal, and binary conversions
5478+ are unlimited. The limit can be configured.
5479+
5480+ The :class: `int ` type in CPython is an abitrary length number stored in binary
5481+ form (commonly known as a "bignum"). There exists no algorithm that can convert
5482+ a string to a binary integer or a binary integer to a string in linear time,
5483+ *unless * the base is a power of 2. Even the best known algorithms for base 10
5484+ have sub-quadratic complexity. Converting a large value such as ``int('1' *
5485+ 500_000) `` can take over a second on a fast CPU.
5486+
5487+ Limiting conversion size offers a practical way to avoid `CVE-2020-10735
5488+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735> `_.
5489+
5490+ The limit is applied to the number of digit characters in the input or output
5491+ string when a non-linear conversion algorithm would be involved. Underscores
5492+ and the sign are not counted towards the limit.
5493+
5494+ When an operation would exceed the limit, a :exc: `ValueError ` is raised:
5495+
5496+ .. doctest ::
5497+
5498+ >>> import sys
5499+ >>> sys.set_int_max_str_digits(4300 ) # Illustrative, this is the default.
5500+ >>> _ = int (' 2' * 5432 )
5501+ Traceback (most recent call last):
5502+ ...
5503+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits.
5504+ >>> i = int (' 2' * 4300 )
5505+ >>> len (str (i))
5506+ 4300
5507+ >>> i_squared = i* i
5508+ >>> len (str (i_squared))
5509+ Traceback (most recent call last):
5510+ ...
5511+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits.
5512+ >>> len (hex (i_squared))
5513+ 7144
5514+ >>> assert int (hex (i_squared), base = 16 ) == i* i # Hexadecimal is unlimited.
5515+
5516+ The default limit is 4300 digits as provided in
5517+ :data: `sys.int_info.default_max_str_digits <sys.int_info> `.
5518+ The lowest limit that can be configured is 640 digits as provided in
5519+ :data: `sys.int_info.str_digits_check_threshold <sys.int_info> `.
5520+
5521+ Verification:
5522+
5523+ .. doctest ::
5524+
5525+ >>> import sys
5526+ >>> assert sys.int_info.default_max_str_digits == 4300 , sys.int_info
5527+ >>> assert sys.int_info.str_digits_check_threshold == 640 , sys.int_info
5528+ >>> msg = int (' 578966293710682886880994035146873798396722250538762761564'
5529+ ... ' 9252925514383915483333812743580549779436104706260696366600'
5530+ ... ' 571186405732' ).to_bytes(53 , ' big' )
5531+ ...
5532+
5533+ .. versionadded :: 3.12
5534+
5535+ Affected APIs
5536+ -------------
5537+
5538+ The limition only applies to potentially slow conversions between :class: `int `
5539+ and :class: `str ` or :class: `bytes `:
5540+
5541+ * ``int(string) `` with default base 10.
5542+ * ``int(string, base) `` for all bases that are not a power of 2.
5543+ * ``str(integer) ``.
5544+ * ``repr(integer) ``
5545+ * any other string conversion to base 10, for example ``f"{integer}" ``,
5546+ ``"{}".format(integer) ``, or ``b"%d" % integer ``.
5547+
5548+ The limitations do not apply to functions with a linear algorithm:
5549+
5550+ * ``int(string, base) `` with base 2, 4, 8, 16, or 32.
5551+ * :func: `int.from_bytes ` and :func: `int.to_bytes `.
5552+ * :func: `hex `, :func: `oct `, :func: `bin `.
5553+ * :ref: `formatspec ` for hex, octal, and binary numbers.
5554+ * :class: `str ` to :class: `float `.
5555+ * :class: `str ` to :class: `decimal.Decimal `.
5556+
5557+ Configuring the limit
5558+ ---------------------
5559+
5560+ Before Python starts up you can use an environment variable or an interpreter
5561+ command line flag to configure the limit:
5562+
5563+ * :envvar: `PYTHONINTMAXSTRDIGITS `, e.g.
5564+ ``PYTHONINTMAXSTRDIGITS=640 python3 `` to set the limit to 640 or
5565+ ``PYTHONINTMAXSTRDIGITS=0 python3 `` to disable the limitation.
5566+ * :option: `-X int_max_str_digits <-X> `, e.g.
5567+ ``python3 -X int_max_str_digits=640 ``
5568+ * :data: `sys.flags.int_max_str_digits ` contains the value of
5569+ :envvar: `PYTHONINTMAXSTRDIGITS ` or :option: `-X int_max_str_digits <-X> `.
5570+ If both the env var and the ``-X `` option are set, the ``-X `` option takes
5571+ precedence. A value of *-1 * indicates that both were unset, thus a value of
5572+ :data: `sys.int_info.default_max_str_digits ` was used during initilization.
5573+
5574+ From code, you can inspect the current limit and set a new one using these
5575+ :mod: `sys ` APIs:
5576+
5577+ * :func: `sys.get_int_max_str_digits ` and :func: `sys.set_int_max_str_digits ` are
5578+ a getter and setter for the interpreter-wide limit. Subinterpreters have
5579+ their own limit.
5580+
5581+ Information about the default and minimum can be found in :attr: `sys.int_info `:
5582+
5583+ * :data: `sys.int_info.default_max_str_digits <sys.int_info> ` is the compiled-in
5584+ default limit.
5585+ * :data: `sys.int_info.str_digits_check_threshold <sys.int_info> ` is the lowest
5586+ accepted value for the limit (other than 0 which disables it).
5587+
5588+ .. versionadded :: 3.12
5589+
5590+ .. caution ::
5591+
5592+ Setting a low limit *can * lead to problems. While rare, code exists that
5593+ contains integer constants in decimal in their source that exceed the
5594+ minimum threshold. A consequence of setting the limit is that Python source
5595+ code containing decimal integer literals longer than the limit will
5596+ encounter an error during parsing, usually at startup time or import time or
5597+ even at installation time - anytime an up to date ``.pyc `` does not already
5598+ exist for the code. A workaround for source that contains such large
5599+ constants is to convert them to ``0x `` hexadecimal form as it has no limit.
5600+
5601+ Test your application thoroughly if you use a low limit. Ensure your tests
5602+ run with the limit set early via the environment or flag so that it applies
5603+ during startup and even during any installation step that may invoke Python
5604+ to precompile ``.py `` sources to ``.pyc `` files.
5605+
5606+ Recommended configuration
5607+ -------------------------
5608+
5609+ The default :data: `sys.int_info.default_max_str_digits ` is expected to be
5610+ reasonable for most applications. If your application requires a different
5611+ limit, set it from your main entry point using Python version agnostic code as
5612+ these APIs were added in security patch releases in versions before 3.12.
5613+
5614+ Example::
5615+
5616+ >>> import sys
5617+ >>> if hasattr(sys, "set_int_max_str_digits"):
5618+ ... upper_bound = 68000
5619+ ... lower_bound = 4004
5620+ ... current_limit = sys.get_int_max_str_digits()
5621+ ... if current_limit == 0 or current_limit > upper_bound:
5622+ ... sys.set_int_max_str_digits(upper_bound)
5623+ ... elif current_limit < lower_bound:
5624+ ... sys.set_int_max_str_digits(lower_bound)
5625+
5626+ If you need to disable it entirely, set it to ``0 ``.
5627+
5628+
54635629.. rubric :: Footnotes
54645630
54655631.. [1 ] Additional information on these special methods may be found in the Python
0 commit comments