[pypy-svn] r18552 - in pypy/dist/pypy/translator/c: . src test
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 14 16:39:03 CEST 2005
Author: arigo
Date: Fri Oct 14 16:38:59 2005
New Revision: 18552
Modified:
pypy/dist/pypy/translator/c/funcgen.py
pypy/dist/pypy/translator/c/src/mem.h
pypy/dist/pypy/translator/c/test/test_annotated.py
Log:
Check for impossibly large number of items before malloc'ing arrays.
Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py (original)
+++ pypy/dist/pypy/translator/c/funcgen.py Fri Oct 14 16:38:59 2005
@@ -517,11 +517,19 @@
eresult = self.expr(op.result)
if VARPART.OF is Void: # strange
esize = 'sizeof(%s)' % (cdecl(typename, ''),)
+ result = ''
else:
- esize = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''),
- elength,
- cdecl(itemtypename, ''))
- result = self.gcpolicy.zero_malloc(TYPE, esize, eresult, err)
+ itemtype = cdecl(itemtypename, '')
+ result = 'OP_MAX_VARSIZE(%s, %s, %s);\n' % (
+ elength,
+ itemtype,
+ err)
+ esize = 'sizeof(%s)-sizeof(%s)+%s*sizeof(%s)' % (
+ cdecl(typename, ''),
+ itemtype,
+ elength,
+ itemtype)
+ result += self.gcpolicy.zero_malloc(TYPE, esize, eresult, err)
result += '\n%s->%s = %s;' % (eresult, lenfld, elength)
return result
Modified: pypy/dist/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/mem.h (original)
+++ pypy/dist/pypy/translator/c/src/mem.h Fri Oct 14 16:38:59 2005
@@ -3,6 +3,17 @@
/*** C header subsection: operations on LowLevelTypes ***/
+/* a reasonably safe bound on the largest allowed argument value
+ that we can pass to malloc. This is used for var-sized mallocs
+ to compute the largest allowed number of items in the array. */
+#define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096)
+
+#define OP_MAX_VARSIZE(numitems, itemtype, err) { \
+ if ((numitems) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \
+ FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \
+ }
+
+
/* XXX hack to initialize the refcount of global structures: officially,
we need a value equal to the number of references to this global from
other globals, plus one. This upper bound "approximation" will do... */
Modified: pypy/dist/pypy/translator/c/test/test_annotated.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_annotated.py (original)
+++ pypy/dist/pypy/translator/c/test/test_annotated.py Fri Oct 14 16:38:59 2005
@@ -1,5 +1,5 @@
import autopath
-import py
+import py, sys
from pypy.translator.tool.cbuild import skip_missing_compiler
from pypy.translator.translator import Translator
@@ -166,3 +166,14 @@
fn = self.getcompiled(f)
assert fn(-4.5) == 92.125
assert fn(4.5) == 90.125
+
+ def test_memoryerror(self):
+ def f(i=int):
+ lst = [0]*i
+ lst[-1] = 5
+ return lst[0]
+ fn = self.getcompiled(f)
+ assert fn(1) == 5
+ assert fn(2) == 0
+ py.test.raises(MemoryError, fn, sys.maxint//2+1)
+ py.test.raises(MemoryError, fn, sys.maxint)
More information about the Pypy-commit
mailing list