Issue #14127: Fix two bugs with the Windows implementation.
This commit is contained in:
parent
009b15e2c3
commit
b333640aba
|
@ -3658,9 +3658,17 @@ typedef struct {
|
|||
/*
|
||||
* utime_read_time_arguments() processes arguments for the utime
|
||||
* family of functions.
|
||||
* returns zero on failure.
|
||||
*/
|
||||
static int
|
||||
|
||||
typedef enum {
|
||||
utime_success = 0,
|
||||
utime_parse_failure = 1,
|
||||
utime_times_and_ns_collision = 2,
|
||||
utime_times_conversion_failure = 3,
|
||||
utime_ns_conversion_failure = 4,
|
||||
} utime_status;
|
||||
|
||||
static utime_status
|
||||
utime_read_time_arguments(utime_arguments *ua)
|
||||
{
|
||||
PyObject *times = NULL;
|
||||
|
@ -3668,7 +3676,8 @@ utime_read_time_arguments(utime_arguments *ua)
|
|||
char format[24];
|
||||
char *kwlist[4];
|
||||
char **kw = kwlist;
|
||||
int return_value;
|
||||
utime_status return_value;
|
||||
int parse_result;
|
||||
|
||||
*kw++ = ua->first_argument_name;
|
||||
*kw++ = "times";
|
||||
|
@ -3681,20 +3690,21 @@ utime_read_time_arguments(utime_arguments *ua)
|
|||
ua->function_name);
|
||||
|
||||
if (ua->converter)
|
||||
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
|
||||
parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
|
||||
format, kwlist, ua->converter, ua->path, ×, &ns);
|
||||
else
|
||||
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
|
||||
parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
|
||||
format, kwlist, ua->path, ×, &ns);
|
||||
|
||||
if (!return_value)
|
||||
return 0;
|
||||
if (!parse_result)
|
||||
return utime_parse_failure;
|
||||
|
||||
if (times && ns) {
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"%s: you may specify either 'times'"
|
||||
" or 'ns' but not both",
|
||||
ua->function_name);
|
||||
return_value = utime_times_and_ns_collision;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -3704,15 +3714,18 @@ utime_read_time_arguments(utime_arguments *ua)
|
|||
"%s: 'time' must be either"
|
||||
" a tuple of two ints or None",
|
||||
ua->function_name);
|
||||
return_value = utime_times_conversion_failure;
|
||||
goto fail;
|
||||
}
|
||||
ua->now = 0;
|
||||
if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
|
||||
&ua->atime_s, &ua->atime_ns) == -1 ||
|
||||
_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
|
||||
&ua->mtime_s, &ua->mtime_ns) == -1)
|
||||
&ua->mtime_s, &ua->mtime_ns) == -1) {
|
||||
return_value = utime_times_conversion_failure;
|
||||
goto fail;
|
||||
return 1;
|
||||
}
|
||||
return utime_success;
|
||||
}
|
||||
|
||||
if (ns) {
|
||||
|
@ -3720,25 +3733,28 @@ utime_read_time_arguments(utime_arguments *ua)
|
|||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: 'ns' must be a tuple of two ints",
|
||||
ua->function_name);
|
||||
return_value = utime_ns_conversion_failure;
|
||||
goto fail;
|
||||
}
|
||||
ua->now = 0;
|
||||
if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
|
||||
&ua->atime_s, &ua->atime_ns) ||
|
||||
!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
|
||||
&ua->mtime_s, &ua->mtime_ns))
|
||||
&ua->mtime_s, &ua->mtime_ns)) {
|
||||
return_value = utime_ns_conversion_failure;
|
||||
goto fail;
|
||||
return 1;
|
||||
}
|
||||
return utime_success;
|
||||
}
|
||||
|
||||
/* either times=None, or neither times nor ns was specified. use "now". */
|
||||
ua->now = 1;
|
||||
return 1;
|
||||
return utime_success;
|
||||
|
||||
fail:
|
||||
if (ua->converter)
|
||||
Py_DECREF(ua->path);
|
||||
return 0;
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3767,7 +3783,10 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
ua.path_format = 'U';
|
||||
ua.path = &upath;
|
||||
|
||||
if (!utime_read_time_arguments(&ua)) {
|
||||
switch (utime_read_time_arguments(&ua)) {
|
||||
default:
|
||||
return NULL;
|
||||
case utime_success: {
|
||||
wchar_t *wpath = PyUnicode_AsUnicode(upath);
|
||||
if (wpath == NULL)
|
||||
return NULL;
|
||||
|
@ -3778,8 +3797,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
Py_END_ALLOW_THREADS
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return win32_error_object("utime", upath);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
case utime_parse_failure: {
|
||||
const char *apath;
|
||||
/* Drop the argument parsing error as narrow strings
|
||||
are also valid. */
|
||||
|
@ -3787,7 +3807,7 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
|
||||
ua.path_format = 'y';
|
||||
ua.path = (PyObject **)&apath;
|
||||
if (!utime_read_time_arguments(&ua))
|
||||
if (utime_read_time_arguments(&ua) != utime_success)
|
||||
return NULL;
|
||||
if (win32_warn_bytes_api())
|
||||
return NULL;
|
||||
|
@ -3801,6 +3821,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
win32_error("utime", apath);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ua.now) {
|
||||
|
@ -3839,7 +3862,7 @@ done:
|
|||
ua.path = &opath;
|
||||
ua.converter = PyUnicode_FSConverter;
|
||||
|
||||
if (!utime_read_time_arguments(&ua))
|
||||
if (utime_read_time_arguments(&ua) != utime_success)
|
||||
return NULL;
|
||||
path = PyBytes_AsString(opath);
|
||||
if (ua.now) {
|
||||
|
@ -3892,7 +3915,7 @@ posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
ua.path = (PyObject **)&fd;
|
||||
ua.first_argument_name = "fd";
|
||||
|
||||
if (!utime_read_time_arguments(&ua))
|
||||
if (utime_read_time_arguments(&ua) != utime_success)
|
||||
return NULL;
|
||||
|
||||
if (ua.now) {
|
||||
|
@ -3937,7 +3960,7 @@ posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
ua.path = &opath;
|
||||
ua.converter = PyUnicode_FSConverter;
|
||||
|
||||
if (!utime_read_time_arguments(&ua))
|
||||
if (utime_read_time_arguments(&ua) != utime_success)
|
||||
return NULL;
|
||||
path = PyBytes_AsString(opath);
|
||||
|
||||
|
|
Loading…
Reference in New Issue