Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aac81e2

Browse files
Issue #14010: Fix a crash when iterating or deleting deeply nested filters
(builting and in itertools module, i.e. map(), itertools.chain(), etc).
2 parents c53fd51 + e8f706e commit aac81e2

6 files changed

Lines changed: 224 additions & 14 deletions

File tree

Lib/test/test_builtin.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1564,8 +1564,40 @@ def test_baddecorator(self):
15641564
data = 'The quick Brown fox Jumped over The lazy Dog'.split()
15651565
self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0)
15661566

1567+
class TestRecursionLimit(unittest.TestCase):
1568+
# Issue #14010
1569+
recursionlimit = sys.getrecursionlimit()
1570+
1571+
def test_filter(self):
1572+
it = (0, 1)
1573+
for _ in range(self.recursionlimit):
1574+
it = filter(bool, it)
1575+
with self.assertRaises(RuntimeError):
1576+
for _ in it:
1577+
pass
1578+
del it
1579+
1580+
def test_map(self):
1581+
it = (0, 1)
1582+
for _ in range(self.recursionlimit):
1583+
it = map(int, it)
1584+
with self.assertRaises(RuntimeError):
1585+
for _ in it:
1586+
pass
1587+
del it
1588+
1589+
def test_zip(self):
1590+
it = (0, 1)
1591+
for _ in range(self.recursionlimit):
1592+
it = zip(it)
1593+
with self.assertRaises(RuntimeError):
1594+
for _ in it:
1595+
pass
1596+
del it
1597+
1598+
15671599
def test_main(verbose=None):
1568-
test_classes = (BuiltinTest, TestSorted)
1600+
test_classes = (BuiltinTest, TestSorted, TestRecursionLimit)
15691601

15701602
run_unittest(*test_classes)
15711603

Lib/test/test_itertools.py

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,121 @@ def __init__(self, newarg=None, *args):
18081808
self.assertNotIn("does not take keyword arguments", err.args[0])
18091809

18101810

1811+
class TestRecursionLimit(unittest.TestCase):
1812+
# Issue #14010
1813+
recursionlimit = sys.getrecursionlimit()
1814+
1815+
def test_accumulate(self):
1816+
it = (0, 1)
1817+
for _ in range(self.recursionlimit):
1818+
it = accumulate(it)
1819+
with self.assertRaises(RuntimeError):
1820+
for _ in it:
1821+
pass
1822+
del it
1823+
1824+
def test_chain(self):
1825+
it = (0, 1)
1826+
for _ in range(self.recursionlimit):
1827+
it = chain(it, ())
1828+
with self.assertRaises(RuntimeError):
1829+
for _ in it:
1830+
pass
1831+
del it
1832+
1833+
def test_compress(self):
1834+
data = (0, 1)
1835+
selectors = (True, True)
1836+
it = data
1837+
for _ in range(self.recursionlimit):
1838+
it = compress(it, selectors)
1839+
with self.assertRaises(RuntimeError):
1840+
for _ in it:
1841+
pass
1842+
del it
1843+
1844+
it = selectors
1845+
for _ in range(self.recursionlimit):
1846+
it = compress(data, it)
1847+
with self.assertRaises(RuntimeError):
1848+
for _ in it:
1849+
pass
1850+
del it
1851+
1852+
def test_cycle(self):
1853+
it = (0, 1)
1854+
for _ in range(self.recursionlimit):
1855+
it = cycle(it)
1856+
with self.assertRaises(RuntimeError):
1857+
for _ in range(3):
1858+
next(it)
1859+
del it
1860+
1861+
def test_dropwhile(self):
1862+
it = (0, 1, 0)
1863+
for _ in range(self.recursionlimit):
1864+
it = dropwhile(bool, it)
1865+
with self.assertRaises(RuntimeError):
1866+
for _ in it:
1867+
pass
1868+
del it
1869+
1870+
def test_filterfalse(self):
1871+
it = (0, 1)
1872+
for _ in range(self.recursionlimit):
1873+
it = filterfalse(bool, it)
1874+
with self.assertRaises(RuntimeError):
1875+
for _ in it:
1876+
pass
1877+
del it
1878+
1879+
def test_groupby(self):
1880+
key = operator.itemgetter(0)
1881+
it = ((0, []), (1, []))
1882+
for _ in range(self.recursionlimit):
1883+
it = groupby(it, key)
1884+
with self.assertRaises(RuntimeError):
1885+
for _ in it:
1886+
pass
1887+
del it
1888+
1889+
def test_islice(self):
1890+
it = (0, 1)
1891+
for _ in range(self.recursionlimit):
1892+
it = islice(it, 2)
1893+
with self.assertRaises(RuntimeError):
1894+
for _ in it:
1895+
pass
1896+
del it
1897+
1898+
def test_starmap(self):
1899+
it = 'ab'
1900+
for _ in range(self.recursionlimit):
1901+
it = starmap(tuple, it)
1902+
with self.assertRaises(RuntimeError):
1903+
for _ in it:
1904+
pass
1905+
del it
1906+
1907+
def test_takewhile(self):
1908+
it = (1, 0)
1909+
for _ in range(self.recursionlimit):
1910+
it = takewhile(bool, it)
1911+
with self.assertRaises(RuntimeError):
1912+
for _ in it:
1913+
pass
1914+
del it
1915+
1916+
def test_zip_longest(self):
1917+
it = (0, 1)
1918+
for _ in range(self.recursionlimit):
1919+
it = zip_longest(it)
1920+
with self.assertRaises(RuntimeError):
1921+
for _ in it:
1922+
pass
1923+
del it
1924+
1925+
18111926
libreftest = """ Doctest for examples in the library reference: libitertools.tex
18121927
18131928
@@ -2042,7 +2157,7 @@ def __init__(self, newarg=None, *args):
20422157
def test_main(verbose=None):
20432158
test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
20442159
RegressionTests, LengthTransparency,
2045-
SubclassWithKwargsTest, TestExamples)
2160+
SubclassWithKwargsTest, TestExamples, TestRecursionLimit)
20462161
support.run_unittest(*test_classes)
20472162

20482163
# verify reference counting

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #14010: Fix a crash when iterating or deleting deeply nested filters
14+
(builting and in itertools module, i.e. map(), itertools.chain(), etc).
15+
1316
- Issue #17469: Fix _Py_GetAllocatedBlocks() and sys.getallocatedblocks()
1417
when running on valgrind.
1518

0 commit comments

Comments
 (0)