Skip to content

Commit fca705d

Browse files
bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. (#514) (#722)
(cherry picked from commit a5af6e1)
1 parent 69eab31 commit fca705d

File tree

6 files changed

+872
-9
lines changed

6 files changed

+872
-9
lines changed

Lib/test/test_fileio.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from functools import wraps
1111

1212
from test.support import (TESTFN, TESTFN_UNICODE, check_warnings, run_unittest,
13-
make_bad_fd, cpython_only)
13+
make_bad_fd, cpython_only, swap_attr)
1414
from collections import UserList
1515

1616
import _io # C implementation of io
@@ -176,6 +176,12 @@ def testReprNoCloseFD(self):
176176
finally:
177177
os.close(fd)
178178

179+
def testRecursiveRepr(self):
180+
# Issue #25455
181+
with swap_attr(self.f, 'name', self.f):
182+
with self.assertRaises(RuntimeError):
183+
repr(self.f) # Should not crash
184+
179185
def testErrors(self):
180186
f = self.f
181187
self.assertFalse(f.isatty())

Lib/test/test_io.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,16 @@ def test_repr(self):
10141014
raw.name = b"dummy"
10151015
self.assertEqual(repr(b), "<%s name=b'dummy'>" % clsname)
10161016

1017+
def test_recursive_repr(self):
1018+
# Issue #25455
1019+
raw = self.MockRawIO()
1020+
b = self.tp(raw)
1021+
with support.swap_attr(raw, 'name', b):
1022+
try:
1023+
repr(b) # Should not crash
1024+
except RuntimeError:
1025+
pass
1026+
10171027
def test_flush_error_on_close(self):
10181028
# Test that buffered file is closed despite failed flush
10191029
# and that flush() is called before file closed.
@@ -2424,6 +2434,16 @@ def test_repr(self):
24242434
t.buffer.detach()
24252435
repr(t) # Should not raise an exception
24262436

2437+
def test_recursive_repr(self):
2438+
# Issue #25455
2439+
raw = self.BytesIO()
2440+
t = self.TextIOWrapper(raw)
2441+
with support.swap_attr(raw, 'name', t):
2442+
try:
2443+
repr(t) # Should not crash
2444+
except RuntimeError:
2445+
pass
2446+
24272447
def test_line_buffering(self):
24282448
r = self.BytesIO()
24292449
b = self.BufferedWriter(r, 1000)

0 commit comments

Comments
 (0)