mirror of
https://github.com/python/cpython.git
synced 2025-11-01 10:45:30 +00:00
Fix BZ2File.(x)readlines() for files without a newline.
This commit is contained in:
parent
f755432f41
commit
33a5f2af59
3 changed files with 51 additions and 9 deletions
|
|
@ -37,7 +37,7 @@ class BaseTest(unittest.TestCase):
|
||||||
return bz2.decompress(data)
|
return bz2.decompress(data)
|
||||||
|
|
||||||
class BZ2FileTest(BaseTest):
|
class BZ2FileTest(BaseTest):
|
||||||
"Test MCRYPT type miscelaneous methods."
|
"Test BZ2File type miscellaneous methods."
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.filename = TESTFN
|
self.filename = TESTFN
|
||||||
|
|
@ -245,6 +245,22 @@ class BZ2FileTest(BaseTest):
|
||||||
self.assertEqual(f.tell(), len(self.DATA))
|
self.assertEqual(f.tell(), len(self.DATA))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def testBug1191043(self):
|
||||||
|
# readlines() for files containing no newline
|
||||||
|
data = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t'
|
||||||
|
f = open(self.filename, "wb")
|
||||||
|
f.write(data)
|
||||||
|
f.close()
|
||||||
|
bz2f = BZ2File(self.filename)
|
||||||
|
lines = bz2f.readlines()
|
||||||
|
bz2f.close()
|
||||||
|
self.assertEqual(lines, ['Test'])
|
||||||
|
bz2f = BZ2File(self.filename)
|
||||||
|
xlines = bz2f.xreadlines()
|
||||||
|
bz2f.close()
|
||||||
|
self.assertEqual(lines, ['Test'])
|
||||||
|
|
||||||
|
|
||||||
class BZ2CompressorTest(BaseTest):
|
class BZ2CompressorTest(BaseTest):
|
||||||
def testCompress(self):
|
def testCompress(self):
|
||||||
# "Test BZ2Compressor.compress()/flush()"
|
# "Test BZ2Compressor.compress()/flush()"
|
||||||
|
|
|
||||||
|
|
@ -1570,6 +1570,9 @@ Core and builtins
|
||||||
Extension modules
|
Extension modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Fix bz2.BZ2File.(x)readlines() for files containing one line without
|
||||||
|
newlines.
|
||||||
|
|
||||||
- Added socket.getservbyport(), and make the second argument in
|
- Added socket.getservbyport(), and make the second argument in
|
||||||
getservbyname() and getservbyport() optional.
|
getservbyname() and getservbyport() optional.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,18 @@ static char __author__[] =
|
||||||
Gustavo Niemeyer <niemeyer@conectiva.com>\n\
|
Gustavo Niemeyer <niemeyer@conectiva.com>\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
|
/* Our very own off_t-like type, 64-bit if possible */
|
||||||
|
/* copied from Objects/fileobject.c */
|
||||||
|
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
||||||
|
typedef off_t Py_off_t;
|
||||||
|
#elif SIZEOF_OFF_T >= 8
|
||||||
|
typedef off_t Py_off_t;
|
||||||
|
#elif SIZEOF_FPOS_T >= 8
|
||||||
|
typedef fpos_t Py_off_t;
|
||||||
|
#else
|
||||||
|
#error "Large file support, but neither off_t nor fpos_t is large enough."
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
|
#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
|
||||||
|
|
||||||
#define MODE_CLOSED 0
|
#define MODE_CLOSED 0
|
||||||
|
|
@ -405,7 +417,9 @@ Util_ReadAhead(BZ2FileObject *f, int bufsize)
|
||||||
Util_DropReadAhead(f);
|
Util_DropReadAhead(f);
|
||||||
}
|
}
|
||||||
if (f->mode == MODE_READ_EOF) {
|
if (f->mode == MODE_READ_EOF) {
|
||||||
return -1;
|
f->f_bufptr = f->f_buf;
|
||||||
|
f->f_bufend = f->f_buf;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
|
if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -682,13 +696,13 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
totalread += nread;
|
totalread += nread;
|
||||||
p = memchr(buffer+nfilled, '\n', nread);
|
p = memchr(buffer+nfilled, '\n', nread);
|
||||||
if (p == NULL) {
|
if (!shortread && p == NULL) {
|
||||||
/* Need a larger buffer to fit this line */
|
/* Need a larger buffer to fit this line */
|
||||||
nfilled += nread;
|
nfilled += nread;
|
||||||
buffersize *= 2;
|
buffersize *= 2;
|
||||||
if (buffersize > INT_MAX) {
|
if (buffersize > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
"line is longer than a Python string can hold");
|
"line is longer than a Python string can hold");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (big_buffer == NULL) {
|
if (big_buffer == NULL) {
|
||||||
|
|
@ -705,11 +719,11 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
|
||||||
_PyString_Resize(&big_buffer, buffersize);
|
_PyString_Resize(&big_buffer, buffersize);
|
||||||
buffer = PyString_AS_STRING(big_buffer);
|
buffer = PyString_AS_STRING(big_buffer);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
end = buffer+nfilled+nread;
|
end = buffer+nfilled+nread;
|
||||||
q = buffer;
|
q = buffer;
|
||||||
do {
|
while (p != NULL) {
|
||||||
/* Process complete lines */
|
/* Process complete lines */
|
||||||
p++;
|
p++;
|
||||||
line = PyString_FromStringAndSize(q, p-q);
|
line = PyString_FromStringAndSize(q, p-q);
|
||||||
|
|
@ -721,7 +735,7 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
|
||||||
goto error;
|
goto error;
|
||||||
q = p;
|
q = p;
|
||||||
p = memchr(q, '\n', end-q);
|
p = memchr(q, '\n', end-q);
|
||||||
} while (p != NULL);
|
}
|
||||||
/* Move the remaining incomplete line to the start */
|
/* Move the remaining incomplete line to the start */
|
||||||
nfilled = end-q;
|
nfilled = end-q;
|
||||||
memmove(buffer, q, nfilled);
|
memmove(buffer, q, nfilled);
|
||||||
|
|
@ -962,7 +976,8 @@ static PyObject *
|
||||||
BZ2File_seek(BZ2FileObject *self, PyObject *args)
|
BZ2File_seek(BZ2FileObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int where = 0;
|
int where = 0;
|
||||||
long offset;
|
PyObject *offobj;
|
||||||
|
Py_off_t offset;
|
||||||
char small_buffer[SMALLCHUNK];
|
char small_buffer[SMALLCHUNK];
|
||||||
char *buffer = small_buffer;
|
char *buffer = small_buffer;
|
||||||
size_t buffersize = SMALLCHUNK;
|
size_t buffersize = SMALLCHUNK;
|
||||||
|
|
@ -973,7 +988,15 @@ BZ2File_seek(BZ2FileObject *self, PyObject *args)
|
||||||
int rewind = 0;
|
int rewind = 0;
|
||||||
PyObject *ret = NULL;
|
PyObject *ret = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "l|i:seek", &offset, &where))
|
if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
|
||||||
|
return NULL;
|
||||||
|
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
||||||
|
offset = PyInt_AsLong(offobj);
|
||||||
|
#else
|
||||||
|
offset = PyLong_Check(offobj) ?
|
||||||
|
PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
|
||||||
|
#endif
|
||||||
|
if (PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ACQUIRE_LOCK(self);
|
ACQUIRE_LOCK(self);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue