File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 4343 import _winapi
4444except ImportError :
4545 _winapi = None
46+ try :
47+ from _testcapi import INT_MAX
48+ except ImportError :
49+ INT_MAX = 2 ** 31 - 1
4650
4751from test .script_helper import assert_python_ok
4852
@@ -119,6 +123,21 @@ def test_read(self):
119123 self .assertEqual (type (s ), bytes )
120124 self .assertEqual (s , b"spam" )
121125
126+ def test_large_read (self ):
127+ with open (support .TESTFN , "wb" ) as fp :
128+ fp .write (b'test' )
129+ self .addCleanup (support .unlink , support .TESTFN )
130+
131+ # Issue #21932: Make sure that os.read() does not raise an
132+ # OverflowError for size larger than INT_MAX
133+ size = INT_MAX + 10
134+ with open (support .TESTFN , "rb" ) as fp :
135+ data = os .read (fp .fileno (), size )
136+
137+ # The test does not try to read more than 2 GB at once because the
138+ # operating system is free to return less bytes than requested.
139+ self .assertEqual (data , b'test' )
140+
122141 def test_write (self ):
123142 # os.write() accepts bytes- and buffer-like objects but not strings
124143 fd = os .open (support .TESTFN , os .O_CREAT | os .O_WRONLY )
Original file line number Diff line number Diff line change @@ -108,6 +108,11 @@ Core and Builtins
108108Library
109109-------
110110
111+ - Issue #21932: os.read() now uses a :c:func:`Py_ssize_t` type instead of
112+ :c:type:`int` for the size to support reading more than 2 GB at once. On
113+ Windows, the size is truncted to INT_MAX. As any call to os.read(), the OS
114+ may read less bytes than the number of requested bytes.
115+
111116- Issue #21942: Fixed source file viewing in pydoc's server mode on Windows.
112117
113118- Issue #11259: asynchat.async_chat().set_terminator() now raises a ValueError
Original file line number Diff line number Diff line change @@ -7989,24 +7989,31 @@ Read a file descriptor.");
79897989static PyObject *
79907990posix_read (PyObject * self , PyObject * args )
79917991{
7992- int fd , size ;
7992+ int fd ;
7993+ Py_ssize_t size ;
79937994 Py_ssize_t n ;
79947995 PyObject * buffer ;
7995- if (!PyArg_ParseTuple (args , "ii :read" , & fd , & size ))
7996+ if (!PyArg_ParseTuple (args , "in :read" , & fd , & size ))
79967997 return NULL ;
7998+ if (!_PyVerify_fd (fd ))
7999+ return posix_error ();
8000+ #ifdef MS_WINDOWS
8001+ if (size > INT_MAX )
8002+ size = INT_MAX ;
8003+ #endif
79978004 if (size < 0 ) {
79988005 errno = EINVAL ;
79998006 return posix_error ();
80008007 }
80018008 buffer = PyBytes_FromStringAndSize ((char * )NULL , size );
80028009 if (buffer == NULL )
80038010 return NULL ;
8004- if (!_PyVerify_fd (fd )) {
8005- Py_DECREF (buffer );
8006- return posix_error ();
8007- }
80088011 Py_BEGIN_ALLOW_THREADS
8012+ #ifdef MS_WINDOWS
8013+ n = read (fd , PyBytes_AS_STRING (buffer ), (int )size );
8014+ #else
80098015 n = read (fd , PyBytes_AS_STRING (buffer ), size );
8016+ #endif
80108017 Py_END_ALLOW_THREADS
80118018 if (n < 0 ) {
80128019 Py_DECREF (buffer );
You can’t perform that action at this time.
0 commit comments