Re: Segfault in name mapper
"R. Tyler Croy" <[email protected]> Mon, 13 Sep 2010 16:09:49 -0700
| Newsgroups | gmane.comp.python.cheetah |
|---|---|
| Message-ID | <[email protected]> |
On Mon, 13 Sep 2010, Jon Siddle wrote:
> It is possible to trivially cause the name mapper to segfault if
> getattr throws an exception:
Very interesting, thanks for the patch! I'll get it applied after I finish
putting out some fires at $WORKPLACE and get a new release out with it.
>
> $a.b.c
>
> If a.__getattr__('b') throws an exception, the name mapper will
> segfault. This is caused by the
> following code in PyNamemapper_valueForName():
>
> nextVal = PyObject_GetAttrString(currentVal, currentKey);
> if (exc != NULL) {
> // if exception == AttributeError
> if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
> setNotFoundException(currentKey, currentVal);
> if (i > 0) {
> Py_DECREF(currentVal);
> }
> return NULL;
> }
> }
>
> As you can see, only AttributeError is handled. Any other exception
> will cause currentVal to be NULL
> the next time round the loop and the call to
> PyObject_GetAttrString(currentVal, currentKey) will segfault.
>
> The solution is simply to move the decref-return code outside the
> check for AttributeError so that it happens
> for all exceptions.
>
> The attached patch fixes the bug, and adds a test for it. I've added
> a return code check to the buildandrun
> script so the segfault doesn't go unnoticed when the test fails.
>
> FYI We encountered this when using the sqlalchemy ORM, which can
> throw exceptions from __getattr__ on
> objects in the session, so it's quite likely that others will
> encounter this.
>
> Thanks
>
> Jon
>
> --
> Jon Siddle, CoreFiling Limited
> Software Tools Developer
> http://www.corefiling.com
> Phone: +44-1865-203192
> diff --git a/buildandrun b/buildandrun
> index d3b4e42..41a636a 100755
> --- a/buildandrun
> +++ b/buildandrun
> @@ -58,7 +58,8 @@ def main():
> os.putenv('PYTHONPATH', libdir)
>
> rc = subprocess.call( ['python',] + args )
> -
> + if rc == -11:
> + logging.error('Segmentation fault in test process. Test failed.')
>
>
> if __name__ == '__main__':
> diff --git a/cheetah/Tests/NameMapper.py b/cheetah/Tests/NameMapper.py
> index ac42244..c44fb4c 100644
> --- a/cheetah/Tests/NameMapper.py
> +++ b/cheetah/Tests/NameMapper.py
> @@ -43,6 +43,10 @@ class DummyClass(object):
> except:
> raise
>
> +class DummyClassGetAttrRaises(object):
> + def __getattr__(self, name):
> + raise ValueError
> +
>
> def dummyFunc(arg="Scooby"):
> return arg
> @@ -67,6 +71,7 @@ testNamespace = {
> 'aClass': DummyClass,
> 'aFunc': dummyFunc,
> 'anObj': DummyClass(),
> + 'anObjThatRaises': DummyClassGetAttrRaises(),
> 'aMeth': DummyClass().meth1,
> 'none': None,
> 'emptyString': '',
> @@ -419,6 +424,14 @@ class VFN(NameMapperTest):
> for i in range(10):
> self.get('aDict.nestedDict.funcThatRaises', False)
>
> + def test61(self):
> + """Accessing attribute where __getattr__ raises shouldn't segfault if something follows it"""
> +
> + def test(self=self):
> + self.get('anObjThatRaises.willraise.anything')
> + self.assertRaises(ValueError, test)
> +
> +
> class VFS(VFN):
> _searchListLength = 1
>
> diff --git a/cheetah/c/_namemapper.c b/cheetah/c/_namemapper.c
> index a41571b..a114658 100644
> --- a/cheetah/c/_namemapper.c
> +++ b/cheetah/c/_namemapper.c
> @@ -188,14 +188,15 @@ static PyObject *PyNamemapper_valueForName(PyObject *obj, char *nameChunks[], in
> nextVal = PyObject_GetAttrString(currentVal, currentKey);
> exc = PyErr_Occurred();
> if (exc != NULL) {
> - // if exception == AttributeError
> + // if exception == AttributeError, report our own exception
> if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
> setNotFoundException(currentKey, currentVal);
> - if (i > 0) {
> - Py_DECREF(currentVal);
> - }
> - return NULL;
> }
> + // any exceptions results in failure
> + if (i > 0) {
> + Py_DECREF(currentVal);
> + }
> + return NULL;
> }
> }
> if (i > 0) {
>
> ------------------------------------------------------------------------------
> Start uncovering the many advantages of virtual appliances
> and start using them to simplify application deployment and
> accelerate your shift to cloud computing
> http://p.sf.net/sfu/novell-sfdev2dev
> _______________________________________________
> Cheetahtemplate-discuss mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
- R. Tyler Croy
--------------------------------------
GitHub: http://github.com/rtyler
Twitter: http://twitter.com/agentdero
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Cheetahtemplate-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
signature.asc
(application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) iEYEARECAAYFAkyOrzwACgkQFCbH3D9R4W9hhwCgmIhFGuT36ypP//6ASSCSS3eD QxQAn2+tY2oJpFgquq2Yw5t9ujt/PzwF =TGOJ -----END PGP SIGNATURE-----