diff options
author | Jon Siddle <js@corefiling.co.uk> | 2010-09-14 15:08:26 +0100 |
---|---|---|
committer | R. Tyler Croy <tyler@monkeypox.org> | 2010-09-15 10:52:11 -0700 |
commit | 0287a0833cc30e0e469f6a774770002128a0281f (patch) | |
tree | 6079c22e274f2b9a69aadd7bd5c57d0ba4045061 /cheetah | |
parent | a969475248fcaa350dc921b2ec52499d8c7fb84e (diff) | |
download | python-cheetah-0287a0833cc30e0e469f6a774770002128a0281f.tar.gz |
Added test and fix for segfault in namemapper where exception is thrown by __getattr__.
Diffstat (limited to 'cheetah')
-rw-r--r-- | cheetah/Tests/NameMapper.py | 13 | ||||
-rw-r--r-- | cheetah/c/_namemapper.c | 11 |
2 files changed, 19 insertions, 5 deletions
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) { |