INN commit: trunk (innd/python.c nnrpd/python.c)
INN Commit
Russ_Allbery at isc.org
Sun Jun 22 09:50:42 UTC 2008
Date: Sunday, June 22, 2008 @ 02:50:42
Author: iulius
Revision: 7889
Fix an issue with Python exception handling.
Modified:
trunk/innd/python.c
trunk/nnrpd/python.c
----------------+
innd/python.c | 25 ++++++++++++++++++++-----
nnrpd/python.c | 34 ++++++++++++++++++++++++++--------
2 files changed, 46 insertions(+), 13 deletions(-)
Modified: innd/python.c
===================================================================
--- innd/python.c 2008-06-22 09:28:06 UTC (rev 7888)
+++ innd/python.c 2008-06-22 09:50:42 UTC (rev 7889)
@@ -8,6 +8,14 @@
**
** The astute reader may notice the commission of blatant atrocities against
** Python's OO model here. Don't tell Guido.
+**
+** A quick note regarding Python exceptions: functions like
+** PyObject_GetAttrString(PyObject *o, const char *attr_name)
+** raise an exception when they fail, even though they return NULL.
+** And as exceptions accumulate from caller to caller and so on,
+** it generates weird issues with Python scripts afterwards. So such
+** uses should be checked before. For instance with:
+** PyObject_HasAttrString(PyObject *o, const char *attr_name)
*/
#include "config.h"
@@ -569,8 +577,15 @@
{
Py_XDECREF(*methptr);
- /* Get a pointer to given method. */
- *methptr = PyObject_GetAttrString(PYFilterObject, (char *) methname);
+ /* We check with HasAttrString() the existence of the method because
+ * otherwise, in case it does not exist, an exception is raised by Python,
+ * although the result of the function is NULL. */
+ if (PyObject_HasAttrString(PYFilterObject, (char *) methname) == 1) {
+ /* Get a pointer to given method. */
+ *methptr = PyObject_GetAttrString(PYFilterObject, (char *) methname);
+ } else {
+ *methptr = NULL;
+ }
/* See if such method is defined. */
if (*methptr == NULL)
@@ -578,9 +593,9 @@
else {
/* See if it is callable. */
if (PyCallable_Check(*methptr) == 0) {
- syslog(L_ERROR, "python object %s found but not a function", methname);
- Py_DECREF(*methptr);
- *methptr = NULL;
+ syslog(L_ERROR, "python object %s found but not a function", methname);
+ Py_DECREF(*methptr);
+ *methptr = NULL;
}
}
}
Modified: nnrpd/python.c
===================================================================
--- nnrpd/python.c 2008-06-22 09:28:06 UTC (rev 7888)
+++ nnrpd/python.c 2008-06-22 09:50:42 UTC (rev 7889)
@@ -9,6 +9,14 @@
** This code bases on Python work for innd filtering done by
** G.J. Andruk <meowing at banet.net>. Also it borrows some ideas from
** TCL/Perl work done by Bob Heiney and Christophe Wolfhugel.
+**
+** A quick note regarding Python exceptions: functions like
+** PyObject_GetAttrString(PyObject *o, const char *attr_name)
+** raise an exception when they fail, even though they return NULL.
+** And as exceptions accumulate from caller to caller and so on,
+** it generates weird issues with Python scripts afterwards. So such
+** uses should be checked before. For instance with:
+** PyObject_HasAttrString(PyObject *o, const char *attr_name)
*/
#include "config.h"
@@ -293,7 +301,7 @@
/*
** Now invoke newsgroup access method.
- **/
+ */
result = PyObject_CallFunction(proc, (char *) "O", PYauthinfo);
/* Check the response. */
@@ -430,7 +438,7 @@
/*
** Now invoke newsgroup dynamic access method and see if
** it likes this user to access this newsgroup.
- **/
+ */
result = PyObject_CallFunction(proc, (char *) "O", PYauthinfo);
/* Check the response. */
@@ -583,7 +591,7 @@
PyObject *result = NULL;
PyObject *temp;
- /* Set_auth_hook method should return a pointer to nnrpd auth object. */
+ /* set_auth_hook method should return a pointer to nnrpd auth object. */
if (PyArg_ParseTuple(args, (char *) "O:set_auth_hook", &temp)) {
Py_XINCREF(temp);
Py_XDECREF(PYAuthObject);
@@ -605,10 +613,11 @@
PY_load_python(void)
{
if (!PythonLoaded) {
- /* Add path for nnrpd module. The environment variable PYTHONPATH
+ /*
+ ** Add path for nnrpd module. The environment variable PYTHONPATH
** does it; one can also append innconf->pathfilter to sys.path once
** Python has been initialized.
- **/
+ */
setenv("PYTHONPATH", innconf->pathfilter, 1);
/* Load up the interpreter ;-O */
@@ -630,7 +639,7 @@
/*
** Grab space for authinfo dictionary so we aren't forever
** recreating them.
- **/
+ */
PYauthinfo = PyDict_New();
PYauthitem = xcalloc(_PY_MAX_AUTH_ITEM, sizeof(PyObject *));
@@ -657,8 +666,17 @@
methptr = &fp->procs[type][method];
- /* Get a pointer to given method. */
- *methptr = PyObject_GetAttrString(PYAuthObject, (char *) methname);
+ /*
+ ** We check with HasAttrString() the existence of the method because
+ ** otherwise, in case it does not exist, an exception is raised by Python,
+ ** although the result of the function is NULL.
+ */
+ if (PyObject_HasAttrString(PYAuthObject, (char *) methname) == 1) {
+ /* Get a pointer to given method. */
+ *methptr = PyObject_GetAttrString(PYAuthObject, (char *) methname);
+ } else {
+ *methptr = NULL;
+ }
/* See if such method is defined. */
if (*methptr == NULL)
More information about the inn-committers
mailing list