Package: python-tclink Version: 3.4.0-1.1 Severity: normal
Python extensions written in C have a per-thread error indication. If an error happens, and an extension function doesn't check for the error and convert it into an exception, then the error indication stays set and some future extension function is likely to check for and raise the error. This can happen in a garbage collection and cause Python to abort. There are other scenarios that lead to a segfault, but I don't understand that well enough to include an example here. Here's an example. The version of tctest.py is the program from the python-tclink source, modified so params["state"] is None. This provokes an error because PyString_AsString refuses to convert Py_None to a string. [EMAIL PROTECTED]:/tmp$ cat tctest.py #!/usr/bin/python # # Test script for TCLink Python client. # import tclink print 'Using TCLink version', tclink.getVersion() params = { 'custid': 'TestMerchant', 'password': 'password', 'action': 'preauth', 'cc': '4111111111111111', 'exp': '0404', 'amount': '100', 'avs': 'n', 'state': None } result = tclink.send(params) if result['status'] == 'approved': print 'The transaction was approved!' elif result['status'] == 'decline': print 'The transaction was declined.' else: print 'There was an error.' print 'Here are the full details:' print result [EMAIL PROTECTED]:/tmp$ python tctest.py Using TCLink version 3.4-Python-Linux-i686 The transaction was approved! Here are the full details: {'status': 'approved', 'transid': '011-0017158794', 'avs': 'N'} Exception exceptions.TypeError: 'expected string or Unicode object, NoneType found' in 'garbage collection' ignored Fatal Python error: unexpected exception during garbage collection Aborted [EMAIL PROTECTED]:/tmp$ Note that the exception message "expected string or Unicode object, NoneType found" is correct, modulo poor English: something of type NoneType really was encountered when something of type string was appropriate, specifically the value of params["state"]. However, because the exception happened later, it happened during a garbage collection and python aborted. Here's a patch: --- py_tclink.c 2003-09-05 15:47:36.000000000 -0700 +++ /home/tim/ml/branches/tim/server/test/tclink-3.4-python-hacked/py_tclink.c 2005-04-27 10:12:48.000000000 -0700 @@ -36,15 +36,23 @@ TCLinkCon *c; param *p; - if (!PyArg_ParseTuple(args, "O", &input)) return (PyObject *)NULL; /* stuff the parameters */ handle = TCLinkCreate(); - while (PyDict_Next(input, &pos, &key, &value)) - TCLinkPushParam(handle, PyString_AsString(key), PyString_AsString(value)); + while (PyDict_Next(input, &pos, &key, &value) && !PyErr_Occurred()) { + char *k = PyString_AsString(key); + char *v; + if (!PyErr_Occurred()) v = PyString_AsString(value); + if (!PyErr_Occurred()) TCLinkPushParam(handle, k, v); + } + + if (PyErr_Occurred()) { + TCLinkDestroy(handle); + return NULL; + } Py_BEGIN_ALLOW_THREADS @@ -57,13 +65,18 @@ c = (TCLinkCon *)handle; output = PyDict_New(); - for (p = c->recv_param_list; p; p = p->next) - PyDict_SetItem(output, Py_BuildValue("s", p->name), Py_BuildValue("s", p->value)); + for (p = c->recv_param_list; p && !PyErr_Occurred(); p = p->next) + PyDict_SetItem(output, Py_BuildValue("s", p->name), + Py_BuildValue("s", p->value)); TCLinkDestroy(handle); - - return output; + if (PyErr_Occurred()) { + Py_DECREF(output); + return NULL; + } else { + return output; + } } #define TCLINKGETVERSION_DOC "Returns the module version string.\n" And here's what happens when I run with the patched py_tclink.c. The point here is that python didn't abort, and the python stack trace accurately points at the bad code. [EMAIL PROTECTED]:/tmp$ export PYTHONPATH=/home/tim/python-tclink-3.4.0/build/lib.linux-i686-2.3 [EMAIL PROTECTED]:/tmp$ python tctest.py Using TCLink version 3.4-Python-Linux-i686 Traceback (most recent call last): File "tctest.py", line 21, in ? result = tclink.send(params) TypeError: expected string or Unicode object, NoneType found [EMAIL PROTECTED]:/tmp$ -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (1500, 'testing'), (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.4.26-treo Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Versions of packages python-tclink depends on: ii python 2.3.5-1 An interactive high-level object-o ii python2.3-tclink 3.4.0-1.1 TrustCommerce credit card processi -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]