@@ -521,6 +521,13 @@ class`. float also has the following additional methods.
521521
522522 .. versionadded :: 2.6
523523
524+ .. note ::
525+
526+ The values returned by ``as_integer_ratio() `` can be huge. Attempts
527+ to render such integers into decimal strings may bump into the
528+ :ref: `integer string conversion length limitation
529+ <int_max_str_digits>`.
530+
524531.. method :: float.is_integer()
525532
526533 Return ``True `` if the float instance is finite with integral
@@ -3190,6 +3197,167 @@ The following attributes are only supported by :term:`new-style class`\ es.
31903197 [<type 'bool'>]
31913198
31923199
3200+ .. _int_max_str_digits :
3201+
3202+ Integer string conversion length limitation
3203+ ===========================================
3204+
3205+ CPython has a global limit for converting between :class: `long ` and :class: `str `
3206+ or :class: `unicode ` to mitigate denial of service attacks. This limit *only * applies
3207+ to decimal or other non-power-of-two number bases. Hexadecimal, octal, and binary
3208+ conversions are unlimited. The limit can be configured.
3209+
3210+ The :class: `long ` type in CPython is an arbitrary length number stored in binary
3211+ form (commonly known as a "bignum"). There exists no algorithm that can convert
3212+ a string to a binary integer or a binary integer to a string in linear time,
3213+ *unless * the base is a power of 2. Even the best known algorithms for base 10
3214+ have sub-quadratic complexity. Converting a large value such as ``long('1' *
3215+ 500_000) `` can take over a second on a fast CPU.
3216+
3217+ Limiting conversion size offers a practical way to avoid `CVE-2020-10735
3218+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735> `_.
3219+
3220+ The limit is applied to the number of digit characters in the input or output
3221+ string when a non-linear conversion algorithm would be involved. Trailing *L*s
3222+ and the sign are not counted towards the limit.
3223+
3224+ When an operation would exceed the limit, a :exc: `ValueError ` is raised:
3225+
3226+ .. doctest ::
3227+
3228+ >>> import sys
3229+ >>> sys.set_int_max_str_digits(4300 ) # Illustrative, this is the default.
3230+ >>> _ = long (' 2' * 5432 )
3231+ Traceback (most recent call last):
3232+ ...
3233+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits.
3234+ >>> i = long (' 2' * 4300 )
3235+ >>> len (str (i))
3236+ 4300
3237+ >>> i_squared = i* i
3238+ >>> len (str (i_squared))
3239+ Traceback (most recent call last):
3240+ ...
3241+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits.
3242+ >>> len (hex (i_squared))
3243+ 7144
3244+ >>> assert long (hex (i_squared), base = 16 ) == i* i # Hexadecimal is unlimited.
3245+
3246+ The default limit is 4300 digits as provided in
3247+ :data: `sys.long_info.default_max_str_digits <sys.long_info> `.
3248+ The lowest limit that can be configured is 640 digits as provided in
3249+ :data: `sys.long_info.str_digits_check_threshold <sys.long_info> `.
3250+
3251+ Verification:
3252+
3253+ .. doctest ::
3254+
3255+ >>> import sys
3256+ >>> assert sys.int_info.default_max_str_digits == 4300 , sys.int_info
3257+ >>> assert sys.int_info.str_digits_check_threshold == 640 , sys.int_info
3258+ >>> msg = long (' 578966293710682886880994035146873798396722250538762761564'
3259+ ... ' 9252925514383915483333812743580549779436104706260696366600'
3260+ ... ' 571186405732' ).to_bytes(53 , ' big' )
3261+ ...
3262+
3263+ .. versionadded :: 2.7.18.6
3264+
3265+
3266+ Affected APIs
3267+ -------------
3268+
3269+ Because int automatically converts to long if the value is larger than
3270+ :data: `sys.maxint ` this limitation applies to potentially slow conversions
3271+ between any of :class: `int ` or :class: `long ` and :class: `str ` or :class: `unicode `:
3272+
3273+ * ``int(string) `` with default base 10.
3274+ * ``int(string, base) `` for all bases that are not a power of 2.
3275+ * ``long(string) `` with default base 10.
3276+ * ``long(string, base) `` for all bases that are not a power of 2.
3277+ * ``int(unicode) `` with default base 10.
3278+ * ``int(unicode, base) `` for all bases that are not a power of 2.
3279+ * ``long(unicode) `` with default base 10.
3280+ * ``long(unicode, base) `` for all bases that are not a power of 2.
3281+ * ``str(long) ``.
3282+ * ``repr(long) ``.
3283+ * ``unicode(long) ``.
3284+ * any other string conversion to base 10, for example ``"{}".format(long) ``.
3285+
3286+ The limitations do not apply to functions with a linear algorithm:
3287+
3288+ * ``long(string, base) `` with base 2, 4, 8, 16, or 32.
3289+ * :func: `hex `, :func: `oct `, :func: `bin `.
3290+ * :ref: `formatspec ` for hex, octal, and binary numbers.
3291+ * :class: `str ` to :class: `float `.
3292+ * :class: `str ` to :class: `decimal.Decimal `.
3293+
3294+ Configuring the limit
3295+ ---------------------
3296+
3297+ Before Python starts up you can use an environment variable to configure the limit:
3298+
3299+ * :envvar: `PYTHONINTMAXSTRDIGITS `, e.g.
3300+ ``PYTHONINTMAXSTRDIGITS=640 python `` to set the limit to 640 or
3301+ ``PYTHONINTMAXSTRDIGITS=0 python `` to disable the limitation.
3302+ * :data: `sys.flags.long_max_str_digits ` contains the value of
3303+ :envvar: `PYTHONINTMAXSTRDIGITS `. A value of *-1 * indicates that none was set,
3304+ thus a value of :data: `sys.int_info.default_max_str_digits ` was used during
3305+ initialization.
3306+
3307+ From code, you can inspect the current limit and set a new one using these
3308+ :mod: `sys ` APIs:
3309+
3310+ * :func: `sys.get_int_max_str_digits ` and :func: `sys.set_int_max_str_digits ` are
3311+ a getter and setter for the interpreter-wide limit.
3312+
3313+ Information about the default and minimum can be found in :attr: `sys.long_info `:
3314+
3315+ * :data: `sys.long_info.default_max_str_digits <sys.long_info> ` is the compiled-in
3316+ default limit.
3317+ * :data: `sys.long_info.str_digits_check_threshold <sys.long_info> ` is the lowest
3318+ accepted value for the limit (other than 0 which disables it).
3319+
3320+ .. versionadded :: 2.7.18.6
3321+
3322+ .. caution ::
3323+
3324+ Setting a low limit *can * lead to problems. While rare, code exists that
3325+ contains integer constants in decimal in their source that exceed the
3326+ minimum threshold. A consequence of setting the limit is that Python source
3327+ code containing decimal integer literals longer than the limit will
3328+ encounter an error during parsing, usually at startup time or import time or
3329+ even at installation time - anytime an up to date ``.pyc `` does not already
3330+ exist for the code. A workaround for source that contains such large
3331+ constants is to convert them to ``0x `` hexadecimal form as it has no limit.
3332+
3333+ Test your application thoroughly if you use a low limit. Ensure your tests
3334+ run with the limit set early via the environment so that it applies during
3335+ startup and even during any installation step that may invoke Python to
3336+ precompile ``.py `` sources to ``.pyc `` files.
3337+
3338+ Recommended configuration
3339+ -------------------------
3340+
3341+ The default :data: `sys.long_info.default_max_str_digits ` is expected to be
3342+ reasonable for most applications. If your application requires a different
3343+ limit, set it from your main entry point using Python version agnostic code as
3344+ these APIs were ported from the original fix in version 3.12.
3345+
3346+ Example::
3347+
3348+ >>> import sys
3349+ >>> if hasattr(sys, "set_int_max_str_digits"):
3350+ ... upper_bound = 68000
3351+ ... lower_bound = 4004
3352+ ... current_limit = sys.get_int_max_str_digits()
3353+ ... if current_limit == 0 or current_limit > upper_bound:
3354+ ... sys.set_int_max_str_digits(upper_bound)
3355+ ... elif current_limit < lower_bound:
3356+ ... sys.set_int_max_str_digits(lower_bound)
3357+
3358+ If you need to disable it entirely, set it to ``0 ``.
3359+
3360+
31933361.. rubric :: Footnotes
31943362
31953363.. [1 ] Additional information on these special methods may be found in the Python
0 commit comments