mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Merged revisions 74336 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r74336 | antoine.pitrou | 2009-08-06 22:18:29 +0200 (jeu., 06 août 2009) | 8 lines Issue #6629: Fix a data corruption issue in the new `io` package, which could occur when writing to a BufferedRandom object (e.g. a file opened in "rb+" or "wb+" mode) after having buffered a certain amount of data for reading. This bug was not present in the pure Python implementation. Yes, this is a serious issue. ........
This commit is contained in:
		
							parent
							
								
									5a5453978f
								
							
						
					
					
						commit
						a0ceb731fb
					
				
					 3 changed files with 38 additions and 0 deletions
				
			
		| 
						 | 
					@ -1328,6 +1328,26 @@ def _read(bufio):
 | 
				
			||||||
            bufio.readinto(bytearray(1))
 | 
					            bufio.readinto(bytearray(1))
 | 
				
			||||||
        self.check_writes(_read)
 | 
					        self.check_writes(_read)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_write_after_readahead(self):
 | 
				
			||||||
 | 
					        # Issue #6629: writing after the buffer was filled by readahead should
 | 
				
			||||||
 | 
					        # first rewind the raw stream.
 | 
				
			||||||
 | 
					        for overwrite_size in [1, 5]:
 | 
				
			||||||
 | 
					            raw = self.BytesIO(b"A" * 10)
 | 
				
			||||||
 | 
					            bufio = self.tp(raw, 4)
 | 
				
			||||||
 | 
					            # Trigger readahead
 | 
				
			||||||
 | 
					            self.assertEqual(bufio.read(1), b"A")
 | 
				
			||||||
 | 
					            self.assertEqual(bufio.tell(), 1)
 | 
				
			||||||
 | 
					            # Overwriting should rewind the raw stream if it needs so
 | 
				
			||||||
 | 
					            bufio.write(b"B" * overwrite_size)
 | 
				
			||||||
 | 
					            self.assertEqual(bufio.tell(), overwrite_size + 1)
 | 
				
			||||||
 | 
					            # If the write size was smaller than the buffer size, flush() and
 | 
				
			||||||
 | 
					            # check that rewind happens.
 | 
				
			||||||
 | 
					            bufio.flush()
 | 
				
			||||||
 | 
					            self.assertEqual(bufio.tell(), overwrite_size + 1)
 | 
				
			||||||
 | 
					            s = raw.getvalue()
 | 
				
			||||||
 | 
					            self.assertEqual(s,
 | 
				
			||||||
 | 
					                b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_misbehaved_io(self):
 | 
					    def test_misbehaved_io(self):
 | 
				
			||||||
        BufferedReaderTest.test_misbehaved_io(self)
 | 
					        BufferedReaderTest.test_misbehaved_io(self)
 | 
				
			||||||
        BufferedWriterTest.test_misbehaved_io(self)
 | 
					        BufferedWriterTest.test_misbehaved_io(self)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,11 @@ C-API
 | 
				
			||||||
Library
 | 
					Library
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue #6629: Fix a data corruption issue in the new I/O library, which could
 | 
				
			||||||
 | 
					  occur when writing to a BufferedRandom object (e.g. a file opened in "rb+" or
 | 
				
			||||||
 | 
					  "wb+" mode) after having buffered a certain amount of data for reading. This
 | 
				
			||||||
 | 
					  bug was not present in the pure Python implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Issue #6622: Fix "local variable 'secret' referenced before
 | 
					- Issue #6622: Fix "local variable 'secret' referenced before
 | 
				
			||||||
  assignment" bug in POP3.apop.
 | 
					  assignment" bug in POP3.apop.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1757,6 +1757,19 @@ bufferedwriter_write(buffered *self, PyObject *args)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Py_CLEAR(res);
 | 
					    Py_CLEAR(res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Adjust the raw stream position if it is away from the logical stream
 | 
				
			||||||
 | 
					       position. This happens if the read buffer has been filled but not
 | 
				
			||||||
 | 
					       modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
 | 
				
			||||||
 | 
					       the raw stream by itself).
 | 
				
			||||||
 | 
					       Fixes issue #6629.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    n = RAW_OFFSET(self);
 | 
				
			||||||
 | 
					    if (n != 0) {
 | 
				
			||||||
 | 
					        if (_buffered_raw_seek(self, -n, 1) < 0)
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					        self->raw_pos -= n;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Then write buf itself. At this point the buffer has been emptied. */
 | 
					    /* Then write buf itself. At this point the buffer has been emptied. */
 | 
				
			||||||
    remaining = buf.len;
 | 
					    remaining = buf.len;
 | 
				
			||||||
    written = 0;
 | 
					    written = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue