@@ -112,13 +112,17 @@ _is_fdescfs_mounted_on_dev_fd(void)
112112static int
113113_sanity_check_python_fd_sequence (PyObject * fd_sequence )
114114{
115- Py_ssize_t seq_idx , seq_len = PySequence_Length ( fd_sequence ) ;
115+ Py_ssize_t seq_idx ;
116116 long prev_fd = -1 ;
117- for (seq_idx = 0 ; seq_idx < seq_len ; ++ seq_idx ) {
118- PyObject * py_fd = PySequence_Fast_GET_ITEM (fd_sequence , seq_idx );
119- long iter_fd = PyLong_AsLong (py_fd );
117+ for (seq_idx = 0 ; seq_idx < PyTuple_GET_SIZE (fd_sequence ); ++ seq_idx ) {
118+ PyObject * py_fd = PyTuple_GET_ITEM (fd_sequence , seq_idx );
119+ long iter_fd ;
120+ if (!PyLong_Check (py_fd )) {
121+ return 1 ;
122+ }
123+ iter_fd = PyLong_AsLong (py_fd );
120124 if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX ) {
121- /* Negative, overflow, not a Long, unsorted, too big for a fd. */
125+ /* Negative, overflow, unsorted, too big for a fd. */
122126 return 1 ;
123127 }
124128 prev_fd = iter_fd ;
@@ -133,13 +137,12 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
133137{
134138 /* Binary search. */
135139 Py_ssize_t search_min = 0 ;
136- Py_ssize_t search_max = PySequence_Length (fd_sequence ) - 1 ;
140+ Py_ssize_t search_max = PyTuple_GET_SIZE (fd_sequence ) - 1 ;
137141 if (search_max < 0 )
138142 return 0 ;
139143 do {
140144 long middle = (search_min + search_max ) / 2 ;
141- long middle_fd = PyLong_AsLong (
142- PySequence_Fast_GET_ITEM (fd_sequence , middle ));
145+ long middle_fd = PyLong_AsLong (PyTuple_GET_ITEM (fd_sequence , middle ));
143146 if (fd == middle_fd )
144147 return 1 ;
145148 if (fd > middle_fd )
@@ -155,9 +158,9 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
155158{
156159 Py_ssize_t i , len ;
157160
158- len = PySequence_Length (py_fds_to_keep );
161+ len = PyTuple_GET_SIZE (py_fds_to_keep );
159162 for (i = 0 ; i < len ; ++ i ) {
160- PyObject * fdobj = PySequence_Fast_GET_ITEM (py_fds_to_keep , i );
163+ PyObject * fdobj = PyTuple_GET_ITEM (py_fds_to_keep , i );
161164 long fd = PyLong_AsLong (fdobj );
162165 assert (!PyErr_Occurred ());
163166 assert (0 <= fd && fd <= INT_MAX );
@@ -214,14 +217,13 @@ static void
214217_close_fds_by_brute_force (long start_fd , PyObject * py_fds_to_keep )
215218{
216219 long end_fd = safe_get_max_fd ();
217- Py_ssize_t num_fds_to_keep = PySequence_Length (py_fds_to_keep );
220+ Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE (py_fds_to_keep );
218221 Py_ssize_t keep_seq_idx ;
219222 int fd_num ;
220223 /* As py_fds_to_keep is sorted we can loop through the list closing
221224 * fds inbetween any in the keep list falling within our range. */
222225 for (keep_seq_idx = 0 ; keep_seq_idx < num_fds_to_keep ; ++ keep_seq_idx ) {
223- PyObject * py_keep_fd = PySequence_Fast_GET_ITEM (py_fds_to_keep ,
224- keep_seq_idx );
226+ PyObject * py_keep_fd = PyTuple_GET_ITEM (py_fds_to_keep , keep_seq_idx );
225227 int keep_fd = PyLong_AsLong (py_keep_fd );
226228 if (keep_fd < start_fd )
227229 continue ;
@@ -307,7 +309,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
307309
308310
309311/* Close all open file descriptors from start_fd and higher.
310- * Do not close any in the sorted py_fds_to_keep list .
312+ * Do not close any in the sorted py_fds_to_keep tuple .
311313 *
312314 * This function violates the strict use of async signal safe functions. :(
313315 * It calls opendir(), readdir() and closedir(). Of these, the one most
@@ -563,8 +565,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
563565#endif
564566
565567 if (!PyArg_ParseTuple (
566- args , "OOpOOOiiiiiiiiiiO:fork_exec" ,
567- & process_args , & executable_list , & close_fds , & py_fds_to_keep ,
568+ args , "OOpO!OOiiiiiiiiiiO:fork_exec" ,
569+ & process_args , & executable_list ,
570+ & close_fds , & PyTuple_Type , & py_fds_to_keep ,
568571 & cwd_obj , & env_list ,
569572 & p2cread , & p2cwrite , & c2pread , & c2pwrite ,
570573 & errread , & errwrite , & errpipe_read , & errpipe_write ,
@@ -575,10 +578,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
575578 PyErr_SetString (PyExc_ValueError , "errpipe_write must be >= 3" );
576579 return NULL ;
577580 }
578- if (PySequence_Length (py_fds_to_keep ) < 0 ) {
579- PyErr_SetString (PyExc_ValueError , "cannot get length of fds_to_keep" );
580- return NULL ;
581- }
582581 if (_sanity_check_python_fd_sequence (py_fds_to_keep )) {
583582 PyErr_SetString (PyExc_ValueError , "bad value(s) in fds_to_keep" );
584583 return NULL ;
@@ -632,6 +631,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
632631 goto cleanup ;
633632 for (arg_num = 0 ; arg_num < num_args ; ++ arg_num ) {
634633 PyObject * borrowed_arg , * converted_arg ;
634+ if (PySequence_Fast_GET_SIZE (fast_args ) != num_args ) {
635+ PyErr_SetString (PyExc_RuntimeError , "args changed during iteration" );
636+ goto cleanup ;
637+ }
635638 borrowed_arg = PySequence_Fast_GET_ITEM (fast_args , arg_num );
636639 if (PyUnicode_FSConverter (borrowed_arg , & converted_arg ) == 0 )
637640 goto cleanup ;
0 commit comments