Commit b333640a authored by Larry Hastings's avatar Larry Hastings

Issue #14127: Fix two bugs with the Windows implementation.

parent 009b15e2
...@@ -3658,9 +3658,17 @@ typedef struct { ...@@ -3658,9 +3658,17 @@ typedef struct {
/* /*
* utime_read_time_arguments() processes arguments for the utime * utime_read_time_arguments() processes arguments for the utime
* family of functions. * 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) utime_read_time_arguments(utime_arguments *ua)
{ {
PyObject *times = NULL; PyObject *times = NULL;
...@@ -3668,7 +3676,8 @@ utime_read_time_arguments(utime_arguments *ua) ...@@ -3668,7 +3676,8 @@ utime_read_time_arguments(utime_arguments *ua)
char format[24]; char format[24];
char *kwlist[4]; char *kwlist[4];
char **kw = kwlist; char **kw = kwlist;
int return_value; utime_status return_value;
int parse_result;
*kw++ = ua->first_argument_name; *kw++ = ua->first_argument_name;
*kw++ = "times"; *kw++ = "times";
...@@ -3681,20 +3690,21 @@ utime_read_time_arguments(utime_arguments *ua) ...@@ -3681,20 +3690,21 @@ utime_read_time_arguments(utime_arguments *ua)
ua->function_name); ua->function_name);
if (ua->converter) 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, &times, &ns); format, kwlist, ua->converter, ua->path, &times, &ns);
else else
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
format, kwlist, ua->path, &times, &ns); format, kwlist, ua->path, &times, &ns);
if (!return_value) if (!parse_result)
return 0; return utime_parse_failure;
if (times && ns) { if (times && ns) {
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"%s: you may specify either 'times'" "%s: you may specify either 'times'"
" or 'ns' but not both", " or 'ns' but not both",
ua->function_name); ua->function_name);
return_value = utime_times_and_ns_collision;
goto fail; goto fail;
} }
...@@ -3704,15 +3714,18 @@ utime_read_time_arguments(utime_arguments *ua) ...@@ -3704,15 +3714,18 @@ utime_read_time_arguments(utime_arguments *ua)
"%s: 'time' must be either" "%s: 'time' must be either"
" a tuple of two ints or None", " a tuple of two ints or None",
ua->function_name); ua->function_name);
return_value = utime_times_conversion_failure;
goto fail; goto fail;
} }
ua->now = 0; ua->now = 0;
if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
&ua->atime_s, &ua->atime_ns) == -1 || &ua->atime_s, &ua->atime_ns) == -1 ||
_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 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; goto fail;
return 1; }
return utime_success;
} }
if (ns) { if (ns) {
...@@ -3720,25 +3733,28 @@ utime_read_time_arguments(utime_arguments *ua) ...@@ -3720,25 +3733,28 @@ utime_read_time_arguments(utime_arguments *ua)
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%s: 'ns' must be a tuple of two ints", "%s: 'ns' must be a tuple of two ints",
ua->function_name); ua->function_name);
return_value = utime_ns_conversion_failure;
goto fail; goto fail;
} }
ua->now = 0; ua->now = 0;
if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
&ua->atime_s, &ua->atime_ns) || &ua->atime_s, &ua->atime_ns) ||
!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), !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; goto fail;
return 1; }
return utime_success;
} }
/* either times=None, or neither times nor ns was specified. use "now". */ /* either times=None, or neither times nor ns was specified. use "now". */
ua->now = 1; ua->now = 1;
return 1; return utime_success;
fail: fail:
if (ua->converter) if (ua->converter)
Py_DECREF(ua->path); Py_DECREF(ua->path);
return 0; return return_value;
} }
...@@ -3767,7 +3783,10 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3767,7 +3783,10 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
ua.path_format = 'U'; ua.path_format = 'U';
ua.path = &upath; 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); wchar_t *wpath = PyUnicode_AsUnicode(upath);
if (wpath == NULL) if (wpath == NULL)
return NULL; return NULL;
...@@ -3778,8 +3797,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3778,8 +3797,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return win32_error_object("utime", upath); return win32_error_object("utime", upath);
break;
} }
else { case utime_parse_failure: {
const char *apath; const char *apath;
/* Drop the argument parsing error as narrow strings /* Drop the argument parsing error as narrow strings
are also valid. */ are also valid. */
...@@ -3787,7 +3807,7 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3787,7 +3807,7 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
ua.path_format = 'y'; ua.path_format = 'y';
ua.path = (PyObject **)&apath; ua.path = (PyObject **)&apath;
if (!utime_read_time_arguments(&ua)) if (utime_read_time_arguments(&ua) != utime_success)
return NULL; return NULL;
if (win32_warn_bytes_api()) if (win32_warn_bytes_api())
return NULL; return NULL;
...@@ -3801,6 +3821,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3801,6 +3821,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
win32_error("utime", apath); win32_error("utime", apath);
return NULL; return NULL;
} }
break;
}
} }
if (ua.now) { if (ua.now) {
...@@ -3839,7 +3862,7 @@ done: ...@@ -3839,7 +3862,7 @@ done:
ua.path = &opath; ua.path = &opath;
ua.converter = PyUnicode_FSConverter; ua.converter = PyUnicode_FSConverter;
if (!utime_read_time_arguments(&ua)) if (utime_read_time_arguments(&ua) != utime_success)
return NULL; return NULL;
path = PyBytes_AsString(opath); path = PyBytes_AsString(opath);
if (ua.now) { if (ua.now) {
...@@ -3892,7 +3915,7 @@ posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3892,7 +3915,7 @@ posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs)
ua.path = (PyObject **)&fd; ua.path = (PyObject **)&fd;
ua.first_argument_name = "fd"; ua.first_argument_name = "fd";
if (!utime_read_time_arguments(&ua)) if (utime_read_time_arguments(&ua) != utime_success)
return NULL; return NULL;
if (ua.now) { if (ua.now) {
...@@ -3937,7 +3960,7 @@ posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3937,7 +3960,7 @@ posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs)
ua.path = &opath; ua.path = &opath;
ua.converter = PyUnicode_FSConverter; ua.converter = PyUnicode_FSConverter;
if (!utime_read_time_arguments(&ua)) if (utime_read_time_arguments(&ua) != utime_success)
return NULL; return NULL;
path = PyBytes_AsString(opath); path = PyBytes_AsString(opath);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment