List of commits:
Subject Hash Author Date (UTC)
bpo-30065: Fixed arguments validation in _posixsubprocess.fork_exec(). (#1110) 66bffd1663489d080349debbf1b472d432351038 Serhiy Storchaka 2017-04-19 18:12:46
bpo-30070: Fixed leaks and crashes in errors handling in the parser module. (#1131) a79f4c219531c05fc8f670c1e4bbf12c081935d3 Serhiy Storchaka 2017-04-19 18:09:21
bpo-22352: Adjust widths in the output of dis.dis() for large line numbers and (#1153) d90045f319e2ea9772b9fbd62a05fdf34af96b6c Serhiy Storchaka 2017-04-19 17:36:31
bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping_Size() (#1096) bf623ae8843dc30b28c574bec8d29fc14be59d86 Serhiy Storchaka 2017-04-19 17:03:52
bpo-29925: Skip test_uuid1_safe() on OS X Tiger (#971) c209b70d610da50a844a3c10f37d6183bade3446 Victor Stinner 2017-04-19 11:01:03
Minor grammar fixes (GH-1174) 8312fba0a1ef8f0a1a6c1760c73a89e29cfca09a Mariatta 2017-04-19 01:59:47
Fix minor typos (GH-1173) 992ae6444cc745c23d3bcc604983cc8e39405bd2 cocoatomo 2017-04-19 00:38:26
bpo-29514: Check magic number for bugfix release (#54) d6d344d8330a5975fc102e8f275d47044294f1d1 Eric Appelt 2017-04-17 18:35:43
fix a refleak in slot_sq_length (#1162) 8e1ddbd592c3aaf02a58789771f891c0101c6e05 Xiang Zhang 2017-04-16 16:54:21
bpo-30022: Get rid of using EnvironmentError and IOError (except test… (#1051) 55fe1ae9708d81b902b6fe8f6590e2a24b1bd4b0 Serhiy Storchaka 2017-04-16 07:46:38
bpo-10076: Compiled regular expression and match objects now are copyable. (#1000) fdbd01151dbd5feea3e4c0316d102db3d2a2a412 Serhiy Storchaka 2017-04-16 07:16:03
bpo-28765: Use concrete types API in _sre.c. (#1009) cd85d0b90b39310c8ca7329bd35e82c2c1c8f4ad Serhiy Storchaka 2017-04-16 06:39:30
bpo-29839: Raise ValueError rather than OverflowError in len() for negative values. (#701) baf9f29811dba9c06e76b8e220bd77260202f299 Serhiy Storchaka 2017-04-16 06:37:18
bpo-29838: Add asserts for checking results of sq_length and mq_length slots. (#700) 813f943c592cf225871b99cffc99304c8cbbee40 Serhiy Storchaka 2017-04-16 06:21:44
bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1130) 026435ce49419a3366171416c68114dd8a1144c7 Xiang Zhang 2017-04-15 04:47:28
bpo-19225: Remove duplicated description for standard warning categories (GH-1068) eaeda64c2fd2abd33e59b03298f9cdc9e8efef89 cocoatomo 2017-04-15 02:06:02
bpo-29738: Add Olivier Vielpeau to Misc/ACKS (GH-1146) 39f5956ffbcc4fe83cee59eed1d18845a5b25dd2 Mariatta 2017-04-15 01:33:48
bpo-29738: Fix memory leak in _get_crl_dp (GH-526) 2849cc34a8db93d448a62d69c462402347b50dcb Olivier Vielpeau 2017-04-15 01:06:07
bpo-30059: Include Py_Ellipsis in C API documentation (#1018) 0dc5c3169dcd4853612d11ed8c92b12fa210c07f Michael Seifert 2017-04-14 19:18:35
improve alignment autoconf test (#1129) e4f961be0946639eb4356e274268dd9b5e90da9b Benjamin Peterson 2017-04-14 16:36:45
Commit 66bffd1663489d080349debbf1b472d432351038 - bpo-30065: Fixed arguments validation in _posixsubprocess.fork_exec(). (#1110)
Author: Serhiy Storchaka
Author date (UTC): 2017-04-19 18:12
Committer name: GitHub
Committer date (UTC): 2017-04-19 18:12
Parent(s): a79f4c219531c05fc8f670c1e4bbf12c081935d3
Signer:
Signing key:
Signing status: N
Tree: bdbec28fed6a4e3ab35d620aaafb5193bab12557
File Lines added Lines deleted
Lib/multiprocessing/util.py 1 1
Lib/subprocess.py 2 1
Lib/test/test_capi.py 3 3
Lib/test/test_subprocess.py 12 1
Modules/_posixsubprocess.c 23 20
File Lib/multiprocessing/util.py changed (mode: 100644) (index 1a2c0db40b..0ce274ceca)
... ... def _close_stdin():
386 386
387 387 def spawnv_passfds(path, args, passfds): def spawnv_passfds(path, args, passfds):
388 388 import _posixsubprocess import _posixsubprocess
389 passfds = sorted(passfds)
389 passfds = tuple(sorted(map(int, passfds)))
390 390 errpipe_read, errpipe_write = os.pipe() errpipe_read, errpipe_write = os.pipe()
391 391 try: try:
392 392 return _posixsubprocess.fork_exec( return _posixsubprocess.fork_exec(
File Lib/subprocess.py changed (mode: 100644) (index 76c340c879..551aad342b)
... ... class Popen(object):
1252 1252 fds_to_keep.add(errpipe_write) fds_to_keep.add(errpipe_write)
1253 1253 self.pid = _posixsubprocess.fork_exec( self.pid = _posixsubprocess.fork_exec(
1254 1254 args, executable_list, args, executable_list,
1255 close_fds, sorted(fds_to_keep), cwd, env_list,
1255 close_fds, tuple(sorted(map(int, fds_to_keep))),
1256 cwd, env_list,
1256 1257 p2cread, p2cwrite, c2pread, c2pwrite, p2cread, p2cwrite, c2pread, c2pwrite,
1257 1258 errread, errwrite, errread, errwrite,
1258 1259 errpipe_read, errpipe_write, errpipe_read, errpipe_write,
File Lib/test/test_capi.py changed (mode: 100644) (index 6e14248a12..a95e4c5280)
... ... class CAPITest(unittest.TestCase):
98 98 def __len__(self): def __len__(self):
99 99 return 1 return 1
100 100 self.assertRaises(TypeError, _posixsubprocess.fork_exec, self.assertRaises(TypeError, _posixsubprocess.fork_exec,
101 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
101 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
102 102 # Issue #15736: overflow in _PySequence_BytesToCharpArray() # Issue #15736: overflow in _PySequence_BytesToCharpArray()
103 103 class Z(object): class Z(object):
104 104 def __len__(self): def __len__(self):
 
... ... class CAPITest(unittest.TestCase):
106 106 def __getitem__(self, i): def __getitem__(self, i):
107 107 return b'x' return b'x'
108 108 self.assertRaises(MemoryError, _posixsubprocess.fork_exec, self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
109 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
109 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
110 110
111 111 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
112 112 def test_subprocess_fork_exec(self): def test_subprocess_fork_exec(self):
 
... ... class CAPITest(unittest.TestCase):
116 116
117 117 # Issue #15738: crash in subprocess_fork_exec() # Issue #15738: crash in subprocess_fork_exec()
118 118 self.assertRaises(TypeError, _posixsubprocess.fork_exec, self.assertRaises(TypeError, _posixsubprocess.fork_exec,
119 Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
119 Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
120 120
121 121 @unittest.skipIf(MISSING_C_DOCSTRINGS, @unittest.skipIf(MISSING_C_DOCSTRINGS,
122 122 "Signature information for builtins requires docstrings") "Signature information for builtins requires docstrings")
File Lib/test/test_subprocess.py changed (mode: 100644) (index 8511207f0d..f01bd1a695)
... ... class POSIXProcessTestCase(BaseTestCase):
2418 2418 with self.assertRaises(TypeError): with self.assertRaises(TypeError):
2419 2419 _posixsubprocess.fork_exec( _posixsubprocess.fork_exec(
2420 2420 args, exe_list, args, exe_list,
2421 True, [], cwd, env_list,
2421 True, (), cwd, env_list,
2422 2422 -1, -1, -1, -1, -1, -1, -1, -1,
2423 2423 1, 2, 3, 4, 1, 2, 3, 4,
2424 2424 True, True, func) True, True, func)
 
... ... class POSIXProcessTestCase(BaseTestCase):
2430 2430 def test_fork_exec_sorted_fd_sanity_check(self): def test_fork_exec_sorted_fd_sanity_check(self):
2431 2431 # Issue #23564: sanity check the fork_exec() fds_to_keep sanity check. # Issue #23564: sanity check the fork_exec() fds_to_keep sanity check.
2432 2432 import _posixsubprocess import _posixsubprocess
2433 class BadInt:
2434 first = True
2435 def __init__(self, value):
2436 self.value = value
2437 def __int__(self):
2438 if self.first:
2439 self.first = False
2440 return self.value
2441 raise ValueError
2442
2433 2443 gc_enabled = gc.isenabled() gc_enabled = gc.isenabled()
2434 2444 try: try:
2435 2445 gc.enable() gc.enable()
 
... ... class POSIXProcessTestCase(BaseTestCase):
2440 2450 (18, 23, 42, 2**63), # Out of range. (18, 23, 42, 2**63), # Out of range.
2441 2451 (5, 4), # Not sorted. (5, 4), # Not sorted.
2442 2452 (6, 7, 7, 8), # Duplicate. (6, 7, 7, 8), # Duplicate.
2453 (BadInt(1), BadInt(2)),
2443 2454 ): ):
2444 2455 with self.assertRaises( with self.assertRaises(
2445 2456 ValueError, ValueError,
File Modules/_posixsubprocess.c changed (mode: 100644) (index 5007a39bc2..d1434d59f8)
... ... _is_fdescfs_mounted_on_dev_fd(void)
111 111 static int static int
112 112 _sanity_check_python_fd_sequence(PyObject *fd_sequence) _sanity_check_python_fd_sequence(PyObject *fd_sequence)
113 113 { {
114 Py_ssize_t seq_idx, seq_len = PySequence_Length(fd_sequence);
114 Py_ssize_t seq_idx;
115 115 long prev_fd = -1; 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);
119 123 if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { 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. */
121 125 return 1; return 1;
122 126 } }
123 127 prev_fd = iter_fd; prev_fd = iter_fd;
 
... ... _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
132 136 { {
133 137 /* Binary search. */ /* Binary search. */
134 138 Py_ssize_t search_min = 0; 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;
136 140 if (search_max < 0) if (search_max < 0)
137 141 return 0; return 0;
138 142 do { do {
139 143 long middle = (search_min + search_max) / 2; 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));
142 145 if (fd == middle_fd) if (fd == middle_fd)
143 146 return 1; return 1;
144 147 if (fd > middle_fd) if (fd > middle_fd)
 
... ... make_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
154 157 { {
155 158 Py_ssize_t i, len; Py_ssize_t i, len;
156 159
157 len = PySequence_Length(py_fds_to_keep);
160 len = PyTuple_GET_SIZE(py_fds_to_keep);
158 161 for (i = 0; i < len; ++i) { 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);
160 163 long fd = PyLong_AsLong(fdobj); long fd = PyLong_AsLong(fdobj);
161 164 assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
162 165 assert(0 <= fd && fd <= INT_MAX); assert(0 <= fd && fd <= INT_MAX);
 
... ... static void
213 216 _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep)
214 217 { {
215 218 long end_fd = safe_get_max_fd(); 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);
217 220 Py_ssize_t keep_seq_idx; Py_ssize_t keep_seq_idx;
218 221 int fd_num; int fd_num;
219 222 /* As py_fds_to_keep is sorted we can loop through the list closing /* As py_fds_to_keep is sorted we can loop through the list closing
220 223 * fds inbetween any in the keep list falling within our range. */ * fds inbetween any in the keep list falling within our range. */
221 224 for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { 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);
224 226 int keep_fd = PyLong_AsLong(py_keep_fd); int keep_fd = PyLong_AsLong(py_keep_fd);
225 227 if (keep_fd < start_fd) if (keep_fd < start_fd)
226 228 continue; continue;
 
... ... _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
306 308
307 309
308 310 /* Close all open file descriptors from start_fd and higher. /* 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.
310 312 * *
311 313 * This function violates the strict use of async signal safe functions. :( * This function violates the strict use of async signal safe functions. :(
312 314 * It calls opendir(), readdir() and closedir(). Of these, the one most * It calls opendir(), readdir() and closedir(). Of these, the one most
 
... ... subprocess_fork_exec(PyObject* self, PyObject *args)
562 564 #endif #endif
563 565
564 566 if (!PyArg_ParseTuple( 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,
567 570 &cwd_obj, &env_list, &cwd_obj, &env_list,
568 571 &p2cread, &p2cwrite, &c2pread, &c2pwrite, &p2cread, &p2cwrite, &c2pread, &c2pwrite,
569 572 &errread, &errwrite, &errpipe_read, &errpipe_write, &errread, &errwrite, &errpipe_read, &errpipe_write,
 
... ... subprocess_fork_exec(PyObject* self, PyObject *args)
574 577 PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
575 578 return NULL; return NULL;
576 579 } }
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 }
581 580 if (_sanity_check_python_fd_sequence(py_fds_to_keep)) { if (_sanity_check_python_fd_sequence(py_fds_to_keep)) {
582 581 PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep"); PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep");
583 582 return NULL; return NULL;
 
... ... subprocess_fork_exec(PyObject* self, PyObject *args)
631 630 goto cleanup; goto cleanup;
632 631 for (arg_num = 0; arg_num < num_args; ++arg_num) { for (arg_num = 0; arg_num < num_args; ++arg_num) {
633 632 PyObject *borrowed_arg, *converted_arg; 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 }
634 637 borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
635 638 if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
636 639 goto cleanup; goto cleanup;
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/benf_wspdigital/cpython

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/benf_wspdigital/cpython

Clone this repository using git:
git clone git://git.rocketgit.com/user/benf_wspdigital/cpython

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main