Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.8.x, 5.8.0 Beta
-
None
-
linux
4.8.x
fedora 22
-
f53ab9d7363e2fb3b63cec1a00851f84f901de18
Description
QFile::atEnd() incorrectly returns false under the following conditions
- open a qfile
- perform an operation causing the d->cachedSize of QFilePrivate to be set
such as atEnd(),size(),resize(),bytesAvailable() - close file
- open a different filename that is smaller than the first using the same qfile object
- d->cachedSize now incorrectly refers to the larger size from the 1st file
- atEnd() will now always report false for regular files since (pos() < d->cachedSize) is always true. This line always occurs before the last "return bytesAvailable() == 0" line is reached in atEnd(). d->cachedSize would have been reset in the size() call within QIODevice::bytesAvailable() as occured when the 1st file initially called atEnd().
- the above behavior will occur unless the size(),resize(),bytesAvailable() is called to reset d->cachedSize before the end of file condition is reached.
Our workaround is to call one of these methods, such as size(), after opening the file for cases where we want to open/close multiple files with the same object, or to just avoid using atEnd() in those situations.
This would not occur if only one file is open/closed, the 2nd file is larger than the first one, methods such as bytesAvailable() are called before the end of the file, or atEnd() is not needed.
In the qt code this could be fixed by always setting d->cachedSize = 0 during the QFile::open() call. Currently this is only done in the constructor and a few other cases.
This bug was surprising but after verifying our specific use case and looking at the qt code, this bug appears to have been there from the very beginning.