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',
)
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):
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:
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:18
+ 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):
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).<br />%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):