|
3 | 3 | )
|
4 | 4 | from test.support.import_helper import import_module
|
5 | 5 | from test.support.os_helper import TESTFN, unlink
|
| 6 | +from test.support.script_helper import assert_python_ok |
6 | 7 | import unittest
|
7 | 8 | import errno
|
8 | 9 | import os
|
|
12 | 13 | import socket
|
13 | 14 | import string
|
14 | 15 | import sys
|
| 16 | +import textwrap |
15 | 17 | import weakref
|
16 | 18 |
|
17 | 19 | # Skip test if we can't import mmap.
|
@@ -1058,6 +1060,81 @@ def __exit__(self, exc_type, exc_value, traceback):
|
1058 | 1060 | with self.assertRaisesRegex(ValueError, "mmap closed or invalid"):
|
1059 | 1061 | m.write_byte(X())
|
1060 | 1062 |
|
| 1063 | + @unittest.skipUnless(os.name == 'nt', 'requires Windows') |
| 1064 | + @unittest.skipUnless(hasattr(mmap.mmap, '_protect'), 'test needs debug build') |
| 1065 | + def test_access_violations(self): |
| 1066 | + from test.support.os_helper import TESTFN |
| 1067 | + |
| 1068 | + code = textwrap.dedent(""" |
| 1069 | + import faulthandler |
| 1070 | + import mmap |
| 1071 | + import os |
| 1072 | + import sys |
| 1073 | + from contextlib import suppress |
| 1074 | +
|
| 1075 | + # Prevent logging access violations to stderr. |
| 1076 | + faulthandler.disable() |
| 1077 | +
|
| 1078 | + PAGESIZE = mmap.PAGESIZE |
| 1079 | + PAGE_NOACCESS = 0x01 |
| 1080 | +
|
| 1081 | + with open(sys.argv[1], 'bw+') as f: |
| 1082 | + f.write(b'A'* PAGESIZE) |
| 1083 | + f.flush() |
| 1084 | +
|
| 1085 | + m = mmap.mmap(f.fileno(), PAGESIZE) |
| 1086 | + m._protect(PAGE_NOACCESS, 0, PAGESIZE) |
| 1087 | + with suppress(OSError): |
| 1088 | + m.read(PAGESIZE) |
| 1089 | + assert False, 'mmap.read() did not raise' |
| 1090 | + with suppress(OSError): |
| 1091 | + m.read_byte() |
| 1092 | + assert False, 'mmap.read_byte() did not raise' |
| 1093 | + with suppress(OSError): |
| 1094 | + m.readline() |
| 1095 | + assert False, 'mmap.readline() did not raise' |
| 1096 | + with suppress(OSError): |
| 1097 | + m.write(b'A'* PAGESIZE) |
| 1098 | + assert False, 'mmap.write() did not raise' |
| 1099 | + with suppress(OSError): |
| 1100 | + m.write_byte(0) |
| 1101 | + assert False, 'mmap.write_byte() did not raise' |
| 1102 | + with suppress(OSError): |
| 1103 | + m[0] # test mmap_subscript |
| 1104 | + assert False, 'mmap.__getitem__() did not raise' |
| 1105 | + with suppress(OSError): |
| 1106 | + m[0:10] # test mmap_subscript |
| 1107 | + assert False, 'mmap.__getitem__() did not raise' |
| 1108 | + with suppress(OSError): |
| 1109 | + m[0:10:2] # test mmap_subscript |
| 1110 | + assert False, 'mmap.__getitem__() did not raise' |
| 1111 | + with suppress(OSError): |
| 1112 | + m[0] = 1 |
| 1113 | + assert False, 'mmap.__setitem__() did not raise' |
| 1114 | + with suppress(OSError): |
| 1115 | + m[0:10] = b'A'* 10 |
| 1116 | + assert False, 'mmap.__setitem__() did not raise' |
| 1117 | + with suppress(OSError): |
| 1118 | + m[0:10:2] = b'A'* 5 |
| 1119 | + assert False, 'mmap.__setitem__() did not raise' |
| 1120 | + with suppress(OSError): |
| 1121 | + m.move(0, 10, 1) |
| 1122 | + assert False, 'mmap.move() did not raise' |
| 1123 | + with suppress(OSError): |
| 1124 | + list(m) # test mmap_item |
| 1125 | + assert False, 'mmap.__getitem__() did not raise' |
| 1126 | + with suppress(OSError): |
| 1127 | + m.find(b'A') |
| 1128 | + assert False, 'mmap.find() did not raise' |
| 1129 | + with suppress(OSError): |
| 1130 | + m.rfind(b'A') |
| 1131 | + assert False, 'mmap.rfind() did not raise' |
| 1132 | + """) |
| 1133 | + rt, stdout, stderr = assert_python_ok("-c", code, TESTFN) |
| 1134 | + self.assertEqual(stdout.strip(), b'') |
| 1135 | + self.assertEqual(stderr.strip(), b'') |
| 1136 | + |
| 1137 | + |
1061 | 1138 | class LargeMmapTests(unittest.TestCase):
|
1062 | 1139 |
|
1063 | 1140 | def setUp(self):
|
|
0 commit comments