diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap index 4adf7027b78..1706ad58680 100644 --- a/Lib/test/output/test_mmap +++ b/Lib/test/output/test_mmap @@ -24,6 +24,7 @@ test_mmap Ensuring that readonly mmap can't be write() to. Ensuring that readonly mmap can't be write_byte() to. Ensuring that readonly mmap can't be resized. + Opening mmap with size too big Opening mmap with access=ACCESS_WRITE Modifying write-through memory map. Opening mmap with access=ACCESS_COPY diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 11edbaf797f..dd1fb3f359c 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -189,6 +189,21 @@ def test_both(): verify(open(TESTFN, "rb").read() == 'a'*mapsize, "Readonly memory map data file was modified") + print " Opening mmap with size too big" + import sys + f = open(TESTFN, "r+b") + try: + m = mmap.mmap(f.fileno(), mapsize+1) + except ValueError: + # we do not expect a ValueError on Windows + if sys.platform.startswith('win'): + verify(0, "Opening mmap with size+1 should work on Windows.") + pass + else: + # we expect a ValueError on Unix, but not on Windows + if not sys.platform.startswith('win'): + verify(0, "Opening mmap with size+1 should raise ValueError.") + print " Opening mmap with access=ACCESS_WRITE" f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE) diff --git a/Misc/NEWS b/Misc/NEWS index f638e50e920..b877703afb1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -274,6 +274,9 @@ Core and builtins Extension modules +- If the size passed to mmap.mmap() is larger than the length of the + file on non-Windows platforms, a ValueError is raised. [SF bug 585792] + - The xreadlines module is slated for obsolescence. - The strptime function in the time module is now always available (a diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 2bb6edc8088..cff3c146e6c 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -850,6 +850,9 @@ _GetMapSize(PyObject *o) static PyObject * new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) { +#ifdef HAVE_FSTAT + struct stat st; +#endif mmap_object *m_obj; PyObject *map_size_obj = NULL; int map_size; @@ -890,7 +893,14 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) return PyErr_Format(PyExc_ValueError, "mmap invalid access parameter."); } - + +#ifdef HAVE_FSTAT + if (fstat(fd, &st) == 0 && (size_t)map_size > st.st_size) { + PyErr_SetString(PyExc_ValueError, + "mmap length is greater than file size"); + return NULL; + } +#endif m_obj = PyObject_New (mmap_object, &mmap_object_type); if (m_obj == NULL) {return NULL;} m_obj->size = (size_t) map_size;