[pypy-commit] pypy py3k: have asctime make the same bounds checks as strftime

pjenvey noreply at buildbot.pypy.org
Fri Mar 29 05:13:08 CET 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r62863:03b22d5b87f0
Date: 2013-03-28 21:09 -0700
http://bitbucket.org/pypy/pypy/changeset/03b22d5b87f0/

Log:	have asctime make the same bounds checks as strftime

diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -446,7 +446,7 @@
                        space.w_DeprecationWarning)
 
     # tm_wday does not need checking of its upper-bound since taking "%
-    #  7" in gettmarg() automatically restricts the range.
+    #  7" in _gettmarg() automatically restricts the range.
     if rffi.getintfield(glob_buf, 'c_tm_wday') < -1:
         raise OperationError(space.w_ValueError,
                              space.wrap("day of week out of range"))
@@ -461,6 +461,32 @@
 
     return glob_buf
 
+def _checktm(space, t_ref):
+    """Checks added to make sure strftime() and asctime() do not crash
+    Python by indexing blindly into some array for a textual
+    representation by some bad index (fixes bug #897625).  No check for
+    year or wday since handled in _gettmarg()."""
+    if not 0 <= rffi.getintfield(t_ref, 'c_tm_mon') <= 11:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("month out of range"))
+    if not 1 <= rffi.getintfield(t_ref, 'c_tm_mday') <= 31:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("day of month out of range"))
+    if not 0 <= rffi.getintfield(t_ref, 'c_tm_hour') <= 23:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("hour out of range"))
+    if not 0 <= rffi.getintfield(t_ref, 'c_tm_min') <= 59:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("minute out of range"))
+    if not 0 <= rffi.getintfield(t_ref, 'c_tm_sec') <= 61:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("seconds out of range"))
+    # tm_wday does not need checking: "% 7" in _gettmarg() automatically
+    # restricts the range
+    if not 0 <= rffi.getintfield(t_ref, 'c_tm_yday') <= 365:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("day of year out of range"))
+
 def time(space):
     """time() -> floating point number
 
@@ -511,6 +537,7 @@
     When the time tuple is not present, current time as returned by localtime()
     is used."""
     buf_value = _gettmarg(space, w_tup)
+    _checktm(space, buf_value)
     return _asctime(space, buf_value)
 
 _wday_names = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
@@ -611,29 +638,8 @@
     See the library reference manual for formatting codes. When the time tuple
     is not present, current time as returned by localtime() is used."""
     buf_value = _gettmarg(space, w_tup)
+    _checktm(space, buf_value)
 
-    # Checks added to make sure strftime() does not crash Python by
-    # indexing blindly into some array for a textual representation
-    # by some bad index (fixes bug #897625).
-    # No check for year since handled in gettmarg().
-    if rffi.getintfield(buf_value, 'c_tm_mon') < 0 or rffi.getintfield(buf_value, 'c_tm_mon') > 11:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("month out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_mday') < 1 or rffi.getintfield(buf_value, 'c_tm_mday') > 31:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of month out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_hour') < 0 or rffi.getintfield(buf_value, 'c_tm_hour') > 23:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("hour out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_min') < 0 or rffi.getintfield(buf_value, 'c_tm_min') > 59:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("minute out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_sec') < 0 or rffi.getintfield(buf_value, 'c_tm_sec') > 61:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("seconds out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_yday') < 0 or rffi.getintfield(buf_value, 'c_tm_yday') > 365:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of year out of range"))
     # Normalize tm_isdst just in case someone foolishly implements %Z
     # based on the assumption that tm_isdst falls within the range of
     # [-1, 1]
diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -138,6 +138,7 @@
         raises(TypeError, rctime.asctime, (1, 2))
         raises(TypeError, rctime.asctime, (1, 2, 3, 4, 5, 6, 'f', 8, 9))
         raises(TypeError, rctime.asctime, "foo")
+        raises(ValueError, rctime.asctime, (1900, -1, 1, 0, 0, 0, 0, 1, -1))
         res = rctime.asctime()
         assert isinstance(res, str)
         rctime.asctime(rctime.localtime())


More information about the pypy-commit mailing list