Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b333640

Browse files
committed
Issue #14127: Fix two bugs with the Windows implementation.
1 parent 009b15e commit b333640

1 file changed

Lines changed: 42 additions & 19 deletions

File tree

Modules/posixmodule.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3658,17 +3658,26 @@ typedef struct {
36583658
/*
36593659
* utime_read_time_arguments() processes arguments for the utime
36603660
* family of functions.
3661-
* returns zero on failure.
36623661
*/
3663-
static int
3662+
3663+
typedef enum {
3664+
utime_success = 0,
3665+
utime_parse_failure = 1,
3666+
utime_times_and_ns_collision = 2,
3667+
utime_times_conversion_failure = 3,
3668+
utime_ns_conversion_failure = 4,
3669+
} utime_status;
3670+
3671+
static utime_status
36643672
utime_read_time_arguments(utime_arguments *ua)
36653673
{
36663674
PyObject *times = NULL;
36673675
PyObject *ns = NULL;
36683676
char format[24];
36693677
char *kwlist[4];
36703678
char **kw = kwlist;
3671-
int return_value;
3679+
utime_status return_value;
3680+
int parse_result;
36723681

36733682
*kw++ = ua->first_argument_name;
36743683
*kw++ = "times";
@@ -3681,20 +3690,21 @@ utime_read_time_arguments(utime_arguments *ua)
36813690
ua->function_name);
36823691

36833692
if (ua->converter)
3684-
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
3693+
parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
36853694
format, kwlist, ua->converter, ua->path, &times, &ns);
36863695
else
3687-
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
3696+
parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
36883697
format, kwlist, ua->path, &times, &ns);
36893698

3690-
if (!return_value)
3691-
return 0;
3699+
if (!parse_result)
3700+
return utime_parse_failure;
36923701

36933702
if (times && ns) {
36943703
PyErr_Format(PyExc_RuntimeError,
36953704
"%s: you may specify either 'times'"
36963705
" or 'ns' but not both",
36973706
ua->function_name);
3707+
return_value = utime_times_and_ns_collision;
36983708
goto fail;
36993709
}
37003710

@@ -3704,41 +3714,47 @@ utime_read_time_arguments(utime_arguments *ua)
37043714
"%s: 'time' must be either"
37053715
" a tuple of two ints or None",
37063716
ua->function_name);
3717+
return_value = utime_times_conversion_failure;
37073718
goto fail;
37083719
}
37093720
ua->now = 0;
37103721
if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
37113722
&ua->atime_s, &ua->atime_ns) == -1 ||
37123723
_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
3713-
&ua->mtime_s, &ua->mtime_ns) == -1)
3724+
&ua->mtime_s, &ua->mtime_ns) == -1) {
3725+
return_value = utime_times_conversion_failure;
37143726
goto fail;
3715-
return 1;
3727+
}
3728+
return utime_success;
37163729
}
37173730

37183731
if (ns) {
37193732
if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
37203733
PyErr_Format(PyExc_TypeError,
37213734
"%s: 'ns' must be a tuple of two ints",
37223735
ua->function_name);
3736+
return_value = utime_ns_conversion_failure;
37233737
goto fail;
37243738
}
37253739
ua->now = 0;
37263740
if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
37273741
&ua->atime_s, &ua->atime_ns) ||
37283742
!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
3729-
&ua->mtime_s, &ua->mtime_ns))
3743+
&ua->mtime_s, &ua->mtime_ns)) {
3744+
return_value = utime_ns_conversion_failure;
37303745
goto fail;
3731-
return 1;
3746+
}
3747+
return utime_success;
37323748
}
37333749

37343750
/* either times=None, or neither times nor ns was specified. use "now". */
37353751
ua->now = 1;
3736-
return 1;
3752+
return utime_success;
37373753

37383754
fail:
37393755
if (ua->converter)
37403756
Py_DECREF(ua->path);
3741-
return 0;
3757+
return return_value;
37423758
}
37433759

37443760

@@ -3767,7 +3783,10 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
37673783
ua.path_format = 'U';
37683784
ua.path = &upath;
37693785

3770-
if (!utime_read_time_arguments(&ua)) {
3786+
switch (utime_read_time_arguments(&ua)) {
3787+
default:
3788+
return NULL;
3789+
case utime_success: {
37713790
wchar_t *wpath = PyUnicode_AsUnicode(upath);
37723791
if (wpath == NULL)
37733792
return NULL;
@@ -3778,16 +3797,17 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
37783797
Py_END_ALLOW_THREADS
37793798
if (hFile == INVALID_HANDLE_VALUE)
37803799
return win32_error_object("utime", upath);
3800+
break;
37813801
}
3782-
else {
3802+
case utime_parse_failure: {
37833803
const char *apath;
37843804
/* Drop the argument parsing error as narrow strings
37853805
are also valid. */
37863806
PyErr_Clear();
37873807

37883808
ua.path_format = 'y';
37893809
ua.path = (PyObject **)&apath;
3790-
if (!utime_read_time_arguments(&ua))
3810+
if (utime_read_time_arguments(&ua) != utime_success)
37913811
return NULL;
37923812
if (win32_warn_bytes_api())
37933813
return NULL;
@@ -3801,6 +3821,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
38013821
win32_error("utime", apath);
38023822
return NULL;
38033823
}
3824+
break;
3825+
}
3826+
38043827
}
38053828

38063829
if (ua.now) {
@@ -3839,7 +3862,7 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
38393862
ua.path = &opath;
38403863
ua.converter = PyUnicode_FSConverter;
38413864

3842-
if (!utime_read_time_arguments(&ua))
3865+
if (utime_read_time_arguments(&ua) != utime_success)
38433866
return NULL;
38443867
path = PyBytes_AsString(opath);
38453868
if (ua.now) {
@@ -3892,7 +3915,7 @@ posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs)
38923915
ua.path = (PyObject **)&fd;
38933916
ua.first_argument_name = "fd";
38943917

3895-
if (!utime_read_time_arguments(&ua))
3918+
if (utime_read_time_arguments(&ua) != utime_success)
38963919
return NULL;
38973920

38983921
if (ua.now) {
@@ -3937,7 +3960,7 @@ posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs)
39373960
ua.path = &opath;
39383961
ua.converter = PyUnicode_FSConverter;
39393962

3940-
if (!utime_read_time_arguments(&ua))
3963+
if (utime_read_time_arguments(&ua) != utime_success)
39413964
return NULL;
39423965
path = PyBytes_AsString(opath);
39433966

0 commit comments

Comments
 (0)