Skip to content

Commit f075c91

Browse files
authored
Merge branch 'main' into gh-139269
2 parents d266ac0 + e18dda9 commit f075c91

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3078
-152
lines changed

Doc/library/collections.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,11 @@ Several mathematical operations are provided for combining :class:`Counter`
367367
objects to produce multisets (counters that have counts greater than zero).
368368
Addition and subtraction combine counters by adding or subtracting the counts
369369
of corresponding elements. Intersection and union return the minimum and
370-
maximum of corresponding counts. Equality and inclusion compare
371-
corresponding counts. Each operation can accept inputs with signed
372-
counts, but the output will exclude results with counts of zero or less.
370+
maximum of corresponding counts. Symmetric difference returns the difference
371+
between the maximum and minimum of the corresponding counts. Equality and
372+
inclusion compare corresponding counts. Each operation can accept inputs
373+
with signed counts, but the output will exclude results with counts of zero
374+
or below.
373375

374376
.. doctest::
375377

@@ -383,6 +385,8 @@ counts, but the output will exclude results with counts of zero or less.
383385
Counter({'a': 1, 'b': 1})
384386
>>> c | d # union: max(c[x], d[x])
385387
Counter({'a': 3, 'b': 2})
388+
>>> c ^ d # max(c[x], d[x]) - min(c[x], d[x])
389+
Counter({'a': 2, 'b': 1})
386390
>>> c == d # equality: c[x] == d[x]
387391
False
388392
>>> c <= d # inclusion: c[x] <= d[x]
@@ -400,6 +404,9 @@ or subtracting from an empty counter.
400404
.. versionadded:: 3.3
401405
Added support for unary plus, unary minus, and in-place multiset operations.
402406

407+
.. versionadded:: next
408+
Added support for the symmetric difference multiset operation, ``c ^ d``.
409+
403410
.. note::
404411

405412
Counters were primarily designed to work with positive integers to represent

Doc/library/pyexpat.rst

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ The :mod:`xml.parsers.expat` module contains two functions:
7272
*encoding* [1]_ is given it will override the implicit or explicit encoding of the
7373
document.
7474

75+
.. _xmlparser-non-root:
76+
77+
Parsers created through :func:`!ParserCreate` are called "root" parsers,
78+
in the sense that they do not have any parent parser attached. Non-root
79+
parsers are created by :meth:`parser.ExternalEntityParserCreate
80+
<xmlparser.ExternalEntityParserCreate>`.
81+
7582
Expat can optionally do XML namespace processing for you, enabled by providing a
7683
value for *namespace_separator*. The value must be a one-character string; a
7784
:exc:`ValueError` will be raised if the string has an illegal length (``None``
@@ -231,6 +238,111 @@ XMLParser Objects
231238
.. versionadded:: 3.13
232239

233240

241+
:class:`!xmlparser` objects have the following methods to tune protections
242+
against some common XML vulnerabilities.
243+
244+
.. method:: xmlparser.SetBillionLaughsAttackProtectionActivationThreshold(threshold, /)
245+
246+
Sets the number of output bytes needed to activate protection against
247+
`billion laughs`_ attacks.
248+
249+
The number of output bytes includes amplification from entity expansion
250+
and reading DTD files.
251+
252+
Parser objects usually have a protection activation threshold of 8 MiB,
253+
but the actual default value depends on the underlying Expat library.
254+
255+
An :exc:`ExpatError` is raised if this method is called on a
256+
|xml-non-root-parser| parser.
257+
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
258+
should not be used as they may have no special meaning.
259+
260+
.. note::
261+
262+
Activation thresholds below 4 MiB are known to break support for DITA 1.3
263+
payload and are hence not recommended.
264+
265+
.. versionadded:: next
266+
267+
.. method:: xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification(max_factor, /)
268+
269+
Sets the maximum tolerated amplification factor for protection against
270+
`billion laughs`_ attacks.
271+
272+
The amplification factor is calculated as ``(direct + indirect) / direct``
273+
while parsing, where ``direct`` is the number of bytes read from
274+
the primary document in parsing and ``indirect`` is the number of
275+
bytes added by expanding entities and reading of external DTD files.
276+
277+
The *max_factor* value must be a non-NaN :class:`float` value greater than
278+
or equal to 1.0. Peak amplifications of factor 15,000 for the entire payload
279+
and of factor 30,000 in the middle of parsing have been observed with small
280+
benign files in practice. In particular, the activation threshold should be
281+
carefully chosen to avoid false positives.
282+
283+
Parser objects usually have a maximum amplification factor of 100,
284+
but the actual default value depends on the underlying Expat library.
285+
286+
An :exc:`ExpatError` is raised if this method is called on a
287+
|xml-non-root-parser| parser or if *max_factor* is outside the valid range.
288+
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
289+
should not be used as they may have no special meaning.
290+
291+
.. note::
292+
293+
The maximum amplification factor is only considered if the threshold
294+
that can be adjusted by :meth:`.SetBillionLaughsAttackProtectionActivationThreshold`
295+
is exceeded.
296+
297+
.. versionadded:: next
298+
299+
.. method:: xmlparser.SetAllocTrackerActivationThreshold(threshold, /)
300+
301+
Sets the number of allocated bytes of dynamic memory needed to activate
302+
protection against disproportionate use of RAM.
303+
304+
Parser objects usually have an allocation activation threshold of 64 MiB,
305+
but the actual default value depends on the underlying Expat library.
306+
307+
An :exc:`ExpatError` is raised if this method is called on a
308+
|xml-non-root-parser| parser.
309+
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
310+
should not be used as they may have no special meaning.
311+
312+
.. versionadded:: next
313+
314+
.. method:: xmlparser.SetAllocTrackerMaximumAmplification(max_factor, /)
315+
316+
Sets the maximum amplification factor between direct input and bytes
317+
of dynamic memory allocated.
318+
319+
The amplification factor is calculated as ``allocated / direct``
320+
while parsing, where ``direct`` is the number of bytes read from
321+
the primary document in parsing and ``allocated`` is the number
322+
of bytes of dynamic memory allocated in the parser hierarchy.
323+
324+
The *max_factor* value must be a non-NaN :class:`float` value greater than
325+
or equal to 1.0. Amplification factors greater than 100.0 can be observed
326+
near the start of parsing even with benign files in practice. In particular,
327+
the activation threshold should be carefully chosen to avoid false positives.
328+
329+
Parser objects usually have a maximum amplification factor of 100,
330+
but the actual default value depends on the underlying Expat library.
331+
332+
An :exc:`ExpatError` is raised if this method is called on a
333+
|xml-non-root-parser| parser or if *max_factor* is outside the valid range.
334+
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
335+
should not be used as they may have no special meaning.
336+
337+
.. note::
338+
339+
The maximum amplification factor is only considered if the threshold
340+
that can be adjusted by :meth:`.SetAllocTrackerActivationThreshold`
341+
is exceeded.
342+
343+
.. versionadded:: next
344+
345+
234346
:class:`xmlparser` objects have the following attributes:
235347

236348

@@ -954,3 +1066,6 @@ The ``errors`` module has the following attributes:
9541066
not. See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
9551067
and https://www.iana.org/assignments/character-sets/character-sets.xhtml.
9561068
1069+
1070+
.. _billion laughs: https://en.wikipedia.org/wiki/Billion_laughs_attack
1071+
.. |xml-non-root-parser| replace:: :ref:`non-root <xmlparser-non-root>`

Doc/library/xml.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ An attacker can abuse XML features to carry out denial of service attacks,
5555
access local files, generate network connections to other machines, or
5656
circumvent firewalls.
5757

58-
Expat versions lower that 2.6.0 may be vulnerable to "billion laughs",
58+
Expat versions lower than 2.6.0 may be vulnerable to "billion laughs",
5959
"quadratic blowup" and "large tokens". Python may be vulnerable if it uses such
6060
older versions of Expat as a system-provided library.
6161
Check :const:`!pyexpat.EXPAT_VERSION`.

Doc/using/configure.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,9 +869,9 @@ Libraries options
869869
.. versionchanged:: 3.13
870870
Default to using the installed ``mpdecimal`` library.
871871

872-
.. deprecated-removed:: 3.13 3.15
872+
.. deprecated-removed:: 3.13 3.16
873873
A copy of the ``mpdecimal`` library sources will no longer be distributed
874-
with Python 3.15.
874+
with Python 3.16.
875875

876876
.. seealso:: :option:`LIBMPDEC_CFLAGS` and :option:`LIBMPDEC_LIBS`.
877877

Doc/whatsnew/3.15.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ New modules
294294
Improved modules
295295
================
296296

297+
collections
298+
-----------
299+
300+
* Added :meth:`!collections.Counter.__xor__` and
301+
:meth:`!collections.Counter.__ixor__` to compute the symmetric difference
302+
between :class:`~collections.Counter` objects.
303+
(Contributed by Raymond Hettinger in :gh:`138682`.)
304+
297305
collections.abc
298306
---------------
299307

@@ -528,6 +536,15 @@ tarfile
528536
(Contributed by Christoph Walcher in :gh:`57911`.)
529537

530538

539+
timeit
540+
------
541+
542+
* The command-line interface now colorizes error tracebacks
543+
by default. This can be controlled with
544+
:ref:`environment variables <using-on-controlling-color>`.
545+
(Contributed by Yi Hong in :gh:`139374`.)
546+
547+
531548
types
532549
------
533550

@@ -545,6 +562,24 @@ unittest
545562
(Contributed by Garry Cairns in :gh:`134567`.)
546563

547564

565+
xml.parsers.expat
566+
-----------------
567+
568+
* Add :meth:`~xml.parsers.expat.xmlparser.SetAllocTrackerActivationThreshold`
569+
and :meth:`~xml.parsers.expat.xmlparser.SetAllocTrackerMaximumAmplification`
570+
to :ref:`xmlparser <xmlparser-objects>` objects to tune protections against
571+
disproportional amounts of dynamic memory usage from within an Expat parser.
572+
(Contributed by Bénédikt Tran in :gh:`90949`.)
573+
574+
* Add :meth:`~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionActivationThreshold`
575+
and :meth:`~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification`
576+
to :ref:`xmlparser <xmlparser-objects>` objects to tune protections against
577+
`billion laughs`_ attacks.
578+
(Contributed by Bénédikt Tran in :gh:`90949`.)
579+
580+
.. _billion laughs: https://en.wikipedia.org/wiki/Billion_laughs_attack
581+
582+
548583
zlib
549584
----
550585

0 commit comments

Comments
 (0)