From: Antoine Pitrou Date: Wed, 15 Aug 2012 21:20:39 +0000 (+0200) Subject: Issue #15604: Update uses of PyObject_IsTrue() to check for and handle errors correctly. X-Git-Tag: v3.3.0rc1~101 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=721738fbee8d75dab5a5d3c4f3dbd7c72d76925e;p=python Issue #15604: Update uses of PyObject_IsTrue() to check for and handle errors correctly. Patch by Serhiy Storchaka. --- 721738fbee8d75dab5a5d3c4f3dbd7c72d76925e diff --cc Misc/NEWS index 2d8b48d1f3,4f3fc5103f..a3965c7300 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -10,106 -10,96 +10,109 @@@ What's New in Python 3.3.0 Release Cand Core and Builtins ----------------- + - Issue #15604: Update uses of PyObject_IsTrue() to check for and handle + errors correctly. Patch by Serhiy Storchaka. + -- Issue #13119: sys.stdout and sys.stderr are now using "\r\n" newline on - Windows, as Python 2. +Library +------- -- Issue #14579: Fix CVE-2012-2135: vulnerability in the utf-16 decoder after - error handling. Patch by Serhiy Storchaka. +- Issue #11062: Fix adding a message from file to Babyl mailbox. -- Issue #15404: Refleak in PyMethodObject repr. +- Issue #15646: Prevent equivalent of a fork bomb when using + multiprocessing on Windows without the "if __name__ == '__main__'" + idiom. -- Issue #15394: An issue in PyModule_Create that caused references to - be leaked on some error paths has been fixed. Patch by Julia Lawall. +C API +----- -- Issue #15368: An issue that caused bytecode generation to be - non-deterministic when using randomized hashing (-R) has been fixed. +Extension Modules +----------------- -- Issue #15020: The program name used to search for Python's path is now - "python3" under Unix, not "python". +Tools/Demos +----------- -- Issue #15033: Fix the exit status bug when modules invoked using -m swith, - return the proper failure return value (1). Patch contributed by Jeff Knupp. +Documentation +------------- -- Issue #12268: File readline, readlines and read() or readall() methods - no longer lose data when an underlying read system call is interrupted. - IOError is no longer raised due to a read system call returning EINTR - from within these methods. +- Issue #15630: Add an example for "continue" stmt in the tutorial. Patch by + Daniel Ellis. -- Issue #15142: Fix reference leak when deallocating instances of types - created using PyType_FromSpec(). -- Issue #10053: Don't close FDs when FileIO.__init__ fails. Loosely based on - the work by Hirokazu Yamamoto. -- Issue #14775: Fix a potential quadratic dict build-up due to the garbage - collector repeatedly trying to untrack dicts. +What's New in Python 3.3.0 Beta 2? +================================== -- Issue #14494: Fix __future__.py and its documentation to note that - absolute imports are the default behavior in 3.0 instead of 2.7. - Patch by Sven Marnach. +*Release date: 12-Aug-2012* -- Issue #14761: Fix potential leak on an error case in the import machinery. +Core and Builtins +----------------- -- Issue #14699: Fix calling the classmethod descriptor directly. +- Issue #15568: Fix the return value of "yield from" when StopIteration is + raised by a custom iterator. -- Issue #14433: Prevent msvcrt crash in interactive prompt when stdin - is closed. +- Issue #13119: sys.stdout and sys.stderr are now using "\r\n" newline on + Windows, as Python 2. -- Issue #11603 (again): Setting __repr__ to __str__ now raises a RuntimeError - when repr() or str() is called on such an object. +- Issue #15534: Fix the fast-search function for non-ASCII Unicode strings. -- Issue #14658: Fix binding a special method to a builtin implementation of a - special method with a different name. +- Issue #15508: Fix the docstring for __import__ to have the proper default + value of 0 for 'level' and to not mention negative levels since they are not + supported. -- Issue #14630: Fix a memory access bug for instances of a subclass of int - with value 0. +- Issue #15425: Eliminated traceback noise from more situations involving + importlib. -- Issue #14612: Fix jumping around with blocks by setting f_lineno. +- Issue #14578: Support modules registered in the Windows registry again. -- Issue #14607: Fix keyword-only arguments which started with ``__``. +- Issue #15466: Stop using TYPE_INT64 in marshal, to make importlib.h (and other + byte code files) equal between 32-bit and 64-bit systems. -- Issue #13889: Check and (if necessary) set FPU control word before calling - any of the dtoa.c string <-> float conversion functions, on MSVC builds of - Python. This fixes issues when embedding Python in a Delphi app. +- Issue #1692335: Move initial exception args assignment to + "BaseException.__new__" to help pickling of naive subclasses. -- Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. +- Issue #12834: Fix PyBuffer_ToContiguous() for non-contiguous arrays. -- Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch - by Suman Saha. +- Issue #15456: Fix code __sizeof__ after #12399 change. Patch by Serhiy + Storchaka. -- Issue #14378: Fix compiling ast.ImportFrom nodes with a "__future__" string as - the module name that was not interned. +- Issue #15404: Refleak in PyMethodObject repr. -- Issue #14331: Use significantly less stack space when importing modules by - allocating path buffers on the heap instead of the stack. +- Issue #15394: An issue in PyModule_Create that caused references to be leaked + on some error paths has been fixed. Patch by Julia Lawall. -- Issue #14334: Prevent in a segfault in type.__getattribute__ when it was not - passed strings. +- Issue #15368: An issue that caused bytecode generation to be non-deterministic + has been fixed. -- Issue #1469629: Allow cycles through an object's __dict__ slot to be - collected. (For example if ``x.__dict__ is x``). +- Issue #15202: Consistently use the name "follow_symlinks" for new parameters + in os and shutil functions. -- Issue #14172: Fix reference leak when marshalling a buffer-like object - (other than a bytes object). +- Issue #15314: __main__.__loader__ is now set correctly during interpreter + startup. -- Issue #13521: dict.setdefault() now does only one lookup for the given key, - making it "atomic" for many purposes. Patch by Filip Gruszczyński. +- Issue #15111: When a module imported using 'from import' has an ImportError + inside itself, don't mask that fact behind a generic ImportError for the + module itself. -- Issue #14471: Fix a possible buffer overrun in the winreg module. +- Issue #15293: Add GC support to the AST base node type. + +- Issue #15291: Fix a memory leak where AST nodes where not properly + deallocated. + +- Issue #15110: Fix the tracebacks generated by "import xxx" to not show the + importlib stack frames. + +- Issue #15020: The program name used to search for Python's path is now + "python3" under Unix, not "python". + +- Issue #15033: Fix the exit status bug when modules invoked using -m swith, + return the proper failure return value (1). Patch contributed by Jeff Knupp. + +- Issue #15229: An OSError subclass whose __init__ doesn't call back + OSError.__init__ could produce incomplete instances, leading to crashes when + calling str() on them. + +- Issue 15307: Virtual environments now use symlinks with framework builds on + Mac OS X, like other POSIX builds. Library ------- diff --cc Modules/_io/textio.c index 421dc50514,490484254b..fb9b67438d --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@@ -1053,13 -1043,16 +1053,16 @@@ textiowrapper_init(textio *self, PyObje Py_DECREF(raw); } - res = PyObject_CallMethod(buffer, "seekable", NULL); + res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL); if (res == NULL) goto error; - self->seekable = self->telling = PyObject_IsTrue(res); + r = PyObject_IsTrue(res); Py_DECREF(res); + if (r < 0) + goto error; + self->seekable = self->telling = r; - self->has_read1 = PyObject_HasAttrString(buffer, "read1"); + self->has_read1 = _PyObject_HasAttrId(buffer, &PyId_read1); self->encoding_start_of_stream = 0; if (self->seekable && self->encoder) { diff --cc Modules/_posixsubprocess.c index 4a147880d5,44e1613f10..ed2dd58796 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@@ -503,7 -501,7 +503,7 @@@ static PyObject subprocess_fork_exec(PyObject* self, PyObject *args) { PyObject *gc_module = NULL; -- PyObject *executable_list, *py_close_fds, *py_fds_to_keep; ++ PyObject *executable_list, *py_fds_to_keep; PyObject *env_list, *preexec_fn; PyObject *process_args, *converted_args = NULL, *fast_args = NULL; PyObject *preexec_fn_args_tuple = NULL; @@@ -518,15 -516,17 +518,14 @@@ Py_ssize_t arg_num; if (!PyArg_ParseTuple( -- args, "OOOOOOiiiiiiiiiiO:fork_exec", -- &process_args, &executable_list, &py_close_fds, &py_fds_to_keep, ++ args, "OOpOOOiiiiiiiiiiO:fork_exec", ++ &process_args, &executable_list, &close_fds, &py_fds_to_keep, &cwd_obj, &env_list, &p2cread, &p2cwrite, &c2pread, &c2pwrite, &errread, &errwrite, &errpipe_read, &errpipe_write, &restore_signals, &call_setsid, &preexec_fn)) return NULL; -- close_fds = PyObject_IsTrue(py_close_fds); - if (close_fds < 0) - return NULL; if (close_fds && errpipe_write < 3) { /* precondition */ PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); return NULL; diff --cc Modules/_ssl.c index b5d15306d6,0a841183a5..1104a4eab7 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@@ -1037,15 -882,19 +1037,15 @@@ PySSL_peercert(PySSLSocket *self, PyObj PyObject *retval = NULL; int len; int verification; -- PyObject *binary_mode = Py_None; - int b; ++ int binary_mode = 0; -- if (!PyArg_ParseTuple(args, "|O:peer_certificate", &binary_mode)) ++ if (!PyArg_ParseTuple(args, "|p:peer_certificate", &binary_mode)) return NULL; if (!self->peer_cert) Py_RETURN_NONE; - if (PyObject_IsTrue(binary_mode)) { - b = PyObject_IsTrue(binary_mode); - if (b < 0) - return NULL; - if (b) { ++ if (binary_mode) { /* return cert in DER-encoded format */ unsigned char *bytes_buf = NULL; diff --cc Modules/itertoolsmodule.c index 194f7fb5a3,77e76fe588..9115b67146 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@@ -1113,31 -913,6 +1115,31 @@@ dropwhile_next(dropwhileobject *lz } } +static PyObject * +dropwhile_reduce(dropwhileobject *lz) +{ + return Py_BuildValue("O(OO)l", Py_TYPE(lz), + lz->func, lz->it, lz->start); +} + +static PyObject * +dropwhile_setstate(dropwhileobject *lz, PyObject *state) +{ + int start = PyObject_IsTrue(state); - if (start == -1) ++ if (start < 0) + return NULL; + lz->start = start; + Py_RETURN_NONE; +} + +static PyMethodDef dropwhile_methods[] = { + {"__reduce__", (PyCFunction)dropwhile_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)dropwhile_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + PyDoc_STRVAR(dropwhile_doc, "dropwhile(predicate, iterable) --> dropwhile object\n\ \n\ @@@ -1270,37 -1045,14 +1272,38 @@@ takewhile_next(takewhileobject *lz } ok = PyObject_IsTrue(good); Py_DECREF(good); - if (ok) - if (ok > 0) ++ if (ok == 1) return item; Py_DECREF(item); - lz->stop = 1; + if (ok == 0) + lz->stop = 1; return NULL; } +static PyObject * +takewhile_reduce(takewhileobject *lz) +{ + return Py_BuildValue("O(OO)l", Py_TYPE(lz), + lz->func, lz->it, lz->stop); +} + +static PyObject * +takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) +{ + int stop = PyObject_IsTrue(state); - if (stop == -1) ++ if (stop < 0) + return NULL; + lz->stop = stop; + Py_RETURN_NONE; +} + +static PyMethodDef takewhile_reduce_methods[] = { + {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)takewhile_reduce_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; PyDoc_STRVAR(takewhile_doc, "takewhile(predicate, iterable) --> takewhile object\n\ \n\ @@@ -3536,7 -2819,7 +3539,7 @@@ compress_next(compressobject *lz if (ok == 1) return datum; Py_DECREF(datum); -- if (ok == -1) ++ if (ok < 0) return NULL; } } diff --cc Modules/parsermodule.c index 2c079add0e,b8732dce87..b4602f5d12 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@@ -382,36 -382,40 +382,28 @@@ parser_sizeof(PyST_Object *st, void *un static PyObject* parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) { -- PyObject *line_option = 0; -- PyObject *col_option = 0; ++ int line_info = 0; ++ int col_info = 0; PyObject *res = 0; int ok; static char *keywords[] = {"st", "line_info", "col_info", NULL}; if (self == NULL || PyModule_Check(self)) { -- ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords, -- &PyST_Type, &self, &line_option, -- &col_option); ++ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2tuple", keywords, ++ &PyST_Type, &self, &line_info, ++ &col_info); } else -- ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:totuple", &keywords[1], -- &line_option, &col_option); ++ ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:totuple", &keywords[1], ++ &line_info, &col_info); if (ok != 0) { -- int lineno = 0; -- int col_offset = 0; -- if (line_option != NULL) { - lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0; - lineno = PyObject_IsTrue(line_option); - if (lineno < 0) - return NULL; -- } -- if (col_option != NULL) { - col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0; - col_offset = PyObject_IsTrue(col_option); - if (col_offset < 0) - return NULL; -- } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(((PyST_Object*)self)->st_node, -- PyTuple_New, PyTuple_SetItem, lineno, col_offset); ++ PyTuple_New, PyTuple_SetItem, line_info, col_info); } return (res); } @@@ -426,35 -430,39 +418,27 @@@ static PyObject* parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) { -- PyObject *line_option = 0; -- PyObject *col_option = 0; ++ int line_info = 0; ++ int col_info = 0; PyObject *res = 0; int ok; static char *keywords[] = {"st", "line_info", "col_info", NULL}; if (self == NULL || PyModule_Check(self)) -- ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords, -- &PyST_Type, &self, &line_option, -- &col_option); ++ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2list", keywords, ++ &PyST_Type, &self, &line_info, ++ &col_info); else -- ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:tolist", &keywords[1], -- &line_option, &col_option); ++ ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:tolist", &keywords[1], ++ &line_info, &col_info); if (ok) { -- int lineno = 0; -- int col_offset = 0; -- if (line_option != 0) { - lineno = PyObject_IsTrue(line_option) ? 1 : 0; - lineno = PyObject_IsTrue(line_option); - if (lineno < 0) - return NULL; -- } - if (col_option != NULL) { - col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0; - if (col_option != 0) { - col_offset = PyObject_IsTrue(col_option); - if (col_offset < 0) - return NULL; -- } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(self->st_node, -- PyList_New, PyList_SetItem, lineno, col_offset); ++ PyList_New, PyList_SetItem, line_info, col_info); } return (res); } diff --cc Modules/pyexpat.c index a500a1e25d,c965ff4aa0..bd2726877f --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@@ -1033,14 -1032,17 +1033,11 @@@ getting the advantage of providing docu static PyObject * xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) { -- PyObject *flagobj = NULL; - XML_Bool flag = XML_TRUE; + int flag = 1; enum XML_Error rc; - if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj)) - if (!PyArg_ParseTuple(args, "O:UseForeignDTD", &flagobj)) ++ if (!PyArg_ParseTuple(args, "p:UseForeignDTD", &flag)) return NULL; - if (flagobj != NULL) - flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE; - rc = XML_UseForeignDTD(self->itself, flag); - if (flagobj != NULL) { - flag = PyObject_IsTrue(flagobj); - if (flag < 0) - return NULL; - } + rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); if (rc != XML_ERROR_NONE) { return set_error(self, rc); }