@@ -4741,6 +4741,165 @@ types, where they are relevant. Some of these are not reported by the
4741
4741
[<class 'bool'>]
4742
4742
4743
4743
4744
+ .. _int_max_str_digits :
4745
+
4746
+ Integer string conversion length limitation
4747
+ ===========================================
4748
+
4749
+ CPython has a global limit for converting between :class: `int ` and :class: `str `
4750
+ to mitigate denial of service attacks. This limit *only * applies to decimal or
4751
+ other non-power-of-two number bases. Hexadecimal, octal, and binary conversions
4752
+ are unlimited. The limit can be configured.
4753
+
4754
+ The :class: `int ` type in CPython is an abitrary length number stored in binary
4755
+ form (commonly known as a "bignum"). There exists no algorithm that can convert
4756
+ a string to a binary integer or a binary integer to a string in linear time,
4757
+ *unless * the base is a power of 2. Even the best known algorithms for base 10
4758
+ have sub-quadratic complexity. Converting a large value such as ``int('1' *
4759
+ 500_000) `` can take over a second on a fast CPU.
4760
+
4761
+ Limiting conversion size offers a practical way to avoid `CVE-2020-10735
4762
+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735> `_.
4763
+
4764
+ The limit is applied to the number of digit characters in the input or output
4765
+ string when a non-linear conversion algorithm would be involved. Underscores
4766
+ and the sign are not counted towards the limit.
4767
+
4768
+ When an operation would exceed the limit, a :exc: `ValueError ` is raised:
4769
+
4770
+ .. doctest ::
4771
+
4772
+ >>> import sys
4773
+ >>> sys.set_int_max_str_digits(4300 ) # Illustrative, this is the default.
4774
+ >>> _ = int (' 2' * 5432 )
4775
+ Traceback (most recent call last):
4776
+ ...
4777
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits.
4778
+ >>> i = int (' 2' * 4300 )
4779
+ >>> len (str (i))
4780
+ 4300
4781
+ >>> i_squared = i* i
4782
+ >>> len (str (i_squared))
4783
+ Traceback (most recent call last):
4784
+ ...
4785
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits.
4786
+ >>> len (hex (i_squared))
4787
+ 7144
4788
+ >>> assert int (hex (i_squared), base = 16 ) == i* i # Hexadecimal is unlimited.
4789
+
4790
+ The default limit is 4300 digits as provided in
4791
+ :data: `sys.int_info.default_max_str_digits <sys.int_info> `.
4792
+ The lowest limit that can be configured is 640 digits as provided in
4793
+ :data: `sys.int_info.str_digits_check_threshold <sys.int_info> `.
4794
+
4795
+ Verification:
4796
+
4797
+ .. doctest ::
4798
+
4799
+ >>> import sys
4800
+ >>> assert sys.int_info.default_max_str_digits == 4300 , sys.int_info
4801
+ >>> assert sys.int_info.str_digits_check_threshold == 640 , sys.int_info
4802
+ >>> msg = int (' 578966293710682886880994035146873798396722250538762761564'
4803
+ ... ' 9252925514383915483333812743580549779436104706260696366600'
4804
+ ... ' 571186405732' ).to_bytes(53 , ' big' )
4805
+ ...
4806
+
4807
+ .. versionadded :: 3.7.14
4808
+
4809
+ Affected APIs
4810
+ -------------
4811
+
4812
+ The limitation only applies to potentially slow conversions between :class: `int `
4813
+ and :class: `str ` or :class: `bytes `:
4814
+
4815
+ * ``int(string) `` with default base 10.
4816
+ * ``int(string, base) `` for all bases that are not a power of 2.
4817
+ * ``str(integer) ``.
4818
+ * ``repr(integer) ``
4819
+ * any other string conversion to base 10, for example ``f"{integer}" ``,
4820
+ ``"{}".format(integer) ``, or ``b"%d" % integer ``.
4821
+
4822
+ The limitations do not apply to functions with a linear algorithm:
4823
+
4824
+ * ``int(string, base) `` with base 2, 4, 8, 16, or 32.
4825
+ * :func: `int.from_bytes ` and :func: `int.to_bytes `.
4826
+ * :func: `hex `, :func: `oct `, :func: `bin `.
4827
+ * :ref: `formatspec ` for hex, octal, and binary numbers.
4828
+ * :class: `str ` to :class: `float `.
4829
+ * :class: `str ` to :class: `decimal.Decimal `.
4830
+
4831
+ Configuring the limit
4832
+ ---------------------
4833
+
4834
+ Before Python starts up you can use an environment variable or an interpreter
4835
+ command line flag to configure the limit:
4836
+
4837
+ * :envvar: `PYTHONINTMAXSTRDIGITS `, e.g.
4838
+ ``PYTHONINTMAXSTRDIGITS=640 python3 `` to set the limit to 640 or
4839
+ ``PYTHONINTMAXSTRDIGITS=0 python3 `` to disable the limitation.
4840
+ * :option: `-X int_max_str_digits <-X> `, e.g.
4841
+ ``python3 -X int_max_str_digits=640 ``
4842
+ * :data: `sys.flags.int_max_str_digits ` contains the value of
4843
+ :envvar: `PYTHONINTMAXSTRDIGITS ` or :option: `-X int_max_str_digits <-X> `.
4844
+ If both the env var and the ``-X `` option are set, the ``-X `` option takes
4845
+ precedence. A value of *-1 * indicates that both were unset, thus a value of
4846
+ :data: `sys.int_info.default_max_str_digits ` was used during initilization.
4847
+
4848
+ From code, you can inspect the current limit and set a new one using these
4849
+ :mod: `sys ` APIs:
4850
+
4851
+ * :func: `sys.get_int_max_str_digits ` and :func: `sys.set_int_max_str_digits ` are
4852
+ a getter and setter for the interpreter-wide limit. Subinterpreters have
4853
+ their own limit.
4854
+
4855
+ Information about the default and minimum can be found in :attr: `sys.int_info `:
4856
+
4857
+ * :data: `sys.int_info.default_max_str_digits <sys.int_info> ` is the compiled-in
4858
+ default limit.
4859
+ * :data: `sys.int_info.str_digits_check_threshold <sys.int_info> ` is the lowest
4860
+ accepted value for the limit (other than 0 which disables it).
4861
+
4862
+ .. versionadded :: 3.7.14
4863
+
4864
+ .. caution ::
4865
+
4866
+ Setting a low limit *can * lead to problems. While rare, code exists that
4867
+ contains integer constants in decimal in their source that exceed the
4868
+ minimum threshold. A consequence of setting the limit is that Python source
4869
+ code containing decimal integer literals longer than the limit will
4870
+ encounter an error during parsing, usually at startup time or import time or
4871
+ even at installation time - anytime an up to date ``.pyc `` does not already
4872
+ exist for the code. A workaround for source that contains such large
4873
+ constants is to convert them to ``0x `` hexadecimal form as it has no limit.
4874
+
4875
+ Test your application thoroughly if you use a low limit. Ensure your tests
4876
+ run with the limit set early via the environment or flag so that it applies
4877
+ during startup and even during any installation step that may invoke Python
4878
+ to precompile ``.py `` sources to ``.pyc `` files.
4879
+
4880
+ Recommended configuration
4881
+ -------------------------
4882
+
4883
+ The default :data: `sys.int_info.default_max_str_digits ` is expected to be
4884
+ reasonable for most applications. If your application requires a different
4885
+ limit, set it from your main entry point using Python version agnostic code as
4886
+ these APIs were added in security patch releases in versions before 3.11.
4887
+
4888
+ Example::
4889
+
4890
+ >>> import sys
4891
+ >>> if hasattr(sys, "set_int_max_str_digits"):
4892
+ ... upper_bound = 68000
4893
+ ... lower_bound = 4004
4894
+ ... current_limit = sys.get_int_max_str_digits()
4895
+ ... if current_limit == 0 or current_limit > upper_bound:
4896
+ ... sys.set_int_max_str_digits(upper_bound)
4897
+ ... elif current_limit < lower_bound:
4898
+ ... sys.set_int_max_str_digits(lower_bound)
4899
+
4900
+ If you need to disable it entirely, set it to ``0 ``.
4901
+
4902
+
4744
4903
.. rubric :: Footnotes
4745
4904
4746
4905
.. [1 ] Additional information on these special methods may be found in the Python
0 commit comments