summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qfsfileengine_unix.cpp
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-03-28 09:23:03 +0200
committerLiang Qi <liang.qi@qt.io>2017-03-28 09:28:31 +0200
commitb48a13fd6843e12b5725aa3ff0d010007e7c43b4 (patch)
tree316cfe36fc67906efcd92ff806c7c0da56ed4f8e /src/corelib/io/qfsfileengine_unix.cpp
parent3398d9d40cb0dae2dc2a1a4f7dc3b4b9cceae903 (diff)
parent15fe60cfdada84ea519f08e905d59cc3fb6d20cd (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: examples/examples.pro tests/auto/corelib/tools/qchar/tst_qchar.cpp tests/auto/other/qaccessibility/accessiblewidgets.h Change-Id: I426696c40ab57d14dc295b8103152cede79f244c
Diffstat (limited to 'src/corelib/io/qfsfileengine_unix.cpp')
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index ff77278dc1..4be4e893b3 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -688,6 +688,19 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
{
+#if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
+ // The Linux mmap2 system call on 32-bit takes a page-shifted 32-bit
+ // integer so the maximum offset is 1 << (32+12) (the shift is always 12,
+ // regardless of the actual page size). Unfortunately, the mmap64()
+ // function is known to be broken in all Linux libcs (glibc, uclibc, musl
+ // and Bionic): all of them do the right shift, but don't confirm that the
+ // result fits into the 32-bit parameter to the kernel.
+
+ static qint64 MaxFileOffset = (Q_INT64_C(1) << (32+12)) - 1;
+#else
+ static qint64 MaxFileOffset = std::numeric_limits<QT_OFF_T>::max();
+#endif
+
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QIODevice::NotOpen) {
@@ -695,7 +708,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
return 0;
}
- if (offset < 0 || offset != qint64(QT_OFF_T(offset))
+ if (offset < 0 || offset > MaxFileOffset
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;