Skip to content

bpo-34373: fix test_mktime and test_pthread_getcpuclickid tests on AIX #8726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions Lib/test/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,13 @@ def test_clock_monotonic(self):
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)
Expand Down Expand Up @@ -431,13 +437,6 @@ def test_localtime_without_arg(self):
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):
Expand Down
Original file line number Diff line number Diff line change
@@ -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
45 changes: 33 additions & 12 deletions Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -940,35 +945,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");
Expand Down
14 changes: 14 additions & 0 deletions Python/pytime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down