Browse files

improved sandbox, added proper striptags and updated documentation to…

… latest sphinx changes

--HG--
branch : trunk
  • Loading branch information...
1 parent 4dc9578 commit 76c280bf5b2263a435e38e0b3612c23eb633ed79 @mitsuhiko mitsuhiko committed May 4, 2008
Showing with 46 additions and 14 deletions.
  1. +1 −1 docs/conf.py
  2. +0 −7 docs/index.rst
  3. +5 −0 docs/templates.rst
  4. +1 −0 jinja2/defaults.py
  5. +1 −2 jinja2/filters.py
  6. +12 −3 jinja2/sandbox.py
  7. +26 −1 jinja2/utils.py
View
2 docs/conf.py
@@ -145,4 +145,4 @@
#latex_appendices = []
# If false, no module index is generated.
-#latex_use_modindex = True
+latex_use_modindex = False
View
7 docs/index.rst
@@ -9,10 +9,3 @@ Contents:
intro
api
templates
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
View
5 docs/templates.rst
@@ -838,3 +838,8 @@ The following functions are available in the global scope by default:
with HTML are generated each paragraph between 20 and 100 words. If html
is disabled regular text is returned. This is useful to generate simple
contents for layout testing.
+
+.. function:: dict(**items)
+
+ A convenient alternative to dict literals. ``{'foo': 'bar'}`` is the same
+ as ``dict(foo='bar')``.
View
1 jinja2/defaults.py
@@ -24,6 +24,7 @@
DEFAULT_NAMESPACE = {
'range': xrange,
+ 'dict': lambda **kw: kw,
'lipsum': generate_lorem_ipsum
}
View
3 jinja2/filters.py
@@ -19,7 +19,6 @@
from jinja2.exceptions import FilterArgumentError
-_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
_word_re = re.compile(r'\w+')
@@ -428,7 +427,7 @@ def do_striptags(value):
"""
if hasattr(value, '__html__'):
value = value.__html__()
- return u' '.join(_striptags_re.sub('', value).split())
+ return Markup(unicode(value)).striptags()
def do_slice(value, slices, fill_with=None):
View
15 jinja2/sandbox.py
@@ -20,14 +20,22 @@
#: maximum number of items a range may produce
MAX_RANGE = 100000
+#: attributes of function objects that are considered unsafe.
+UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict',
+ 'func_defaults', 'func_globals'])
+
+#: unsafe method attributes. function attributes are unsafe for methods too
+UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self'])
+
def safe_range(*args):
"""A range that can't generate ranges with a length of more than
MAX_RANGE items.
"""
rng = xrange(*args)
if len(rng) > MAX_RANGE:
- raise OverflowError('range too big')
+ raise OverflowError('range too big, maximum size for range is %d' %
+ MAX_RANGE)
return rng
@@ -54,9 +62,10 @@ def is_safe_attribute(self, obj, attr, value):
if attr.startswith('_'):
return False
if isinstance(obj, FunctionType):
- return not attr.startswith('func_')
+ return attr not in UNSAFE_FUNCTION_ATTRIBUTES
if isinstance(obj, MethodType):
- return not attr.startswith('im_')
+ return attr not in UNSAFE_FUNCTION_ATTRIBUTES and \
+ attr not in UNSAFE_METHOD_ATTRIBUTES
return True
def is_safe_callable(self, obj):
View
27 jinja2/utils.py
@@ -15,6 +15,7 @@
from thread import allocate_lock
except ImportError:
from dummy_thread import allocate_lock
+from htmlentitydefs import name2codepoint
from collections import deque
from copy import deepcopy
from itertools import imap
@@ -28,7 +29,10 @@
)
)
_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
-
+_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
+_entity_re = re.compile(r'&([^;]+);')
+_entities = name2codepoint.copy()
+_entities['apos'] = 39
# special singleton representing missing values for the runtime
missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
@@ -278,6 +282,27 @@ def splitlines(self, *args, **kwargs):
return map(self.__class__, unicode.splitlines(self, *args, **kwargs))
splitlines.__doc__ = unicode.splitlines.__doc__
+ def unescape(self):
+ """Unescape markup."""
+ def handle_match(m):
+ name = m.group(1)
+ if name in _entities:
+ return unichr(_entities[name])
+ try:
+ if name[:2] in ('#x', '#X'):
+ return unichr(int(name[2:], 16))
+ elif name.startswith('#'):
+ return unichr(int(name[1:]))
+ except ValueError:
+ pass
+ return u''
+ return _entity_re.sub(handle_match, unicode(self))
+
+ def striptags(self):
+ """Strip tags and resolve enities."""
+ stripped = u' '.join(_striptags_re.sub('', self).split())
+ return Markup(stripped).unescape()
+
def make_wrapper(name):
orig = getattr(unicode, name)
def func(self, *args, **kwargs):

0 comments on commit 76c280b

Please sign in to comment.