From 505ff755d704c73ac613d3e8fed02c79c6ae555a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 9 Feb 2014 13:33:53 +0200 Subject: [PATCH] Issue #20437: Fixed 21 potential bugs when deleting objects references. --- Misc/NEWS | 2 ++ Modules/_ctypes/_ctypes.c | 18 ++++++------------ Modules/_sqlite/cursor.c | 9 +++------ Modules/posixmodule.c | 3 +-- Modules/pyexpat.c | 3 +-- Modules/readline.c | 5 ++--- Modules/selectmodule.c | 3 +-- Modules/signalmodule.c | 9 +++------ Modules/syslogmodule.c | 3 +-- Modules/zlibmodule.c | 3 +-- Objects/frameobject.c | 3 +-- Objects/tupleobject.c | 6 ++---- Objects/unicodeobject.c | 12 ++++-------- Python/ceval.c | 9 +++------ Python/import.c | 6 ++---- Python/sysmodule.c | 3 +-- 16 files changed, 34 insertions(+), 63 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 1ec77a44ca0..0b42ab945fb 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.3.4 release candidate 1? Core and Builtins ----------------- +- Issue #20437: Fixed 21 potential bugs when deleting objects references. + - Issue #20538: UTF-7 incremental decoder produced inconsistant string when input was truncated in BASE64 section. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 7d0d258b7a3..48351bee039 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -159,10 +159,8 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) if (-1 == PyDict_DelItem(self->dict, self->key)) /* XXX Error context */ PyErr_WriteUnraisable(Py_None); - Py_DECREF(self->key); - self->key = NULL; - Py_DECREF(self->dict); - self->dict = NULL; + Py_CLEAR(self->key); + Py_CLEAR(self->dict); } Py_INCREF(Py_None); return Py_None; @@ -2930,10 +2928,8 @@ static int PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob) { if (ob == NULL) { - Py_XDECREF(self->restype); - self->restype = NULL; - Py_XDECREF(self->checker); - self->checker = NULL; + Py_CLEAR(self->restype); + Py_CLEAR(self->checker); return 0; } if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { @@ -2976,10 +2972,8 @@ PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob) PyObject *converters; if (ob == NULL || ob == Py_None) { - Py_XDECREF(self->converters); - self->converters = NULL; - Py_XDECREF(self->argtypes); - self->argtypes = NULL; + Py_CLEAR(self->converters); + Py_CLEAR(self->argtypes); } else { converters = converters_from_argtypes(ob); if (!converters) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 49994158db5..09c13d4dbde 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -230,8 +230,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self) if (converter != Py_None) { Py_DECREF(converter); } - Py_XDECREF(self->row_cast_map); - self->row_cast_map = NULL; + Py_CLEAR(self->row_cast_map); return -1; } @@ -443,8 +442,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* self->locked = 1; self->reset = 0; - Py_XDECREF(self->next_row); - self->next_row = NULL; + Py_CLEAR(self->next_row); if (multiple) { /* executemany() */ @@ -860,8 +858,7 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (!self->next_row) { if (self->statement) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); - self->statement = NULL; + Py_CLEAR(self->statement); } return NULL; } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 4b077a0188b..e72fbcf11b4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -693,8 +693,7 @@ typedef struct { static void path_cleanup(path_t *path) { if (path->cleanup) { - Py_DECREF(path->cleanup); - path->cleanup = NULL; + Py_CLEAR(path->cleanup); } } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 7e51d35e622..45680ae9629 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -314,8 +314,7 @@ call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args, } else { if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) { - Py_XDECREF(res); - res = NULL; + Py_CLEAR(res); } } #else diff --git a/Modules/readline.c b/Modules/readline.c index bcd34f70c1c..8fac526be33 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -231,8 +231,7 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) if (!PyArg_ParseTuple(args, buf, &function)) return NULL; if (function == Py_None) { - Py_XDECREF(*hook_var); - *hook_var = NULL; + Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { PyObject *tmp = *hook_var; @@ -827,7 +826,7 @@ on_completion_display_matches_hook(char **matches, (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r); r=NULL; + Py_CLEAR(r); if (0) { error: diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index c492224ecbc..952a0919d4b 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -74,8 +74,7 @@ reap_obj(pylist fd2obj[FD_SETSIZE + 1]) { int i; for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { - Py_XDECREF(fd2obj[i].obj); - fd2obj[i].obj = NULL; + Py_CLEAR(fd2obj[i].obj); } fd2obj[0].sentinel = -1; } diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index fbe1bb7a8cb..704c9f591b2 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1305,12 +1305,9 @@ finisignal(void) Py_XDECREF(func); } - Py_XDECREF(IntHandler); - IntHandler = NULL; - Py_XDECREF(DefaultHandler); - DefaultHandler = NULL; - Py_XDECREF(IgnoreHandler); - IgnoreHandler = NULL; + Py_CLEAR(IntHandler); + Py_CLEAR(DefaultHandler); + Py_CLEAR(IgnoreHandler); } diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 8b877cfdbc2..fc3f37595b6 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -197,8 +197,7 @@ syslog_closelog(PyObject *self, PyObject *unused) { if (S_log_open) { closelog(); - Py_XDECREF(S_ident_o); - S_ident_o = NULL; + Py_CLEAR(S_ident_o); S_log_open = 0; } Py_INCREF(Py_None); diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index e718795fa70..1d1072dcea1 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -392,8 +392,7 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) } error: - Py_XDECREF(self); - self = NULL; + Py_CLEAR(self); success: if (zdict.buf != NULL) PyBuffer_Release(&zdict); diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 808e595157b..b31213098a6 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -952,8 +952,7 @@ void PyFrame_Fini(void) { (void)PyFrame_ClearFreeList(); - Py_XDECREF(builtin_object); - builtin_object = NULL; + Py_CLEAR(builtin_object); } /* Print summary info about the state of the optimized allocator */ diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index ec3f91b2c65..123df8cef3c 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -866,8 +866,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { - Py_XDECREF(v->ob_item[i]); - v->ob_item[i] = NULL; + Py_CLEAR(v->ob_item[i]); } sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { @@ -913,8 +912,7 @@ PyTuple_Fini(void) #if PyTuple_MAXSAVESIZE > 0 /* empty tuples are used all over the place and applications may * rely on the fact that an empty tuple is a singleton. */ - Py_XDECREF(free_list[0]); - free_list[0] = NULL; + Py_CLEAR(free_list[0]); (void)PyTuple_ClearFreeList(); #endif diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index beafaa44963..e1ff999e136 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1846,8 +1846,7 @@ _PyUnicode_ClearStaticStrings() { _Py_Identifier *tmp, *s = static_strings; while (s) { - Py_DECREF(s->object); - s->object = NULL; + Py_CLEAR(s->object); tmp = s->next; s->next = NULL; s = tmp; @@ -4082,8 +4081,7 @@ make_decode_exception(PyObject **exceptionObject, return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } /* error handling callback helper: @@ -6224,8 +6222,7 @@ make_encode_exception(PyObject **exceptionObject, goto onError; return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } } @@ -8225,8 +8222,7 @@ make_translate_exception(PyObject **exceptionObject, goto onError; return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } } diff --git a/Python/ceval.c b/Python/ceval.c index 73925dc4139..2b1619163bd 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3049,8 +3049,7 @@ fast_yield: if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); why = WHY_EXCEPTION; } } @@ -3068,8 +3067,7 @@ fast_yield: else if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); /* why = WHY_EXCEPTION; */ } } @@ -3426,8 +3424,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, if (co->co_flags & CO_GENERATOR) { /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ - Py_XDECREF(f->f_back); - f->f_back = NULL; + Py_CLEAR(f->f_back); PCALL(PCALL_GENERATOR); diff --git a/Python/import.c b/Python/import.c index e91cef83ff1..26f82cf29b4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -253,8 +253,7 @@ imp_release_lock(PyObject *self, PyObject *noargs) void _PyImport_Fini(void) { - Py_XDECREF(extensions); - extensions = NULL; + Py_CLEAR(extensions); #ifdef WITH_THREAD if (import_lock != NULL) { PyThread_free_lock(import_lock); @@ -497,8 +496,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, /* Somebody already imported the module, likely under a different name. XXX this should really not happen. */ - Py_DECREF(def->m_base.m_copy); - def->m_base.m_copy = NULL; + Py_CLEAR(def->m_base.m_copy); } dict = PyModule_GetDict(mod); if (dict == NULL) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 222630c1693..2f700e65071 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -395,8 +395,7 @@ trace_trampoline(PyObject *self, PyFrameObject *frame, result = call_trampoline(tstate, callback, frame, what, arg); if (result == NULL) { PyEval_SetTrace(NULL, NULL); - Py_XDECREF(frame->f_trace); - frame->f_trace = NULL; + Py_CLEAR(frame->f_trace); return -1; } if (result != Py_None) {