mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	GH-128682: Stronger checking of PyStackRef_CLOSE and DEAD. (GH-128683)
				
					
				
			This commit is contained in:
		
							parent
							
								
									6ff8f82f92
								
							
						
					
					
						commit
						517dc65ffc
					
				
					 7 changed files with 224 additions and 127 deletions
				
			
		
							
								
								
									
										79
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										79
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -159,8 +159,8 @@
 | 
			
		|||
                assert(PyUnicode_CheckExact(right_o));
 | 
			
		||||
                STAT_INC(BINARY_OP, hit);
 | 
			
		||||
                PyObject *res_o = PyUnicode_Concat(left_o, right_o);
 | 
			
		||||
                PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
 | 
			
		||||
                PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
 | 
			
		||||
                PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
 | 
			
		||||
                if (res_o == NULL) goto pop_2_error;
 | 
			
		||||
                res = PyStackRef_FromPyObjectSteal(res_o);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +215,7 @@
 | 
			
		|||
                 * that the string is safe to mutate.
 | 
			
		||||
                 */
 | 
			
		||||
                assert(Py_REFCNT(left_o) >= 2);
 | 
			
		||||
                PyStackRef_CLOSE(left);
 | 
			
		||||
                PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
 | 
			
		||||
                PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
 | 
			
		||||
                PyUnicode_Append(&temp, right_o);
 | 
			
		||||
                *target_local = PyStackRef_FromPyObjectSteal(temp);
 | 
			
		||||
| 
						 | 
				
			
			@ -962,10 +962,10 @@
 | 
			
		|||
                /* Callable is not a normal Python function */
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                    }
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    {
 | 
			
		||||
                        stack_pointer += -2 - oparg;
 | 
			
		||||
                        assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -1001,10 +1001,10 @@
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
                    stack_pointer += -2 - oparg;
 | 
			
		||||
                    assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -1351,19 +1351,20 @@
 | 
			
		|||
                self_or_null = &stack_pointer[-1 - oparg];
 | 
			
		||||
                callable = &stack_pointer[-2 - oparg];
 | 
			
		||||
                PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
 | 
			
		||||
                int total_args = oparg;
 | 
			
		||||
                if (!PyStackRef_IsNull(self_or_null[0])) {
 | 
			
		||||
                    args--;
 | 
			
		||||
                    total_args++;
 | 
			
		||||
                }
 | 
			
		||||
                DEOPT_IF(!PyType_Check(callable_o), CALL);
 | 
			
		||||
                PyTypeObject *tp = (PyTypeObject *)callable_o;
 | 
			
		||||
                int total_args = oparg;
 | 
			
		||||
                _PyStackRef *arguments = args;
 | 
			
		||||
                if (!PyStackRef_IsNull(self_or_null[0])) {
 | 
			
		||||
                    arguments--;
 | 
			
		||||
                    total_args++;
 | 
			
		||||
                }
 | 
			
		||||
                DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
 | 
			
		||||
                STAT_INC(CALL, hit);
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1379,7 +1380,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
 | 
			
		||||
                /* Free the arguments. */
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                    PyStackRef_CLOSE(arguments[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1430,8 +1431,9 @@
 | 
			
		|||
                /* Builtin METH_FASTCALL functions, without keywords */
 | 
			
		||||
                PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
 | 
			
		||||
                int total_args = oparg;
 | 
			
		||||
                _PyStackRef *arguments = args;
 | 
			
		||||
                if (!PyStackRef_IsNull(self_or_null[0])) {
 | 
			
		||||
                    args--;
 | 
			
		||||
                    arguments--;
 | 
			
		||||
                    total_args++;
 | 
			
		||||
                }
 | 
			
		||||
                DEOPT_IF(!PyCFunction_CheckExact(callable_o), CALL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,10 +1441,10 @@
 | 
			
		|||
                STAT_INC(CALL, hit);
 | 
			
		||||
                PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
 | 
			
		||||
                /* res = func(self, args, nargs) */
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1462,7 +1464,7 @@
 | 
			
		|||
                assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
                /* Free the arguments. */
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                    PyStackRef_CLOSE(arguments[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1529,7 +1531,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1670,6 +1672,7 @@
 | 
			
		|||
                PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
 | 
			
		||||
                if (PyTuple_CheckExact(callargs_o)) {
 | 
			
		||||
                    tuple = callargs;
 | 
			
		||||
                    kwargs_out = kwargs_in;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    _PyFrame_SetStackPointer(frame, stack_pointer);
 | 
			
		||||
| 
						 | 
				
			
			@ -1684,10 +1687,10 @@
 | 
			
		|||
                    if (tuple_o == NULL) {
 | 
			
		||||
                        goto error;
 | 
			
		||||
                    }
 | 
			
		||||
                    kwargs_out = kwargs_in;
 | 
			
		||||
                    PyStackRef_CLOSE(callargs);
 | 
			
		||||
                    tuple = PyStackRef_FromPyObjectSteal(tuple_o);
 | 
			
		||||
                }
 | 
			
		||||
                kwargs_out = kwargs_in;
 | 
			
		||||
            }
 | 
			
		||||
            // _DO_CALL_FUNCTION_EX
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -1872,16 +1875,17 @@
 | 
			
		|||
            /* isinstance(o, o2) */
 | 
			
		||||
            PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
 | 
			
		||||
            int total_args = oparg;
 | 
			
		||||
            _PyStackRef *arguments = args;
 | 
			
		||||
            if (!PyStackRef_IsNull(self_or_null[0])) {
 | 
			
		||||
                args--;
 | 
			
		||||
                arguments--;
 | 
			
		||||
                total_args++;
 | 
			
		||||
            }
 | 
			
		||||
            DEOPT_IF(total_args != 2, CALL);
 | 
			
		||||
            PyInterpreterState *interp = tstate->interp;
 | 
			
		||||
            DEOPT_IF(callable_o != interp->callable_cache.isinstance, CALL);
 | 
			
		||||
            STAT_INC(CALL, hit);
 | 
			
		||||
            _PyStackRef cls_stackref = args[1];
 | 
			
		||||
            _PyStackRef inst_stackref = args[0];
 | 
			
		||||
            _PyStackRef cls_stackref = arguments[1];
 | 
			
		||||
            _PyStackRef inst_stackref = arguments[0];
 | 
			
		||||
            _PyFrame_SetStackPointer(frame, stack_pointer);
 | 
			
		||||
            int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
 | 
			
		||||
            stack_pointer = _PyFrame_GetStackPointer(frame);
 | 
			
		||||
| 
						 | 
				
			
			@ -1890,9 +1894,11 @@
 | 
			
		|||
            }
 | 
			
		||||
            res = retval ? PyStackRef_True : PyStackRef_False;
 | 
			
		||||
            assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
            PyStackRef_CLOSE(inst_stackref);
 | 
			
		||||
            PyStackRef_CLOSE(cls_stackref);
 | 
			
		||||
            PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
            PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
            for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
            }
 | 
			
		||||
            stack_pointer[-2 - oparg] = res;
 | 
			
		||||
            stack_pointer += -1 - oparg;
 | 
			
		||||
            assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -1997,7 +2003,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2039,10 +2045,10 @@
 | 
			
		|||
                }
 | 
			
		||||
                PyStackRef_CLOSE(kwnames);
 | 
			
		||||
                assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
                    stack_pointer += -3 - oparg;
 | 
			
		||||
                    assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -2198,7 +2204,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2375,8 +2381,8 @@
 | 
			
		|||
            if (res_o == NULL) {
 | 
			
		||||
                GOTO_ERROR(error);
 | 
			
		||||
            }
 | 
			
		||||
            PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
            PyStackRef_CLOSE(arg_stackref);
 | 
			
		||||
            PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
            res = PyStackRef_FromPyObjectSteal(res_o);
 | 
			
		||||
            stack_pointer[-2 - oparg] = res;
 | 
			
		||||
            stack_pointer += -1 - oparg;
 | 
			
		||||
| 
						 | 
				
			
			@ -2456,7 +2462,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2541,7 +2547,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2774,7 +2780,7 @@
 | 
			
		|||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    PyStackRef_CLOSE(self_or_null[0]);
 | 
			
		||||
                    PyStackRef_XCLOSE(self_or_null[0]);
 | 
			
		||||
                    for (int _i = oparg; --_i >= 0;) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[_i]);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2792,10 +2798,10 @@
 | 
			
		|||
                stack_pointer = _PyFrame_GetStackPointer(frame);
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
 | 
			
		||||
                assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
                    stack_pointer += -2 - oparg;
 | 
			
		||||
                    assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -4480,10 +4486,10 @@
 | 
			
		|||
                /* Callable is not a normal Python function */
 | 
			
		||||
                STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
 | 
			
		||||
                if (CONVERSION_FAILED(args_o)) {
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                        PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                    }
 | 
			
		||||
                    PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                    {
 | 
			
		||||
                        stack_pointer += -2 - oparg;
 | 
			
		||||
                        assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -4519,10 +4525,10 @@
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                for (int i = 0; i < total_args; i++) {
 | 
			
		||||
                    PyStackRef_CLOSE(args[i]);
 | 
			
		||||
                }
 | 
			
		||||
                PyStackRef_CLOSE(callable[0]);
 | 
			
		||||
                if (res_o == NULL) {
 | 
			
		||||
                    stack_pointer += -2 - oparg;
 | 
			
		||||
                    assert(WITHIN_STACK_BOUNDS());
 | 
			
		||||
| 
						 | 
				
			
			@ -6540,11 +6546,8 @@
 | 
			
		|||
            PyObject *attr_o = _PySuper_Lookup(cls, self, name,
 | 
			
		||||
                Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
 | 
			
		||||
            stack_pointer = _PyFrame_GetStackPointer(frame);
 | 
			
		||||
            PyStackRef_CLOSE(global_super_st);
 | 
			
		||||
            PyStackRef_CLOSE(class_st);
 | 
			
		||||
            if (attr_o == NULL) {
 | 
			
		||||
                PyStackRef_CLOSE(self_st);
 | 
			
		||||
                goto pop_3_error;
 | 
			
		||||
                goto error;
 | 
			
		||||
            }
 | 
			
		||||
            if (method_found) {
 | 
			
		||||
                self_or_null = self_st; // transfer ownership
 | 
			
		||||
| 
						 | 
				
			
			@ -6552,6 +6555,8 @@
 | 
			
		|||
                PyStackRef_CLOSE(self_st);
 | 
			
		||||
                self_or_null = PyStackRef_NULL;
 | 
			
		||||
            }
 | 
			
		||||
            PyStackRef_CLOSE(class_st);
 | 
			
		||||
            PyStackRef_CLOSE(global_super_st);
 | 
			
		||||
            attr = PyStackRef_FromPyObjectSteal(attr_o);
 | 
			
		||||
            stack_pointer[-3] = attr;
 | 
			
		||||
            stack_pointer[-2] = self_or_null;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue