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