Skip to content

Commit bf79ecf

Browse files
authored
Merge branch 'main' into issue-152631
2 parents 725b037 + bb7e16a commit bf79ecf

16 files changed

Lines changed: 77 additions & 37 deletions

‎Doc/library/email.charset.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ new entries to the global character set, alias, and codec registries:
183183

184184
Optional *output_charset* is the character set that the output should be in.
185185
Conversions will proceed from input charset, to Unicode, to the output charset
186-
when the method :meth:`Charset.convert` is called. The default is to output in
187-
the same character set as the input.
186+
when the method :meth:`Charset.body_encode` is called. The default is to
187+
output in the same character set as the input.
188188

189189
Both *input_charset* and *output_charset* must have Unicode codec entries in the
190190
module's character set-to-codec mapping; use :func:`add_codec` to add codecs the

‎Doc/library/email.parser.rst‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ methods.
4848
FeedParser API
4949
^^^^^^^^^^^^^^
5050

51-
The :class:`BytesFeedParser`, imported from the :mod:`email.feedparser` module,
51+
The :class:`BytesFeedParser`, imported from the :mod:`!email.feedparser` module,
5252
provides an API that is conducive to incremental parsing of email messages,
5353
such as would be necessary when reading the text of an email message from a
5454
source that can block (such as a socket). The :class:`BytesFeedParser` can of
@@ -86,7 +86,7 @@ Here is the API for the :class:`BytesFeedParser`:
8686
more information on what else *policy* controls, see the
8787
:mod:`~email.policy` documentation.
8888

89-
Note: **The policy keyword should always be specified**; The default will
89+
Note: **The policy keyword should always be specified**. The default will
9090
change to :data:`email.policy.default` in a future version of Python.
9191

9292
.. versionadded:: 3.2
@@ -142,7 +142,7 @@ message body, instead setting the payload to the raw body.
142142
arguments have the same meaning and semantics as the *_factory*
143143
and *policy* arguments of :class:`BytesFeedParser`.
144144

145-
Note: **The policy keyword should always be specified**; The default will
145+
Note: **The policy keyword should always be specified**. The default will
146146
change to :data:`email.policy.default` in a future version of Python.
147147

148148
.. versionchanged:: 3.3

‎Doc/tools/.nitignore‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
Doc/library/ast.rst
66
Doc/library/asyncio-extending.rst
7-
Doc/library/email.charset.rst
8-
Doc/library/email.parser.rst
97
Doc/library/logging.config.rst
108
Doc/library/logging.handlers.rst
119
Doc/library/multiprocessing.rst

‎Include/internal/pycore_pyerrors.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ extern int _PyErr_CheckSignalsTstate(PyThreadState *tstate);
186186
extern void _Py_DumpExtensionModules(int fd, PyInterpreterState *interp);
187187
// Exported for external JIT support
188188
PyAPI_FUNC(PyObject *) _Py_CalculateSuggestions(PyObject *dir, PyObject *name);
189-
extern PyObject* _Py_Offer_Suggestions(PyObject* exception);
190189

191190
// Export for '_testinternalcapi' shared extension
192191
PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b,

‎Lib/email/charset.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def add_charset(charset, header_enc=None, body_enc=None, output_charset=None):
151151
152152
Optional output_charset is the character set that the output should be
153153
in. Conversions will proceed from input charset, to Unicode, to the
154-
output charset when the method Charset.convert() is called. The default
154+
output charset when the method Charset.body_encode() is called. The default
155155
is to output in the same character set as the input.
156156
157157
Both input_charset and output_charset must have Unicode codec entries in

‎Lib/gettext.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ def _parse(self, fp):
362362
self.plural = lambda n: int(n != 1) # germanic plural by default
363363
buf = fp.read()
364364
buflen = len(buf)
365+
if buflen < 20:
366+
raise OSError(0, 'File is corrupt', filename)
365367
# Are we big endian or little endian?
366368
magic = unpack('<I', buf[:4])[0]
367369
if magic == self.LE_MAGIC:
@@ -378,6 +380,11 @@ def _parse(self, fp):
378380
if major_version not in self.VERSIONS:
379381
raise OSError(0, 'Bad version number ' + str(major_version), filename)
380382

383+
# The seek tables must lie within the file.
384+
if (masteridx + 8 * msgcount > buflen
385+
or transidx + 8 * msgcount > buflen):
386+
raise OSError(0, 'File is corrupt', filename)
387+
381388
# Now put all messages from the .mo file buffer into the catalog
382389
# dictionary.
383390
for i in range(0, msgcount):

‎Lib/test/test_ast/test_ast.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ def test_AST_objects(self):
103103
# "ast.AST constructor takes 0 positional arguments"
104104
ast.AST(2)
105105

106+
@unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
107+
def test_nodes_have_inline_values(self):
108+
tree = ast.parse("x = f(y, z=1)")
109+
for node in ast.walk(tree):
110+
with self.subTest(node=type(node).__name__):
111+
self.assertTrue(_testinternalcapi.has_inline_values(node))
112+
106113
def test_AST_fields_NULL_check(self):
107114
# See: https://github.com/python/cpython/issues/126105
108115
old_value = ast.AST._fields

‎Lib/test/test_gettext.py‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import base64
33
import gettext
4+
import io
45
import unittest
56
import unittest.mock
67
from functools import partial
@@ -39,7 +40,7 @@
3940
'''
4041

4142
# .mo file with an invalid magic number
42-
GNU_MO_DATA_BAD_MAGIC_NUMBER = base64.b64encode(b'ABCD')
43+
GNU_MO_DATA_BAD_MAGIC_NUMBER = base64.b64encode(b'ABCD' + bytes(16))
4344

4445
# This data contains an invalid major version number (5)
4546
# An unexpected major version number should be treated as an error when
@@ -314,6 +315,39 @@ def test_corrupt_file(self):
314315
self.assertEqual(exception.strerror, "File is corrupt")
315316
self.assertEqual(exception.filename, MOFILE_CORRUPT)
316317

318+
def test_truncated_header(self):
319+
magic = b'\xde\x12\x04\x95'
320+
for buf in (b'', magic, magic + bytes(15)):
321+
with self.subTest(buflen=len(buf)):
322+
with self.assertRaises(OSError) as cm:
323+
gettext.GNUTranslations(io.BytesIO(buf))
324+
self.assertEqual(cm.exception.errno, 0)
325+
self.assertEqual(cm.exception.strerror, "File is corrupt")
326+
327+
def test_offsets_out_of_bounds(self):
328+
buf = bytes([
329+
0xde, 0x12, 0x04, 0x95, # Magic
330+
0x00, 0x00, 0x00, 0x00, # Version
331+
0x01, 0x00, 0x00, 0x00, # Message count
332+
0xe8, 0x03, 0x00, 0x00, # Message offset (past EOF)
333+
0xd0, 0x07, 0x00, 0x00, # Translation offset (past EOF)
334+
])
335+
with self.assertRaises(OSError) as cm:
336+
gettext.GNUTranslations(io.BytesIO(buf))
337+
self.assertEqual(cm.exception.errno, 0)
338+
self.assertEqual(cm.exception.strerror, "File is corrupt")
339+
340+
def test_empty_catalog(self):
341+
buf = bytes([
342+
0xde, 0x12, 0x04, 0x95, # Magic
343+
0x00, 0x00, 0x00, 0x00, # Version
344+
0x00, 0x00, 0x00, 0x00, # Message count
345+
0x14, 0x00, 0x00, 0x00, # Message offset
346+
0x14, 0x00, 0x00, 0x00, # Translation offset
347+
])
348+
t = gettext.GNUTranslations(io.BytesIO(buf))
349+
self.assertEqual(t.gettext('foo'), 'foo')
350+
317351
def test_big_endian_file(self):
318352
with open(MOFILE_BIG_ENDIAN, 'rb') as fp:
319353
t = gettext.GNUTranslations(fp)

‎Lib/test/test_sys.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2042,7 +2042,7 @@ def test_pythontypes(self):
20422042
check = self.check_sizeof
20432043
# _ast.AST
20442044
import _ast
2045-
check(_ast.Module(), size('3P'))
2045+
check(_ast.Module(), size('2P'))
20462046
try:
20472047
raise TypeError
20482048
except TypeError as e:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up :func:`ast.parse` and reduce the memory used by AST nodes by storing
2+
node attributes as inline values instead of a separate per-node dictionary.

0 commit comments

Comments
 (0)