[pypy-commit] pypy stdlib-2.7.6: clean up select overflow checking
bdkearns
noreply at buildbot.pypy.org
Sun Mar 2 16:29:49 CET 2014
Author: Brian Kearns <bdkearns at gmail.com>
Branch: stdlib-2.7.6
Changeset: r69615:5b6d13a5d362
Date: 2014-03-02 10:29 -0500
http://bitbucket.org/pypy/pypy/changeset/5b6d13a5d362/
Log: clean up select overflow checking
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -7,7 +7,8 @@
from rpython.rlib.objectmodel import (we_are_translated, newlist_hint,
compute_unique_id)
from rpython.rlib.signature import signature
-from rpython.rlib.rarithmetic import r_uint
+from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \
+ INT_MIN, INT_MAX, UINT_MAX
from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag,
UserDelAction)
@@ -18,8 +19,6 @@
__all__ = ['ObjSpace', 'OperationError', 'W_Root']
-UINT_MAX_32_BITS = r_uint(4294967295)
-
unpackiterable_driver = jit.JitDriver(name='unpackiterable',
greens=['tp'],
reds=['items', 'w_iterator'])
@@ -1466,7 +1465,7 @@
# Like space.gateway_int_w(), but raises an app-level OverflowError if
# the integer does not fit in 32 bits. Here for gateway.py.
value = self.gateway_int_w(w_obj)
- if value < -2147483647-1 or value > 2147483647:
+ if value < INT_MIN or value > INT_MAX:
raise OperationError(self.w_OverflowError,
self.wrap("expected a 32-bit integer"))
return value
@@ -1475,7 +1474,7 @@
# Like space.gateway_uint_w(), but raises an app-level OverflowError if
# the integer does not fit in 32 bits. Here for gateway.py.
value = self.uint_w(w_obj)
- if value > UINT_MAX_32_BITS:
+ if value > UINT_MAX:
raise OperationError(self.w_OverflowError,
self.wrap("expected an unsigned 32-bit integer"))
return value
@@ -1488,11 +1487,21 @@
if value < 0:
raise OperationError(self.w_ValueError,
self.wrap("expected a non-negative integer"))
- if value > 2147483647:
+ if value > INT_MAX:
raise OperationError(self.w_OverflowError,
self.wrap("expected a 32-bit integer"))
return value
+ def c_short_w(self, w_obj):
+ value = self.int_w(w_obj)
+ if value < SHRT_MIN:
+ raise oefmt(self.w_OverflowError,
+ "signed short integer is less than minimum")
+ elif value > SHRT_MAX:
+ raise oefmt(self.w_OverflowError,
+ "signed short integer is greater than maximum")
+ return value
+
def truncatedint_w(self, w_obj, allow_conversion=True):
# Like space.gateway_int_w(), but return the integer truncated
# instead of raising OverflowError. For obscure cases only.
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -147,6 +147,9 @@
def visit_c_nonnegint(self, el, app_sig):
self.checked_space_method(el, app_sig)
+ def visit_c_short(self, el, app_sig):
+ self.checked_space_method(el, app_sig)
+
def visit_truncatedint_w(self, el, app_sig):
self.checked_space_method(el, app_sig)
@@ -261,6 +264,9 @@
def visit_c_nonnegint(self, typ):
self.run_args.append("space.c_nonnegint_w(%s)" % (self.scopenext(),))
+ def visit_c_short(self, typ):
+ self.run_args.append("space.c_short_w(%s)" % (self.scopenext(),))
+
def visit_truncatedint_w(self, typ):
self.run_args.append("space.truncatedint_w(%s)" % (self.scopenext(),))
@@ -397,6 +403,9 @@
def visit_c_nonnegint(self, typ):
self.unwrap.append("space.c_nonnegint_w(%s)" % (self.nextarg(),))
+ def visit_c_short(self, typ):
+ self.unwrap.append("space.c_short_w(%s)" % (self.nextarg(),))
+
def visit_truncatedint_w(self, typ):
self.unwrap.append("space.truncatedint_w(%s)" % (self.nextarg(),))
diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py
--- a/pypy/module/select/interp_select.py
+++ b/pypy/module/select/interp_select.py
@@ -1,7 +1,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.interpreter.error import OperationError, wrap_oserror
+from pypy.interpreter.error import OperationError, wrap_oserror, oefmt
from rpython.rlib import rpoll
import errno
@@ -20,12 +20,8 @@
def __init__(self):
self.fddict = {}
- @unwrap_spec(events=int)
+ @unwrap_spec(events="c_short")
def register(self, space, w_fd, events=defaultevents):
- if not -32767 - 1 <= events <= 32767:
- m = ("signed short integer is " +
- "greater than maximum" if events > 0 else "less than minimum")
- raise OperationError(space.w_OverflowError, space.wrap(m))
fd = space.c_filedescriptor_w(w_fd)
self.fddict[fd] = events
@@ -53,15 +49,11 @@
# we want to be compatible with cpython and also accept things
# that can be casted to integer (I think)
try:
- # compute the integer
- timeout = space.int_w(space.int(w_timeout))
- except (OverflowError, ValueError):
- raise OperationError(space.w_ValueError,
- space.wrap("math range error"))
-
- if not -2147483647 - 1 <= timeout <= 2147483647:
- msg = "Python int too large to convert to C int"
- raise OperationError(space.w_OverflowError, space.wrap(msg))
+ w_timeout = space.int(w_timeout)
+ except OperationError:
+ raise oefmt(space.w_TypeError,
+ "timeout must be an integer or None")
+ timeout = space.c_int_w(w_timeout)
try:
retval = rpoll.poll(self.fddict, timeout)
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -213,7 +213,7 @@
readend.close()
writeend.close()
- def test_poll_int_overflow(self):
+ def test_poll_int_arguments(self):
import select
pollster = select.poll()
@@ -222,12 +222,16 @@
raises(OverflowError, pollster.poll, 1L << 64)
pollster = select.poll()
- raises(OverflowError, pollster.register, 0, 32768) # SHRT_MAX + 1
- raises(OverflowError, pollster.register, 0, -32768 - 1)
+ exc = raises(OverflowError, pollster.register, 0, 32768) # SHRT_MAX + 1
+ assert exc.value[0] == 'signed short integer is greater than maximum'
+ exc = raises(OverflowError, pollster.register, 0, -32768 - 1)
+ assert exc.value[0] == 'signed short integer is less than minimum'
raises(OverflowError, pollster.register, 0, 65535) # USHRT_MAX + 1
raises(OverflowError, pollster.poll, 2147483648) # INT_MAX + 1
raises(OverflowError, pollster.poll, -2147483648 - 1)
raises(OverflowError, pollster.poll, 4294967296) # UINT_MAX + 1
+ exc = raises(TypeError, pollster.poll, '123')
+ assert exc.value[0] == 'timeout must be an integer or None'
class AppTestSelectWithPipes(_AppTestSelect):
diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -75,7 +75,11 @@
# to handle the win64 special case:
is_emulated_long = _long_typecode != 'l'
+SHRT_MIN = -2**(_get_bitsize('h') - 1)
+SHRT_MAX = 2**(_get_bitsize('h') - 1) - 1
+INT_MIN = -2**(_get_bitsize('i') - 1)
INT_MAX = 2**(_get_bitsize('i') - 1) - 1
+UINT_MAX = 2**_get_bitsize('i') - 1
LONG_BIT = _get_long_bit()
LONG_MASK = (2**LONG_BIT)-1
More information about the pypy-commit
mailing list