]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #8397: Raise an error when attempting to mix iteration and regular
authorAntoine Pitrou <solipsis@pitrou.net>
Sun, 1 Aug 2010 20:08:46 +0000 (20:08 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sun, 1 Aug 2010 20:08:46 +0000 (20:08 +0000)
reads on a BZ2File object, rather than returning incorrect results.

Lib/test/test_bz2.py
Misc/NEWS
Modules/bz2module.c

index 63b30098a8f76a652b3b38893b76adcace403729..082645847489097aba0037697fc265e733867cf7 100644 (file)
@@ -304,6 +304,24 @@ class BZ2FileTest(BaseTest):
         finally:
             f.close()
 
+    def testMixedIterationReads(self):
+        # Issue #8397: mixed iteration and reads should be forbidden.
+        f = bz2.BZ2File(self.filename, 'wb')
+        try:
+            # The internal buffer size is hard-wired to 8192 bytes, we must
+            # write out more than that for the test to stop half through
+            # the buffer.
+            f.write(self.TEXT * 100)
+        finally:
+            f.close()
+        f = bz2.BZ2File(self.filename, 'rb')
+        try:
+            next(f)
+            self.assertRaises(ValueError, f.read)
+            self.assertRaises(ValueError, f.readline)
+            self.assertRaises(ValueError, f.readlines)
+        finally:
+            f.close()
 
 class BZ2CompressorTest(BaseTest):
     def testCompress(self):
index 7d1317d04294f2a5b62004f984f8d7298ed4f506..1126d4ab94d4c95421adfb16c68c6ab7f73d501c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -29,6 +29,9 @@ Extensions
 Library
 -------
 
+- Issue #8397: Raise an error when attempting to mix iteration and regular
+  reads on a BZ2File object, rather than returning incorrect results.
+
 - Issue #9448: Fix a leak of OS resources (mutexes or semaphores) when
   re-initializing a buffered IO object by calling its ``__init__`` method.
 
index 29f85927f43d20e13c6cc91fa144ad1fb1151632..c44d3b97f1f740d84d26e689b8492dc26af78649 100644 (file)
@@ -138,6 +138,22 @@ typedef struct {
 /* ===================================================================== */
 /* Utility functions. */
 
+/* Refuse regular I/O if there's data in the iteration-buffer.
+ * Mixing them would cause data to arrive out of order, as the read*
+ * methods don't use the iteration buffer. */
+static int
+check_iterbuffered(BZ2FileObject *f)
+{
+    if (f->f_buf != NULL &&
+        (f->f_bufend - f->f_bufptr) > 0 &&
+        f->f_buf[0] != '\0') {
+        PyErr_SetString(PyExc_ValueError,
+            "Mixing iteration and read methods would lose data");
+        return -1;
+    }
+    return 0;
+}
+
 static int
 Util_CatchBZ2Error(int bzerror)
 {
@@ -427,6 +443,10 @@ BZ2File_read(BZ2FileObject *self, PyObject *args)
             goto cleanup;
     }
 
+    /* refuse to mix with f.next() */
+    if (check_iterbuffered(self))
+        goto cleanup;
+
     if (bytesrequested < 0)
         buffersize = Util_NewBufferSize((size_t)0);
     else
@@ -516,6 +536,10 @@ BZ2File_readline(BZ2FileObject *self, PyObject *args)
             goto cleanup;
     }
 
+    /* refuse to mix with f.next() */
+    if (check_iterbuffered(self))
+        goto cleanup;
+
     if (sizehint == 0)
         ret = PyBytes_FromStringAndSize("", 0);
     else
@@ -573,6 +597,10 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
             goto cleanup;
     }
 
+    /* refuse to mix with f.next() */
+    if (check_iterbuffered(self))
+        goto cleanup;
+
     if ((list = PyList_New(0)) == NULL)
         goto cleanup;