[Python-checkins] r64549 - in python/trunk: Lib/test/test_warnings.py Lib/warnings.py Misc/NEWS Python/_warnings.c
brett.cannon
python-checkins at python.org
Fri Jun 27 02:31:14 CEST 2008
Author: brett.cannon
Date: Fri Jun 27 02:31:13 2008
New Revision: 64549
Log:
warnings.warn_explicit() did not have the proper TypeErrors in place to prevent
bus errors or SystemError being raised. As a side effect of fixing this, a bad
DECREF that could be triggered when 'message' and 'category' were both None was
fixed.
Closes issue 3211. Thanks JP Calderone for the bug report.
Modified:
python/trunk/Lib/test/test_warnings.py
python/trunk/Lib/warnings.py
python/trunk/Misc/NEWS
python/trunk/Python/_warnings.c
Modified: python/trunk/Lib/test/test_warnings.py
==============================================================================
--- python/trunk/Lib/test/test_warnings.py (original)
+++ python/trunk/Lib/test/test_warnings.py Fri Jun 27 02:31:13 2008
@@ -301,6 +301,21 @@
warning_tests.__name__ = module_name
sys.argv = argv
+ def test_warn_explicit_type_errors(self):
+ # warn_explicit() shoud error out gracefully if it is given objects
+ # of the wrong types.
+ # lineno is expected to be an integer.
+ self.assertRaises(TypeError, self.module.warn_explicit,
+ None, UserWarning, None, None)
+ # Either 'message' needs to be an instance of Warning or 'category'
+ # needs to be a subclass.
+ self.assertRaises(TypeError, self.module.warn_explicit,
+ None, None, None, 1)
+ # 'registry' must be a dict or None.
+ self.assertRaises((TypeError, AttributeError),
+ self.module.warn_explicit,
+ None, Warning, None, 1, registry=42)
+
class CWarnTests(BaseTest, WarnTests):
Modified: python/trunk/Lib/warnings.py
==============================================================================
--- python/trunk/Lib/warnings.py (original)
+++ python/trunk/Lib/warnings.py Fri Jun 27 02:31:13 2008
@@ -202,6 +202,7 @@
def warn_explicit(message, category, filename, lineno,
module=None, registry=None, module_globals=None):
+ lineno = int(lineno)
if module is None:
module = filename or "<unknown>"
if module[-3:].lower() == ".py":
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Fri Jun 27 02:31:13 2008
@@ -25,6 +25,11 @@
Core and Builtins
-----------------
+- Issue #3211: warnings.warn_explicit() did not guard against its 'registry'
+ argument being anything other than a dict or None. Also fixed a bug in error
+ handling when 'message' and 'category' were both set to None, triggering a
+ bus error.
+
- Issue #3100: Corrected a crash on deallocation of a subclassed weakref which
holds the last (strong) reference to its referent.
Modified: python/trunk/Python/_warnings.c
==============================================================================
--- python/trunk/Python/_warnings.c (original)
+++ python/trunk/Python/_warnings.c Fri Jun 27 02:31:13 2008
@@ -280,6 +280,11 @@
PyObject *item = Py_None;
const char *action;
int rc;
+
+ if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
+ return NULL;
+ }
/* Normalize module. */
if (module == NULL) {
@@ -303,6 +308,8 @@
else {
text = message;
message = PyObject_CallFunction(category, "O", message);
+ if (message == NULL)
+ goto cleanup;
}
lineno_obj = PyInt_FromLong(lineno);
@@ -314,7 +321,7 @@
if (key == NULL)
goto cleanup;
- if (registry != NULL) {
+ if ((registry != NULL) && (registry != Py_None)) {
rc = already_warned(registry, key, 0);
if (rc == -1)
goto cleanup;
@@ -336,12 +343,13 @@
is "always". */
rc = 0;
if (strcmp(action, "always") != 0) {
- if (registry != NULL && PyDict_SetItem(registry, key, Py_True) < 0)
+ if (registry != NULL && registry != Py_None &&
+ PyDict_SetItem(registry, key, Py_True) < 0)
goto cleanup;
else if (strcmp(action, "ignore") == 0)
goto return_none;
else if (strcmp(action, "once") == 0) {
- if (registry == NULL) {
+ if (registry == NULL || registry == Py_None) {
registry = get_once_registry();
if (registry == NULL)
goto cleanup;
@@ -351,7 +359,7 @@
}
else if (strcmp(action, "module") == 0) {
/* registry[(text, category, 0)] = 1 */
- if (registry != NULL)
+ if (registry != NULL && registry != Py_None)
rc = update_registry(registry, text, category, 0);
}
else if (strcmp(action, "default") != 0) {
@@ -435,7 +443,7 @@
Py_XDECREF(text);
Py_XDECREF(lineno_obj);
Py_DECREF(module);
- Py_DECREF(message);
+ Py_XDECREF(message);
return result; /* Py_None or NULL. */
}
More information about the Python-checkins
mailing list