@@ -112,13 +112,17 @@ _is_fdescfs_mounted_on_dev_fd(void)
112
112
static int
113
113
_sanity_check_python_fd_sequence (PyObject * fd_sequence )
114
114
{
115
- Py_ssize_t seq_idx , seq_len = PySequence_Length ( fd_sequence ) ;
115
+ Py_ssize_t seq_idx ;
116
116
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 );
120
124
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. */
122
126
return 1 ;
123
127
}
124
128
prev_fd = iter_fd ;
@@ -133,13 +137,12 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
133
137
{
134
138
/* Binary search. */
135
139
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 ;
137
141
if (search_max < 0 )
138
142
return 0 ;
139
143
do {
140
144
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 ));
143
146
if (fd == middle_fd )
144
147
return 1 ;
145
148
if (fd > middle_fd )
@@ -155,9 +158,9 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
155
158
{
156
159
Py_ssize_t i , len ;
157
160
158
- len = PySequence_Length (py_fds_to_keep );
161
+ len = PyTuple_GET_SIZE (py_fds_to_keep );
159
162
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 );
161
164
long fd = PyLong_AsLong (fdobj );
162
165
assert (!PyErr_Occurred ());
163
166
assert (0 <= fd && fd <= INT_MAX );
@@ -214,14 +217,13 @@ static void
214
217
_close_fds_by_brute_force (long start_fd , PyObject * py_fds_to_keep )
215
218
{
216
219
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 );
218
221
Py_ssize_t keep_seq_idx ;
219
222
int fd_num ;
220
223
/* As py_fds_to_keep is sorted we can loop through the list closing
221
224
* fds inbetween any in the keep list falling within our range. */
222
225
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 );
225
227
int keep_fd = PyLong_AsLong (py_keep_fd );
226
228
if (keep_fd < start_fd )
227
229
continue ;
@@ -307,7 +309,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
307
309
308
310
309
311
/* 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 .
311
313
*
312
314
* This function violates the strict use of async signal safe functions. :(
313
315
* It calls opendir(), readdir() and closedir(). Of these, the one most
@@ -563,8 +565,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
563
565
#endif
564
566
565
567
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 ,
568
571
& cwd_obj , & env_list ,
569
572
& p2cread , & p2cwrite , & c2pread , & c2pwrite ,
570
573
& errread , & errwrite , & errpipe_read , & errpipe_write ,
@@ -575,10 +578,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
575
578
PyErr_SetString (PyExc_ValueError , "errpipe_write must be >= 3" );
576
579
return NULL ;
577
580
}
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
- }
582
581
if (_sanity_check_python_fd_sequence (py_fds_to_keep )) {
583
582
PyErr_SetString (PyExc_ValueError , "bad value(s) in fds_to_keep" );
584
583
return NULL ;
@@ -632,6 +631,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
632
631
goto cleanup ;
633
632
for (arg_num = 0 ; arg_num < num_args ; ++ arg_num ) {
634
633
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
+ }
635
638
borrowed_arg = PySequence_Fast_GET_ITEM (fast_args , arg_num );
636
639
if (PyUnicode_FSConverter (borrowed_arg , & converted_arg ) == 0 )
637
640
goto cleanup ;
0 commit comments