Skip to content

Commit 329ea4e

Browse files
bpo-31577: Fix a crash in os.utime() in case of a bad ns argument. (GH-3752)
(cherry picked from commit 0bd1a2d) Co-authored-by: Oren Milman <[email protected]>
1 parent 72c34cf commit 329ea4e

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

Lib/test/test_os.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,22 @@ def test_utime_invalid_arguments(self):
635635
with self.assertRaises(ValueError):
636636
os.utime(self.fname, (5, 5), ns=(5, 5))
637637

638+
@support.cpython_only
639+
def test_issue31577(self):
640+
# The interpreter shouldn't crash in case utime() received a bad
641+
# ns argument.
642+
def get_bad_int(divmod_ret_val):
643+
class BadInt:
644+
def __divmod__(*args):
645+
return divmod_ret_val
646+
return BadInt()
647+
with self.assertRaises(TypeError):
648+
os.utime(self.fname, ns=(get_bad_int(42), 1))
649+
with self.assertRaises(TypeError):
650+
os.utime(self.fname, ns=(get_bad_int(()), 1))
651+
with self.assertRaises(TypeError):
652+
os.utime(self.fname, ns=(get_bad_int((1, 2, 3)), 1))
653+
638654

639655
from test import mapping_tests
640656

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in `os.utime()` in case of a bad ns argument. Patch by Oren
2+
Milman.

Modules/posixmodule.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,6 +4563,12 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
45634563
divmod = PyNumber_Divmod(py_long, billion);
45644564
if (!divmod)
45654565
goto exit;
4566+
if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4567+
PyErr_Format(PyExc_TypeError,
4568+
"%.200s.__divmod__() must return a 2-tuple, not %.200s",
4569+
Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4570+
goto exit;
4571+
}
45664572
*s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
45674573
if ((*s == -1) && PyErr_Occurred())
45684574
goto exit;

0 commit comments

Comments
 (0)