summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Felt <aixtools@users.noreply.github.com>2018-12-28 13:57:37 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2018-12-28 13:57:37 (GMT)
commite2926b72488596f59e43c27f3b7cedf0c5b9e88e (patch)
treedc8a3af47e822ffc6573726decb9c8dd75e6af7a
parentc465682718f15cd3deb6b37db5fb607718ac64ed (diff)
downloadcpython-e2926b72488596f59e43c27f3b7cedf0c5b9e88e.zip
cpython-e2926b72488596f59e43c27f3b7cedf0c5b9e88e.tar.gz
cpython-e2926b72488596f59e43c27f3b7cedf0c5b9e88e.tar.bz2
bpo-34373: fix test_mktime and test_pthread_getcpuclickid tests on AIX (GH-8726)
* Fix test_mktime on AIX by adding code to get mktime to behave the same way as it does on other *nix systems * Fix test_pthread_getcpuclickid in AIX by adjusting the test case expectations when running on AIX in 32-bit mode Patch by Michael Felt.
-rw-r--r--Lib/test/test_time.py15
-rw-r--r--Misc/NEWS.d/next/Tests/2018-08-10-16-17-51.bpo-34373.SKdb1k.rst3
-rw-r--r--Modules/timemodule.c45
-rw-r--r--Python/pytime.c14
4 files changed, 57 insertions, 20 deletions
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 2f0665a..136ad29 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -119,7 +119,13 @@ class TimeTestCase(unittest.TestCase):
def test_pthread_getcpuclockid(self):
clk_id = time.pthread_getcpuclockid(threading.get_ident())
self.assertTrue(type(clk_id) is int)
- self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+ # when in 32-bit mode AIX only returns the predefined constant
+ if not platform.system() == "AIX":
+ self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+ elif (sys.maxsize.bit_length() > 32):
+ self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+ else:
+ self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
t1 = time.clock_gettime(clk_id)
t2 = time.clock_gettime(clk_id)
self.assertLessEqual(t1, t2)
@@ -424,13 +430,6 @@ class TimeTestCase(unittest.TestCase):
def test_mktime(self):
# Issue #1726687
for t in (-2, -1, 0, 1):
- if sys.platform.startswith('aix') and t == -1:
- # Issue #11188, #19748: mktime() returns -1 on error. On Linux,
- # the tm_wday field is used as a sentinel () to detect if -1 is
- # really an error or a valid timestamp. On AIX, tm_wday is
- # unchanged even on success and so cannot be used as a
- # sentinel.
- continue
try:
tt = time.localtime(t)
except (OverflowError, OSError):
diff --git a/Misc/NEWS.d/next/Tests/2018-08-10-16-17-51.bpo-34373.SKdb1k.rst b/Misc/NEWS.d/next/Tests/2018-08-10-16-17-51.bpo-34373.SKdb1k.rst
new file mode 100644
index 0000000..1df5449
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2018-08-10-16-17-51.bpo-34373.SKdb1k.rst
@@ -0,0 +1,3 @@
+Fix ``test_mktime`` and ``test_pthread_getcpuclickid`` tests for AIX
+Add range checking for ``_PyTime_localtime`` for AIX
+Patch by Michael Felt
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 01bb430..cf65229 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -174,10 +174,15 @@ static PyObject *
time_clock_gettime(PyObject *self, PyObject *args)
{
int ret;
- int clk_id;
struct timespec tp;
+#if defined(_AIX) && (SIZEOF_LONG == 8)
+ long clk_id;
+ if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) {
+#else
+ int clk_id;
if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
+#endif
return NULL;
}
@@ -972,35 +977,51 @@ time_mktime(PyObject *self, PyObject *tup)
{
struct tm buf;
time_t tt;
+#ifdef _AIX
+ time_t clk;
+ int year = buf.tm_year;
+ int delta_days = 0;
+#endif
+
if (!gettmarg(tup, &buf,
"iiiiiiiii;mktime(): illegal time tuple argument"))
{
return NULL;
}
-#ifdef _AIX
+#ifndef _AIX
+ buf.tm_wday = -1; /* sentinel; original value ignored */
+ tt = mktime(&buf);
+#else
/* year < 1902 or year > 2037 */
- if (buf.tm_year < 2 || buf.tm_year > 137) {
+ if ((buf.tm_year < 2) || (buf.tm_year > 137)) {
/* Issue #19748: On AIX, mktime() doesn't report overflow error for
* timestamp < -2^31 or timestamp > 2**31-1. */
PyErr_SetString(PyExc_OverflowError,
"mktime argument out of range");
return NULL;
}
-#else
- buf.tm_wday = -1; /* sentinel; original value ignored */
+ year = buf.tm_year;
+ /* year < 1970 - adjust buf.tm_year into legal range */
+ while (buf.tm_year < 70) {
+ buf.tm_year += 4;
+ delta_days -= (366 + (365 * 3));
+ }
+
+ buf.tm_wday = -1;
+ clk = mktime(&buf);
+ buf.tm_year = year;
+
+ if ((buf.tm_wday != -1) && delta_days)
+ buf.tm_wday = (buf.tm_wday + delta_days) % 7;
+
+ tt = clk + (delta_days * (24 * 3600));
#endif
- tt = mktime(&buf);
/* Return value of -1 does not necessarily mean an error, but tm_wday
* cannot remain set to -1 if mktime succeeded. */
if (tt == (time_t)(-1)
-#ifndef _AIX
/* Return value of -1 does not necessarily mean an error, but
* tm_wday cannot remain set to -1 if mktime succeeded. */
- && buf.tm_wday == -1
-#else
- /* on AIX, tm_wday is always sets, even on error */
-#endif
- )
+ && buf.tm_wday == -1)
{
PyErr_SetString(PyExc_OverflowError,
"mktime argument out of range");
diff --git a/Python/pytime.c b/Python/pytime.c
index 0e94131..68c49a8 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -1062,6 +1062,20 @@ _PyTime_localtime(time_t t, struct tm *tm)
}
return 0;
#else /* !MS_WINDOWS */
+#ifdef _AIX
+ /* AIX does not return NULL on an error
+ so test ranges - asif!
+ (1902-01-01, -2145916800.0)
+ (2038-01-01, 2145916800.0) */
+ if (abs(t) > (time_t) 2145916800) {
+#ifdef EINVAL
+ errno = EINVAL;
+#endif
+ PyErr_SetString(PyExc_OverflowError,
+ "ctime argument out of range");
+ return -1;
+ }
+#endif
if (localtime_r(&t, tm) == NULL) {
#ifdef EINVAL
if (errno == 0) {