From b7b811c383ff1bc272f7979191a4d9f44890e358 Mon Sep 17 00:00:00 2001 From: Hirokazu Yamamoto Date: Mon, 29 Jun 2009 14:37:28 +0000 Subject: [PATCH] Merged revisions 73677,73681 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73677 | hirokazu.yamamoto | 2009-06-29 22:25:16 +0900 | 2 lines Issue #6344: Fixed a crash of mmap.read() when passed a negative argument. Reviewed by Amaury Forgeot d'Arc. ........ r73681 | hirokazu.yamamoto | 2009-06-29 23:29:31 +0900 | 1 line Fixed NEWS. ........ --- Misc/NEWS | 2 ++ Modules/mmapmodule.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index c1ffebe6ca5..1ba1a73983d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,8 @@ Core and Builtins Library ------- +- Issue #6344: Fixed a crash of mmap.read() when passed a negative argument. + - Issue #5230: pydoc would report no documentation found if a module generated a 'not found' import error when loaded; it now reports the import errors. Thanks to Lucas Prado Melo for initial fix and collaboration on the tests. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 1d0f490d5ab..ac572d2fb1d 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -232,7 +232,7 @@ static PyObject * mmap_read_method(mmap_object *self, PyObject *args) { - Py_ssize_t num_bytes; + Py_ssize_t num_bytes, n; PyObject *result; CHECK_VALID(NULL); @@ -240,8 +240,18 @@ mmap_read_method(mmap_object *self, return(NULL); /* silently 'adjust' out-of-range requests */ - if (num_bytes > self->size - self->pos) { - num_bytes -= (self->pos+num_bytes) - self->size; + assert(self->size >= self->pos); + n = self->size - self->pos; + /* The difference can overflow, only if self->size is greater than + * PY_SSIZE_T_MAX. But then the operation cannot possibly succeed, + * because the mapped area and the returned string each need more + * than half of the addressable memory. So we clip the size, and let + * the code below raise MemoryError. + */ + if (n < 0) + n = PY_SSIZE_T_MAX; + if (num_bytes < 0 || num_bytes > n) { + num_bytes = n; } result = Py_BuildValue("s#", self->data+self->pos, num_bytes); self->pos += num_bytes;