changeset 569:c17342ef9efb trunk

Attribute access in template expressions no longer silently ignores exceptions other than `AttributeError` raised in the attribute accessor.
author cmlenz
date Tue, 17 Jul 2007 10:00:52 +0000
parents 461d9d0e85a4
children f0461dc3939a
files ChangeLog genshi/template/eval.py genshi/template/tests/eval.py
diffstat 3 files changed, 26 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,8 @@
    ignored tags (ticket #132).
  * The HTML sanitizer now strips any CSS comments in style attributes, which
    could previously be used to hide malicious property values.
+ * Attribute access in template expressions no longer silently ignores
+   exceptions other than `AttributeError` raised in the attribute accessor.
 
 
 Version 0.4.2
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -259,18 +259,19 @@
         if val is UNDEFINED:
             val = BUILTINS.get(name, val)
             if val is UNDEFINED:
-                return cls.undefined(name)
+                val = cls.undefined(name)
         return val
     lookup_name = classmethod(lookup_name)
 
     def lookup_attr(cls, data, obj, key):
         __traceback_hide__ = True
-        if hasattr(obj, key):
-            return getattr(obj, key)
-        try:
-            return obj[key]
-        except (KeyError, TypeError):
-            return cls.undefined(key, owner=obj)
+        val = getattr(obj, key, UNDEFINED)
+        if val is UNDEFINED:
+            try:
+                val = obj[key]
+            except (KeyError, TypeError):
+                val = cls.undefined(key, owner=obj)
+        return val
     lookup_attr = classmethod(lookup_attr)
 
     def lookup_item(cls, data, obj, key):
@@ -283,7 +284,7 @@
             if isinstance(key, basestring):
                 val = getattr(obj, key, UNDEFINED)
                 if val is UNDEFINED:
-                    return cls.undefined(key, owner=obj)
+                    val = cls.undefined(key, owner=obj)
                 return val
             raise
     lookup_item = classmethod(lookup_item)
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -338,6 +338,14 @@
         self.assertEqual('nil', retval._name)
         assert retval._owner is something
 
+    def test_getattr_exception(self):
+        class Something(object):
+            def prop(self):
+                raise NotImplementedError
+            prop = property(prop)
+        self.assertRaises(NotImplementedError,
+                          Expression('s.prop').evaluate, {'s': Something()})
+
     def test_getitem_undefined_string(self):
         class Something(object):
             def __repr__(self):
@@ -349,6 +357,13 @@
         self.assertEqual('nil', retval._name)
         assert retval._owner is something
 
+    def test_getitem_exception(self):
+        class Something(object):
+            def __getitem__(self, key):
+                raise NotImplementedError
+        self.assertRaises(NotImplementedError,
+                          Expression('s["foo"]').evaluate, {'s': Something()})
+
     def test_error_access_undefined(self):
         expr = Expression("nothing", filename='index.html', lineno=50,
                           lookup='strict')
Copyright (C) 2012-2017 Edgewall Software