summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qfsfileengine.cpp41
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qiodevice_p.h18
3 files changed, 39 insertions, 22 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 42250b629d..a126690240 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 89209e6118..0709a93bad 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 10d92a896d..d764cb0fbb 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);
}