@@ -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
36643672utime_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