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

This commit is contained in:
Larry Hastings 2012-05-04 02:31:57 -07:00
parent 009b15e2c3
commit b333640aba
1 changed files with 42 additions and 19 deletions

View File

@ -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, &times, &ns);
else
return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
format, kwlist, ua->path, &times, &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);