|
|
04a680 |
From 6bebd55022c82829c0b15d24d2ca99edd22562df Mon Sep 17 00:00:00 2001
|
|
|
04a680 |
From: Charalampos Stratakis <cstratak@redhat.com>
|
|
|
04a680 |
Date: Wed, 4 May 2016 10:39:40 +0200
|
|
|
04a680 |
Subject: [PATCH] use Py_ssize_t for file offset and length computations in
|
|
|
04a680 |
iteration
|
|
|
04a680 |
|
|
|
04a680 |
---
|
|
|
04a680 |
Lib/test/test_file2k.py | 16 +++++++++++++++-
|
|
|
04a680 |
Objects/fileobject.c | 15 +++++++--------
|
|
|
04a680 |
2 files changed, 22 insertions(+), 9 deletions(-)
|
|
|
04a680 |
|
|
|
04a680 |
diff --git a/Lib/test/test_file2k.py b/Lib/test/test_file2k.py
|
|
|
04a680 |
index 5a3c354..8f94cee 100644
|
|
|
04a680 |
--- a/Lib/test/test_file2k.py
|
|
|
04a680 |
+++ b/Lib/test/test_file2k.py
|
|
|
04a680 |
@@ -14,7 +14,7 @@ except ImportError:
|
|
|
04a680 |
threading = None
|
|
|
04a680 |
|
|
|
04a680 |
from test import test_support
|
|
|
04a680 |
-from test.test_support import TESTFN, run_unittest
|
|
|
04a680 |
+from test.test_support import TESTFN, run_unittest, requires
|
|
|
04a680 |
from UserList import UserList
|
|
|
04a680 |
|
|
|
04a680 |
class AutoFileTests(unittest.TestCase):
|
|
|
04a680 |
@@ -416,6 +416,20 @@ class OtherFileTests(unittest.TestCase):
|
|
|
04a680 |
finally:
|
|
|
04a680 |
os.unlink(TESTFN)
|
|
|
04a680 |
|
|
|
04a680 |
+ @test_support.precisionbigmemtest(2**31, 2.5, dry_run=False)
|
|
|
04a680 |
+ def test_very_long_line(self, size):
|
|
|
04a680 |
+ # Issue #22526
|
|
|
04a680 |
+ requires('largefile')
|
|
|
04a680 |
+ with open(TESTFN, "wb") as fp:
|
|
|
04a680 |
+ fp.seek(size - 1)
|
|
|
04a680 |
+ fp.write("\0")
|
|
|
04a680 |
+ with open(TESTFN, "rb") as fp:
|
|
|
04a680 |
+ for l in fp:
|
|
|
04a680 |
+ pass
|
|
|
04a680 |
+ self.assertEqual(len(l), size)
|
|
|
04a680 |
+ self.assertEqual(l.count("\0"), size)
|
|
|
04a680 |
+ l = None
|
|
|
04a680 |
+
|
|
|
04a680 |
class FileSubclassTests(unittest.TestCase):
|
|
|
04a680 |
|
|
|
04a680 |
def testExit(self):
|
|
|
04a680 |
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
|
|
|
04a680 |
index 76cdf74..fabe207 100644
|
|
|
04a680 |
--- a/Objects/fileobject.c
|
|
|
04a680 |
+++ b/Objects/fileobject.c
|
|
|
04a680 |
@@ -2230,7 +2230,7 @@ drop_readahead(PyFileObject *f)
|
|
|
04a680 |
(unless at EOF) and no more than bufsize. Returns negative value on
|
|
|
04a680 |
error, will set MemoryError if bufsize bytes cannot be allocated. */
|
|
|
04a680 |
static int
|
|
|
04a680 |
-readahead(PyFileObject *f, int bufsize)
|
|
|
04a680 |
+readahead(PyFileObject *f, Py_ssize_t bufsize)
|
|
|
04a680 |
{
|
|
|
04a680 |
Py_ssize_t chunksize;
|
|
|
04a680 |
|
|
|
04a680 |
@@ -2268,7 +2268,7 @@ readahead(PyFileObject *f, int bufsize)
|
|
|
04a680 |
logarithmic buffer growth to about 50 even when reading a 1gb line. */
|
|
|
04a680 |
|
|
|
04a680 |
static PyStringObject *
|
|
|
04a680 |
-readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
|
|
|
04a680 |
+readahead_get_line_skip(PyFileObject *f, Py_ssize_t skip, Py_ssize_t bufsize)
|
|
|
04a680 |
{
|
|
|
04a680 |
PyStringObject* s;
|
|
|
04a680 |
char *bufptr;
|
|
|
04a680 |
@@ -2288,10 +2288,10 @@ readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
|
|
|
04a680 |
bufptr++; /* Count the '\n' */
|
|
|
04a680 |
len = bufptr - f->f_bufptr;
|
|
|
04a680 |
s = (PyStringObject *)
|
|
|
04a680 |
- PyString_FromStringAndSize(NULL, skip+len);
|
|
|
04a680 |
+ PyString_FromStringAndSize(NULL, skip + len);
|
|
|
04a680 |
if (s == NULL)
|
|
|
04a680 |
return NULL;
|
|
|
04a680 |
- memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
|
|
|
04a680 |
+ memcpy(PyString_AS_STRING(s) + skip, f->f_bufptr, len);
|
|
|
04a680 |
f->f_bufptr = bufptr;
|
|
|
04a680 |
if (bufptr == f->f_bufend)
|
|
|
04a680 |
drop_readahead(f);
|
|
|
04a680 |
@@ -2299,14 +2299,13 @@ readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
|
|
|
04a680 |
bufptr = f->f_bufptr;
|
|
|
04a680 |
buf = f->f_buf;
|
|
|
04a680 |
f->f_buf = NULL; /* Force new readahead buffer */
|
|
|
04a680 |
- assert(skip+len < INT_MAX);
|
|
|
04a680 |
- s = readahead_get_line_skip(
|
|
|
04a680 |
- f, (int)(skip+len), bufsize + (bufsize>>2) );
|
|
|
04a680 |
+ assert(len <= PY_SSIZE_T_MAX - skip);
|
|
|
04a680 |
+ s = readahead_get_line_skip(f, skip + len, bufsize + (bufsize>>2));
|
|
|
04a680 |
if (s == NULL) {
|
|
|
04a680 |
PyMem_Free(buf);
|
|
|
04a680 |
return NULL;
|
|
|
04a680 |
}
|
|
|
04a680 |
- memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
|
|
|
04a680 |
+ memcpy(PyString_AS_STRING(s) + skip, bufptr, len);
|
|
|
04a680 |
PyMem_Free(buf);
|
|
|
04a680 |
}
|
|
|
04a680 |
return s;
|
|
|
04a680 |
--
|
|
|
04a680 |
2.5.5
|
|
|
04a680 |
|