eryksun added the comment:
This fix for issue 20731 doesn't address this bug completely because it's
possible for ftell to return -1 without an actual error, as test2.py
demonstrates.
In text mode, CRLF is translated to LF by the CRT's _read function (Win32
ReadFile). So the buffer that's used by FILE streams is already translated. To
get the stream position, ftell first calls _lseek (Win32 SetFilePointer) to get
the file pointer. Then it adjusts the file pointer for the unwritten/unread
bytes in the buffer. The problem for reading is how to tell whether or not LF
in the buffer was translated from CRLF? The chosen 'solution' is to just assume
CRLF.
The example file test2.py is 33 bytes. At the time fp_setreadl calls
ftell(tok->fp), the file pointer is 33, and Py_UniversalNewlineFgets has read
the stream up to '#coding:latin-1\n'. That leaves 17 newline characters
buffered. As stated above, ftell assumes CRLF, so it calculates the stream
position as 33 - (17 * 2) == -1. That happens to be the value returned for an
error, but who's checking? In this case, errno is 0 instead of the documented
errno constants EBADF or EINVAL.
Here's an example in 2.7.7, since it uses FILE streams:
>>> f = open('test2.py')
>>> f.read(16)
'#coding:latin-1\n'
>>> f.tell()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 0] Error
Can the file be opened in binary mode in Modules/main.c? Currently it's using
`_Py_wfopen(filename, L"r")`. But decoding_fgets calls
Py_UniversalNewlineFgets, which expects binary mode anyway.
----------
nosy: +eryksun
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue20844>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com