summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/largefile
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-03-17 14:33:33 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-03-31 06:31:25 +0000
commit9a0d47bcf1f7988984c38f123828b93fdfc20a49 (patch)
tree4971f37aae0f70446c7430b53ce7fa51cefe204e /tests/auto/corelib/io/largefile
parent9b5b44207ef9a191b0f45857232afdee8c938a04 (diff)
tst_largefile: fix the mapOffsetOverflow case to match actual behavior
Unix mmap(2) system calls do allow for mapping beyond the end of the file, though what happens after you try to dereference the pointers it gives is unspecified. POSIX[1] says that implementations shouldn't allow it: The system shall always zero-fill any partial page at the end of an object. Further, the system shall never write out any modified portions of the last page of an object which are beyond its end. References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal. However, Linux allows this in read-write mode and extends the file (depending on the filesystem). Windows MapViewOfFile never allows mapping beyond the end. [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html Change-Id: Ie67d35dff21147e99ad9fffd14acc8d9a1a0c38d Reviewed-by: Sami Nurmenniemi <sami.nurmenniemi@qt.io> Reviewed-by: Teemu Holappa <teemu.holappa@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/io/largefile')
-rw-r--r--tests/auto/corelib/io/largefile/tst_largefile.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp
index a19a5ce58d..7a174b79fd 100644
--- a/tests/auto/corelib/io/largefile/tst_largefile.cpp
+++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp
@@ -502,23 +502,42 @@ 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
+//Windows: memory-mapping beyond EOF is not allowed
void tst_LargeFile::mapOffsetOverflow()
{
-#ifndef Q_OS_MAC
- // Out-of-range mappings should fail, and not silently clip the offset
- for (int i = 50; i < 63; ++i) {
+ enum {
+#ifdef Q_OS_WIN
+ Succeeds = false,
+ MaxOffset = 63
+#else
+ Succeeds = true,
+# if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
+ MaxOffset = 43
+# else
+ MaxOffset = 63
+# endif
+#endif
+ };
+
+ QByteArray zeroPage(blockSize, '\0');
+ for (int i = maxSizeBits + 1; i < 63; ++i) {
+ bool succeeds = Succeeds && (i <= MaxOffset);
uchar *address = 0;
+ qint64 offset = Q_INT64_C(1) << i;
- address = largeFile.map(((qint64)1 << i), blockSize);
-#if defined(__x86_64__)
- QEXPECT_FAIL("", "fails on 64-bit Linux (QTBUG-21175)", Abort);
-#endif
- QVERIFY( !address );
+ if (succeeds)
+ QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::map: Mapping a file beyond its size is not portable");
+ address = largeFile.map(offset, blockSize);
+ QCOMPARE(!!address, succeeds);
- address = largeFile.map(((qint64)1 << i) + blockSize, blockSize);
- QVERIFY( !address );
+ if (succeeds)
+ QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::map: Mapping a file beyond its size is not portable");
+ address = largeFile.map(offset + blockSize, blockSize);
+ QCOMPARE(!!address, succeeds);
}
-#endif
}
QTEST_APPLESS_MAIN(tst_LargeFile)