diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 42250b629dcb19c49b95854c3fdddbe426998a5b..a1266902406e77bfc9363d9593f02970866e9c76 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -73,6 +73,17 @@ QT_BEGIN_NAMESPACE # endif #endif +#ifdef Q_OS_WIN +// on Windows, read() and write() use int and unsigned int +typedef int SignedIOType; +typedef unsigned int UnsignedIOType; +#else +typedef ssize_t SignedIOType; +typedef size_t UnsignedIOType; +Q_STATIC_ASSERT_X(sizeof(SignedIOType) == sizeof(UnsignedIOType), + "Unsupported: read/write return a type with different size as the len parameter"); +#endif + /*! \class QFSFileEngine \inmodule QtCore \brief The QFSFileEngine class implements Qt's default file engine. @@ -605,13 +616,16 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) } else if (fd != -1) { // Unbuffered stdio mode. -#ifdef Q_OS_WIN - int result; -#else - ssize_t result; -#endif + SignedIOType result; do { - result = QT_READ(fd, data + readBytes, size_t(len - readBytes)); + // calculate the chunk size + // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks + // we limit to the size of the signed type, otherwise we could get a negative number as a result + quint64 wantedBytes = quint64(len) - quint64(readBytes); + UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max(); + if (chunkSize > wantedBytes) + chunkSize = wantedBytes; + result = QT_READ(fd, data + readBytes, chunkSize); } while (result > 0 && (readBytes += result) < len); eof = !(result == -1); @@ -722,13 +736,16 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) } else if (fd != -1) { // Unbuffered stdio mode. -#ifdef Q_OS_WIN - int result; -#else - ssize_t result; -#endif + SignedIOType result; do { - result = QT_WRITE(fd, data + writtenBytes, size_t(len - writtenBytes)); + // calculate the chunk size + // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks + // we limit to the size of the signed type, otherwise we could get a negative number as a result + quint64 wantedBytes = quint64(len) - quint64(writtenBytes); + UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max(); + if (chunkSize > wantedBytes) + chunkSize = wantedBytes; + result = QT_WRITE(fd, data + writtenBytes, chunkSize); } while (result > 0 && (writtenBytes += result) < len); } diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 89209e6118f483721e6a3fcc36df97342ddc8894..0709a93bad94dd0a4e2e966c230a34f77d792693 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -786,7 +786,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize) bool moreToRead = true; do { // Try reading from the buffer. - int lastReadChunkSize = d->buffer.read(data, maxSize); + qint64 lastReadChunkSize = d->buffer.read(data, maxSize); if (lastReadChunkSize > 0) { *d->pPos += lastReadChunkSize; readSoFar += lastReadChunkSize; diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index 10d92a896d76bb18c2795ab8f8b88aa4130d4d12..d764cb0fbb05c2972b93da6a97dbd8d8da7962ec 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -98,19 +98,19 @@ public: first++; return ch; } - int read(char* target, qint64 size) { - int r = qMin(size, len); + qint64 read(char* target, qint64 size) { + qint64 r = qMin(size, len); memcpy(target, first, r); len -= r; first += r; return r; } - int peek(char* target, qint64 size) { - int r = qMin(size, len); + qint64 peek(char* target, qint64 size) { + qint64 r = qMin(size, len); memcpy(target, first, r); return r; } - char* reserve(int size) { + char* reserve(qint64 size) { makeSpace(size + len, freeSpaceAtEnd); char* writePtr = first + len; len += size; @@ -128,16 +128,16 @@ public: clear(); return retVal; } - int readLine(char* target, qint64 size) { - int r = qMin(size, len); + qint64 readLine(char* target, qint64 size) { + qint64 r = qMin(size, len); char* eol = static_cast<char*>(memchr(first, '\n', r)); if (eol) r = 1+(eol-first); memcpy(target, first, r); len -= r; first += r; - return int(r); - } + return r; + } bool canReadLine() const { return memchr(first, '\n', len); }