Fix the fix for mmap() overflow check
The code I introduced in 4ee7425794 only
dealt with systems that reasonably used a 64-bit off_t parameter. Turns
out that we don't turn on largefile support on 32-bit Android, which
meant that the fix caused a regression.
[ChangeLog][QtCore][QFile] Fixed a regression that caused QFile::map()
to succeed or produce incorrect results when trying to map a file at an
offset beyond 4 GB on 32-bit Android systems and on some special Linux
configurations.
Task-number: QTBUG-69148
Change-Id: I2c133120577fa12a32d444488bac3e341966f8d7
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
parent
fdb780b897
commit
9a04453b50
|
|
@ -634,6 +634,7 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time)
|
|||
|
||||
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
|
||||
{
|
||||
qint64 maxFileOffset = std::numeric_limits<QT_OFF_T>::max();
|
||||
#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,
|
||||
|
|
@ -642,9 +643,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
|
|||
// 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();
|
||||
maxFileOffset = qMin((Q_INT64_C(1) << (32+12)) - 1, maxFileOffset);
|
||||
#endif
|
||||
|
||||
Q_Q(QFSFileEngine);
|
||||
|
|
@ -653,7 +652,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (offset < 0 || offset > MaxFileOffset
|
||||
if (offset < 0 || offset > maxFileOffset
|
||||
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
|
||||
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ void tst_LargeFile::mapFile()
|
|||
//Mac: memory-mapping beyond EOF may succeed but it could generate bus error on access
|
||||
//FreeBSD: same
|
||||
//Linux: memory-mapping beyond EOF usually succeeds, but depends on the filesystem
|
||||
// 32-bit: limited to 44-bit offsets
|
||||
// 32-bit: limited to 44-bit offsets (when sizeof(off_t) == 8)
|
||||
//Windows: memory-mapping beyond EOF is not allowed
|
||||
void tst_LargeFile::mapOffsetOverflow()
|
||||
{
|
||||
|
|
@ -521,9 +521,9 @@ void tst_LargeFile::mapOffsetOverflow()
|
|||
#else
|
||||
Succeeds = true,
|
||||
# if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
|
||||
MaxOffset = 43
|
||||
MaxOffset = sizeof(QT_OFF_T) > 4 ? 43 : 30
|
||||
# else
|
||||
MaxOffset = 63
|
||||
MaxOffset = 8 * sizeof(QT_OFF_T) - 1
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue