Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[3.6] bpo-30070: Fixed leaks and crashes in errors handling in the pa…
…rser module. (GH-1131). (#1184)

(cherry picked from commit a79f4c2)
  • Loading branch information
serhiy-storchaka committed Apr 19, 2017
1 parent 680fea4 commit 39dedb6
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 52 deletions.
81 changes: 81 additions & 0 deletions Lib/test/test_parser.py
@@ -1,4 +1,6 @@
import copy
import parser
import pickle
import unittest
import operator
import struct
Expand Down Expand Up @@ -424,6 +426,52 @@ def test_junk(self):
# not even remotely valid:
self.check_bad_tree((1, 2, 3), "<junk>")

def test_illegal_terminal(self):
tree = \
(257,
(269,
(270,
(271,
(277,
(1,))),
(4, ''))),
(4, ''),
(0, ''))
self.check_bad_tree(tree, "too small items in terminal node")
tree = \
(257,
(269,
(270,
(271,
(277,
(1, b'pass'))),
(4, ''))),
(4, ''),
(0, ''))
self.check_bad_tree(tree, "non-string second item in terminal node")
tree = \
(257,
(269,
(270,
(271,
(277,
(1, 'pass', '0', 0))),
(4, ''))),
(4, ''),
(0, ''))
self.check_bad_tree(tree, "non-integer third item in terminal node")
tree = \
(257,
(269,
(270,
(271,
(277,
(1, 'pass', 0, 0))),
(4, ''))),
(4, ''),
(0, ''))
self.check_bad_tree(tree, "too many items in terminal node")

def test_illegal_yield_1(self):
# Illegal yield statement: def f(): return 1; yield 1
tree = \
Expand Down Expand Up @@ -628,6 +676,24 @@ def test_missing_import_source(self):
(4, ''), (0, ''))
self.check_bad_tree(tree, "from import fred")

def test_illegal_encoding(self):
# Illegal encoding declaration
tree = \
(339,
(257, (0, '')))
self.check_bad_tree(tree, "missed encoding")
tree = \
(339,
(257, (0, '')),
b'iso-8859-1')
self.check_bad_tree(tree, "non-string encoding")
tree = \
(339,
(257, (0, '')),
'\udcff')
with self.assertRaises(UnicodeEncodeError):
parser.sequence2st(tree)


class CompileTestCase(unittest.TestCase):

Expand Down Expand Up @@ -772,6 +838,21 @@ def test_comparisons(self):
self.assertRaises(TypeError, operator.lt, st1, 1815)
self.assertRaises(TypeError, operator.gt, b'waterloo', st2)

def test_copy_pickle(self):
sts = [
parser.expr('2 + 3'),
parser.suite('x = 2; y = x + 3'),
parser.expr('list(x**3 for x in range(20))')
]
for st in sts:
st_copy = copy.copy(st)
self.assertEqual(st_copy.totuple(), st.totuple())
st_copy = copy.deepcopy(st)
self.assertEqual(st_copy.totuple(), st.totuple())
for proto in range(pickle.HIGHEST_PROTOCOL+1):
st_copy = pickle.loads(pickle.dumps(st, proto))
self.assertEqual(st_copy.totuple(), st.totuple())

check_sizeof = support.check_sizeof

@support.cpython_only
Expand Down
2 changes: 2 additions & 0 deletions Misc/NEWS
Expand Up @@ -32,6 +32,8 @@ Core and Builtins
Library
-------

- bpo-30070: Fixed leaks and crashes in errors handling in the parser module.

- bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when
readline() or __next__() respectively return non-sizeable object.
Fixed possible other errors caused by not checking results of PyObject_Size(),
Expand Down

0 comments on commit 39dedb6

Please sign in to comment.