Skip to content

Commit cdb63fb

Browse files
committed
Merged revisions 83442 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/release27-maint ................ r83442 | antoine.pitrou | 2010-08-01 22:13:11 +0200 (dim., 01 août 2010) | 10 lines Merged revisions 83440 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r83440 | antoine.pitrou | 2010-08-01 22:08:46 +0200 (dim., 01 août 2010) | 4 lines Issue python#8397: Raise an error when attempting to mix iteration and regular reads on a BZ2File object, rather than returning incorrect results. ........ ................
1 parent 1fa5e05 commit cdb63fb

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

Lib/test/test_bz2.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,24 @@ def comp():
302302
finally:
303303
f.close()
304304

305+
def testMixedIterationReads(self):
306+
# Issue #8397: mixed iteration and reads should be forbidden.
307+
f = bz2.BZ2File(self.filename, 'wb')
308+
try:
309+
# The internal buffer size is hard-wired to 8192 bytes, we must
310+
# write out more than that for the test to stop half through
311+
# the buffer.
312+
f.write(self.TEXT * 100)
313+
finally:
314+
f.close()
315+
f = bz2.BZ2File(self.filename, 'rb')
316+
try:
317+
next(f)
318+
self.assertRaises(ValueError, f.read)
319+
self.assertRaises(ValueError, f.readline)
320+
self.assertRaises(ValueError, f.readlines)
321+
finally:
322+
f.close()
305323

306324
class BZ2CompressorTest(BaseTest):
307325
def testCompress(self):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ C-API
8484
Library
8585
-------
8686

87+
- Issue #8397: Raise an error when attempting to mix iteration and regular
88+
reads on a BZ2File object, rather than returning incorrect results.
89+
8790
- Issue #8620: when a Cmd is fed input that reaches EOF without a final
8891
newline, it no longer truncates the last character of the last command line.
8992

Modules/bz2module.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,22 @@ typedef struct {
144144
/* ===================================================================== */
145145
/* Utility functions. */
146146

147+
/* Refuse regular I/O if there's data in the iteration-buffer.
148+
* Mixing them would cause data to arrive out of order, as the read*
149+
* methods don't use the iteration buffer. */
150+
static int
151+
check_iterbuffered(BZ2FileObject *f)
152+
{
153+
if (f->f_buf != NULL &&
154+
(f->f_bufend - f->f_bufptr) > 0 &&
155+
f->f_buf[0] != '\0') {
156+
PyErr_SetString(PyExc_ValueError,
157+
"Mixing iteration and read methods would lose data");
158+
return -1;
159+
}
160+
return 0;
161+
}
162+
147163
static int
148164
Util_CatchBZ2Error(int bzerror)
149165
{
@@ -527,6 +543,10 @@ BZ2File_read(BZ2FileObject *self, PyObject *args)
527543
goto cleanup;
528544
}
529545

546+
/* refuse to mix with f.next() */
547+
if (check_iterbuffered(self))
548+
goto cleanup;
549+
530550
if (bytesrequested < 0)
531551
buffersize = Util_NewBufferSize((size_t)0);
532552
else
@@ -612,6 +632,10 @@ BZ2File_readline(BZ2FileObject *self, PyObject *args)
612632
goto cleanup;
613633
}
614634

635+
/* refuse to mix with f.next() */
636+
if (check_iterbuffered(self))
637+
goto cleanup;
638+
615639
if (sizehint == 0)
616640
ret = PyString_FromString("");
617641
else
@@ -669,6 +693,10 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
669693
goto cleanup;
670694
}
671695

696+
/* refuse to mix with f.next() */
697+
if (check_iterbuffered(self))
698+
goto cleanup;
699+
672700
if ((list = PyList_New(0)) == NULL)
673701
goto cleanup;
674702

0 commit comments

Comments
 (0)