@@ -111,13 +111,17 @@ _is_fdescfs_mounted_on_dev_fd(void)
111111static int
112112_sanity_check_python_fd_sequence (PyObject * fd_sequence )
113113{
114- Py_ssize_t seq_idx , seq_len = PySequence_Length ( fd_sequence ) ;
114+ Py_ssize_t seq_idx ;
115115 long prev_fd = -1 ;
116- for (seq_idx = 0 ; seq_idx < seq_len ; ++ seq_idx ) {
117- PyObject * py_fd = PySequence_Fast_GET_ITEM (fd_sequence , seq_idx );
118- long iter_fd = PyLong_AsLong (py_fd );
116+ for (seq_idx = 0 ; seq_idx < PyTuple_GET_SIZE (fd_sequence ); ++ seq_idx ) {
117+ PyObject * py_fd = PyTuple_GET_ITEM (fd_sequence , seq_idx );
118+ long iter_fd ;
119+ if (!PyLong_Check (py_fd )) {
120+ return 1 ;
121+ }
122+ iter_fd = PyLong_AsLong (py_fd );
119123 if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX ) {
120- /* Negative, overflow, not a Long, unsorted, too big for a fd. */
124+ /* Negative, overflow, unsorted, too big for a fd. */
121125 return 1 ;
122126 }
123127 prev_fd = iter_fd ;
@@ -132,13 +136,12 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
132136{
133137 /* Binary search. */
134138 Py_ssize_t search_min = 0 ;
135- Py_ssize_t search_max = PySequence_Length (fd_sequence ) - 1 ;
139+ Py_ssize_t search_max = PyTuple_GET_SIZE (fd_sequence ) - 1 ;
136140 if (search_max < 0 )
137141 return 0 ;
138142 do {
139143 long middle = (search_min + search_max ) / 2 ;
140- long middle_fd = PyLong_AsLong (
141- PySequence_Fast_GET_ITEM (fd_sequence , middle ));
144+ long middle_fd = PyLong_AsLong (PyTuple_GET_ITEM (fd_sequence , middle ));
142145 if (fd == middle_fd )
143146 return 1 ;
144147 if (fd > middle_fd )
@@ -154,9 +157,9 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
154157{
155158 Py_ssize_t i , len ;
156159
157- len = PySequence_Length (py_fds_to_keep );
160+ len = PyTuple_GET_SIZE (py_fds_to_keep );
158161 for (i = 0 ; i < len ; ++ i ) {
159- PyObject * fdobj = PySequence_Fast_GET_ITEM (py_fds_to_keep , i );
162+ PyObject * fdobj = PyTuple_GET_ITEM (py_fds_to_keep , i );
160163 long fd = PyLong_AsLong (fdobj );
161164 assert (!PyErr_Occurred ());
162165 assert (0 <= fd && fd <= INT_MAX );
@@ -213,14 +216,13 @@ static void
213216_close_fds_by_brute_force (long start_fd , PyObject * py_fds_to_keep )
214217{
215218 long end_fd = safe_get_max_fd ();
216- Py_ssize_t num_fds_to_keep = PySequence_Length (py_fds_to_keep );
219+ Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE (py_fds_to_keep );
217220 Py_ssize_t keep_seq_idx ;
218221 int fd_num ;
219222 /* As py_fds_to_keep is sorted we can loop through the list closing
220223 * fds inbetween any in the keep list falling within our range. */
221224 for (keep_seq_idx = 0 ; keep_seq_idx < num_fds_to_keep ; ++ keep_seq_idx ) {
222- PyObject * py_keep_fd = PySequence_Fast_GET_ITEM (py_fds_to_keep ,
223- keep_seq_idx );
225+ PyObject * py_keep_fd = PyTuple_GET_ITEM (py_fds_to_keep , keep_seq_idx );
224226 int keep_fd = PyLong_AsLong (py_keep_fd );
225227 if (keep_fd < start_fd )
226228 continue ;
@@ -306,7 +308,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
306308
307309
308310/* Close all open file descriptors from start_fd and higher.
309- * Do not close any in the sorted py_fds_to_keep list .
311+ * Do not close any in the sorted py_fds_to_keep tuple .
310312 *
311313 * This function violates the strict use of async signal safe functions. :(
312314 * It calls opendir(), readdir() and closedir(). Of these, the one most
@@ -562,8 +564,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
562564#endif
563565
564566 if (!PyArg_ParseTuple (
565- args , "OOpOOOiiiiiiiiiiO:fork_exec" ,
566- & process_args , & executable_list , & close_fds , & py_fds_to_keep ,
567+ args , "OOpO!OOiiiiiiiiiiO:fork_exec" ,
568+ & process_args , & executable_list ,
569+ & close_fds , & PyTuple_Type , & py_fds_to_keep ,
567570 & cwd_obj , & env_list ,
568571 & p2cread , & p2cwrite , & c2pread , & c2pwrite ,
569572 & errread , & errwrite , & errpipe_read , & errpipe_write ,
@@ -574,10 +577,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
574577 PyErr_SetString (PyExc_ValueError , "errpipe_write must be >= 3" );
575578 return NULL ;
576579 }
577- if (PySequence_Length (py_fds_to_keep ) < 0 ) {
578- PyErr_SetString (PyExc_ValueError , "cannot get length of fds_to_keep" );
579- return NULL ;
580- }
581580 if (_sanity_check_python_fd_sequence (py_fds_to_keep )) {
582581 PyErr_SetString (PyExc_ValueError , "bad value(s) in fds_to_keep" );
583582 return NULL ;
@@ -631,6 +630,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
631630 goto cleanup ;
632631 for (arg_num = 0 ; arg_num < num_args ; ++ arg_num ) {
633632 PyObject * borrowed_arg , * converted_arg ;
633+ if (PySequence_Fast_GET_SIZE (fast_args ) != num_args ) {
634+ PyErr_SetString (PyExc_RuntimeError , "args changed during iteration" );
635+ goto cleanup ;
636+ }
634637 borrowed_arg = PySequence_Fast_GET_ITEM (fast_args , arg_num );
635638 if (PyUnicode_FSConverter (borrowed_arg , & converted_arg ) == 0 )
636639 goto cleanup ;
0 commit comments