@@ -584,6 +584,13 @@ class`. float also has the following additional methods.
584
584
:exc: `OverflowError ` on infinities and a :exc: `ValueError ` on
585
585
NaNs.
586
586
587
+ .. note ::
588
+
589
+ The values returned by ``as_integer_ratio() `` can be huge. Attempts
590
+ to render such integers into decimal strings may bump into the
591
+ :ref: `integer string conversion length limitation
592
+ <int_max_str_digits>`.
593
+
587
594
.. method :: float.is_integer()
588
595
589
596
Return ``True `` if the float instance is finite with integral
@@ -5407,6 +5414,165 @@ types, where they are relevant. Some of these are not reported by the
5407
5414
[<class 'bool'>]
5408
5415
5409
5416
5417
+ .. _int_max_str_digits :
5418
+
5419
+ Integer string conversion length limitation
5420
+ ===========================================
5421
+
5422
+ CPython has a global limit for converting between :class: `int ` and :class: `str `
5423
+ to mitigate denial of service attacks. This limit *only * applies to decimal or
5424
+ other non-power-of-two number bases. Hexadecimal, octal, and binary conversions
5425
+ are unlimited. The limit can be configured.
5426
+
5427
+ The :class: `int ` type in CPython is an abitrary length number stored in binary
5428
+ form (commonly known as a "bignum"). There exists no algorithm that can convert
5429
+ a string to a binary integer or a binary integer to a string in linear time,
5430
+ *unless * the base is a power of 2. Even the best known algorithms for base 10
5431
+ have sub-quadratic complexity. Converting a large value such as ``int('1' *
5432
+ 500_000) `` can take over a second on a fast CPU.
5433
+
5434
+ Limiting conversion size offers a practical way to avoid `CVE-2020-10735
5435
+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735> `_.
5436
+
5437
+ The limit is applied to the number of digit characters in the input or output
5438
+ string when a non-linear conversion algorithm would be involved. Underscores
5439
+ and the sign are not counted towards the limit.
5440
+
5441
+ When an operation would exceed the limit, a :exc: `ValueError ` is raised:
5442
+
5443
+ .. doctest ::
5444
+
5445
+ >>> import sys
5446
+ >>> sys.set_int_max_str_digits(4300 ) # Illustrative, this is the default.
5447
+ >>> _ = int (' 2' * 5432 )
5448
+ Traceback (most recent call last):
5449
+ ...
5450
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits.
5451
+ >>> i = int (' 2' * 4300 )
5452
+ >>> len (str (i))
5453
+ 4300
5454
+ >>> i_squared = i* i
5455
+ >>> len (str (i_squared))
5456
+ Traceback (most recent call last):
5457
+ ...
5458
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits.
5459
+ >>> len (hex (i_squared))
5460
+ 7144
5461
+ >>> assert int (hex (i_squared), base = 16 ) == i* i # Hexadecimal is unlimited.
5462
+
5463
+ The default limit is 4300 digits as provided in
5464
+ :data: `sys.int_info.default_max_str_digits <sys.int_info> `.
5465
+ The lowest limit that can be configured is 640 digits as provided in
5466
+ :data: `sys.int_info.str_digits_check_threshold <sys.int_info> `.
5467
+
5468
+ Verification:
5469
+
5470
+ .. doctest ::
5471
+
5472
+ >>> import sys
5473
+ >>> assert sys.int_info.default_max_str_digits == 4300 , sys.int_info
5474
+ >>> assert sys.int_info.str_digits_check_threshold == 640 , sys.int_info
5475
+ >>> msg = int (' 578966293710682886880994035146873798396722250538762761564'
5476
+ ... ' 9252925514383915483333812743580549779436104706260696366600'
5477
+ ... ' 571186405732' ).to_bytes(53 , ' big' )
5478
+ ...
5479
+
5480
+ .. versionadded :: 3.10.7
5481
+
5482
+ Affected APIs
5483
+ -------------
5484
+
5485
+ The limition only applies to potentially slow conversions between :class: `int `
5486
+ and :class: `str ` or :class: `bytes `:
5487
+
5488
+ * ``int(string) `` with default base 10.
5489
+ * ``int(string, base) `` for all bases that are not a power of 2.
5490
+ * ``str(integer) ``.
5491
+ * ``repr(integer) ``
5492
+ * any other string conversion to base 10, for example ``f"{integer}" ``,
5493
+ ``"{}".format(integer) ``, or ``b"%d" % integer ``.
5494
+
5495
+ The limitations do not apply to functions with a linear algorithm:
5496
+
5497
+ * ``int(string, base) `` with base 2, 4, 8, 16, or 32.
5498
+ * :func: `int.from_bytes ` and :func: `int.to_bytes `.
5499
+ * :func: `hex `, :func: `oct `, :func: `bin `.
5500
+ * :ref: `formatspec ` for hex, octal, and binary numbers.
5501
+ * :class: `str ` to :class: `float `.
5502
+ * :class: `str ` to :class: `decimal.Decimal `.
5503
+
5504
+ Configuring the limit
5505
+ ---------------------
5506
+
5507
+ Before Python starts up you can use an environment variable or an interpreter
5508
+ command line flag to configure the limit:
5509
+
5510
+ * :envvar: `PYTHONINTMAXSTRDIGITS `, e.g.
5511
+ ``PYTHONINTMAXSTRDIGITS=640 python3 `` to set the limit to 640 or
5512
+ ``PYTHONINTMAXSTRDIGITS=0 python3 `` to disable the limitation.
5513
+ * :option: `-X int_max_str_digits <-X> `, e.g.
5514
+ ``python3 -X int_max_str_digits=640 ``
5515
+ * :data: `sys.flags.int_max_str_digits ` contains the value of
5516
+ :envvar: `PYTHONINTMAXSTRDIGITS ` or :option: `-X int_max_str_digits <-X> `.
5517
+ If both the env var and the ``-X `` option are set, the ``-X `` option takes
5518
+ precedence. A value of *-1 * indicates that both were unset, thus a value of
5519
+ :data: `sys.int_info.default_max_str_digits ` was used during initilization.
5520
+
5521
+ From code, you can inspect the current limit and set a new one using these
5522
+ :mod: `sys ` APIs:
5523
+
5524
+ * :func: `sys.get_int_max_str_digits ` and :func: `sys.set_int_max_str_digits ` are
5525
+ a getter and setter for the interpreter-wide limit. Subinterpreters have
5526
+ their own limit.
5527
+
5528
+ Information about the default and minimum can be found in :attr: `sys.int_info `:
5529
+
5530
+ * :data: `sys.int_info.default_max_str_digits <sys.int_info> ` is the compiled-in
5531
+ default limit.
5532
+ * :data: `sys.int_info.str_digits_check_threshold <sys.int_info> ` is the lowest
5533
+ accepted value for the limit (other than 0 which disables it).
5534
+
5535
+ .. versionadded :: 3.10.7
5536
+
5537
+ .. caution ::
5538
+
5539
+ Setting a low limit *can * lead to problems. While rare, code exists that
5540
+ contains integer constants in decimal in their source that exceed the
5541
+ minimum threshold. A consequence of setting the limit is that Python source
5542
+ code containing decimal integer literals longer than the limit will
5543
+ encounter an error during parsing, usually at startup time or import time or
5544
+ even at installation time - anytime an up to date ``.pyc `` does not already
5545
+ exist for the code. A workaround for source that contains such large
5546
+ constants is to convert them to ``0x `` hexadecimal form as it has no limit.
5547
+
5548
+ Test your application thoroughly if you use a low limit. Ensure your tests
5549
+ run with the limit set early via the environment or flag so that it applies
5550
+ during startup and even during any installation step that may invoke Python
5551
+ to precompile ``.py `` sources to ``.pyc `` files.
5552
+
5553
+ Recommended configuration
5554
+ -------------------------
5555
+
5556
+ The default :data: `sys.int_info.default_max_str_digits ` is expected to be
5557
+ reasonable for most applications. If your application requires a different
5558
+ limit, set it from your main entry point using Python version agnostic code as
5559
+ these APIs were added in security patch releases in versions before 3.11.
5560
+
5561
+ Example::
5562
+
5563
+ >>> import sys
5564
+ >>> if hasattr(sys, "set_int_max_str_digits"):
5565
+ ... upper_bound = 68000
5566
+ ... lower_bound = 4004
5567
+ ... current_limit = sys.get_int_max_str_digits()
5568
+ ... if current_limit == 0 or current_limit > upper_bound:
5569
+ ... sys.set_int_max_str_digits(upper_bound)
5570
+ ... elif current_limit < lower_bound:
5571
+ ... sys.set_int_max_str_digits(lower_bound)
5572
+
5573
+ If you need to disable it entirely, set it to ``0 ``.
5574
+
5575
+
5410
5576
.. rubric :: Footnotes
5411
5577
5412
5578
.. [1 ] Additional information on these special methods may be found in the Python
0 commit comments