summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2012-05-04 09:31:57 (GMT)
committerLarry Hastings <larry@hastings.org>2012-05-04 09:31:57 (GMT)
commitb333640aba212e8f2b70fd5038fe160492666dca (patch)
tree3a7987321850c57268f853e58c1f486477b769e7 /Modules
parent009b15e2c3e3e1f85cf7992893eefb8bc33e5a34 (diff)
downloadcpython-b333640aba212e8f2b70fd5038fe160492666dca.zip
cpython-b333640aba212e8f2b70fd5038fe160492666dca.tar.gz
cpython-b333640aba212e8f2b70fd5038fe160492666dca.tar.bz2
Issue #14127: Fix two bugs with the Windows implementation.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/posixmodule.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 6cabe37..2dbfec1 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -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);