X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/3105e851ce4d7d426b3cffbd601c5b4e12075b41..ca4643640b3e41bc557ecd996d835e67ef707d5e:/validators.py diff --git a/validators.py b/validators.py index 106db8b..5ae9409 100644 --- a/validators.py +++ b/validators.py @@ -1,15 +1,18 @@ from django.utils.translation import ugettext_lazy as _ from django.core.validators import RegexValidator from django.core.exceptions import ValidationError +from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR, TemplateSyntaxError from django.utils import simplejson as json +from django.utils.html import escape, mark_safe import re +from philo.utils import LOADED_TEMPLATE_ATTR -LOADED_TEMPLATE_ATTR = '_philo_loaded_template' INSECURE_TAGS = ( 'load', 'extends', 'include', + 'debug', ) @@ -43,11 +46,8 @@ class URLLinkValidator(RegexValidator): def json_validator(value): try: json.loads(value) - except: - raise ValidationError(u'\'%s\' is not valid JSON' % value) - - -from django.template import Template, Parser, Lexer, TOKEN_BLOCK + except Exception, e: + raise ValidationError(u'JSON decode error: %s' % e) class TemplateValidationParser(Parser): @@ -59,7 +59,7 @@ class TemplateValidationParser(Parser): if secure: disallow |= set(INSECURE_TAGS) - self.allow, self.disallow = allow, disallow + self.allow, self.disallow, self.secure = allow, disallow, secure def parse(self, parse_until=None): if parse_until is None: @@ -112,7 +112,19 @@ class TemplateValidationParser(Parser): return nodelist def disallowed_tag(self, command): - raise ValidationError("Tag not allowed: %s" % command) + if self.secure and command in INSECURE_TAGS: + raise ValidationError('Tag "%s" is not permitted for security reasons.' % command) + raise ValidationError('Tag "%s" is not permitted here.' % command) + + +def linebreak_iter(template_source): + # Cribbed from django/views/debug.py + yield 0 + p = template_source.find('\n') + while p >= 0: + yield p+1 + p = template_source.find('\n', p+1) + yield len(template_source) + 1 class TemplateValidator(object): @@ -127,6 +139,14 @@ class TemplateValidator(object): except ValidationError: raise except Exception, e: + if hasattr(e, 'source') and isinstance(e, TemplateSyntaxError): + origin, (start, end) = e.source + template_source = origin.reload() + upto = 0 + for num, next in enumerate(linebreak_iter(template_source)): + if start >= upto and end <= next: + raise ValidationError(mark_safe("Template code invalid: \"%s\" (%s:%d).
%s" % (escape(template_source[start:end]), origin.loadname, num, e))) + upto = next raise ValidationError("Template code invalid. Error was: %s: %s" % (e.__class__.__name__, e)) def validate_template(self, template_string):