Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def __init__(self, environment, node, source):
self.environment = environment
self.loader = environment.loader.get_controlled_loader()
self.node = node
self.source = source
self.closed = False
#: current level of indention
self.indention = 0
#: each {% cycle %} tag has a unique ID which increments
#: automatically for each tag.
self.last_cycle_id = 0
#: set of used shortcuts jinja has to make local automatically
self.used_shortcuts = set(['undefined_singleton'])
#: set of used datastructures jinja has to import
self.used_data_structures = set()
#: set of used utils jinja has to import
self.used_utils = set()
#: flags for runtime error
self.require_runtime_error = False
#: do wee need a "set" object?
self.need_set_import = False
#: flag for regular expressions
self.compiled_regular_expressions = {}
#: bind the nodes to the callback functions. There are
#: some missing! A few are specified in the `unhandled`
#: mapping in order to disallow their usage, some of them
#: will not appear in the jinja parser output because
#: they are filtered out.
self.handlers = {
# block nodes
def __init__(self, environment, source, filename=None):
self.environment = environment
if isinstance(source, str):
source = source.decode(environment.template_charset, 'ignore')
if isinstance(filename, unicode):
filename = filename.encode('utf-8')
self.source = source
self.filename = filename
self.closed = False
#: set for blocks in order to keep them unique
self.blocks = set()
#: mapping of directives that require special treatment
self.directives = {
# "fake" directives that just trigger errors
'raw': self.parse_raw_directive,
'extends': self.parse_extends_directive,
# real directives
'for': self.parse_for_loop,
'if': self.parse_if_condition,
'cycle': self.parse_cycle_directive,
'call': self.parse_call_directive,
'set': self.parse_set_directive,
'filter': self.parse_filter_directive,
'print': self.parse_print_directive,
'macro': self.parse_macro_directive,
self.indention = 1
# if there is a parent template we parse the parent template and
# update the blocks there. Once this is done we drop the current
# template in favor of the new one. Do that until we found the
# root template.
parent = None
overwrites = {}
blocks = {}
requirements = []
outer_filename = node.filename or '<template>'
# this set is required in order to not add blocks to the block
# dict a second time if they were not overridden in one template
# in the template chain.
already_registered_block = set()
while node.extends is not None:
# the direct child nodes in a template that are not blocks
# are processed as template globals, thus executed *before*
# the master layout template is loaded. This can be used
# for further processing. The output of those nodes does
# not appear in the final template.
requirements += [child for child in node.body.get_child_nodes()
if child.__class__ not in (nodes.Text,
nodes.Block)]
# load the template we inherit from and add not known blocks.
# this also marks the templates on the controlled loader but
# are never removed. that's no problem because we don't allow
# parents we extend from as includes and the controlled loader
# is only used for this templated</template>
'for': self.parse_for_loop,
'if': self.parse_if_condition,
'cycle': self.parse_cycle_directive,
'call': self.parse_call_directive,
'set': self.parse_set_directive,
'filter': self.parse_filter_directive,
'print': self.parse_print_directive,
'macro': self.parse_macro_directive,
'block': self.parse_block_directive,
'include': self.parse_include_directive,
'trans': self.parse_trans_directive
}
#: set of directives that are only available in a certain
#: context.
self.context_directives = set([
'elif', 'else', 'endblock', 'endfilter', 'endfor', 'endif',
'endmacro', 'endraw', 'endtrans', 'pluralize'
])
#: get the `no_variable_block` flag
self.no_variable_block = self.environment.lexer.no_variable_block
self.stream = environment.lexer.tokenize(source, filename)
def __init__(self, environment, node, source):
self.environment = environment
self.loader = environment.loader.get_controlled_loader()
self.node = node
self.source = source
self.closed = False
#: current level of indention
self.indention = 0
#: each {% cycle %} tag has a unique ID which increments
#: automatically for each tag.
self.last_cycle_id = 0
#: set of used shortcuts jinja has to make local automatically
self.used_shortcuts = set(['undefined_singleton'])
#: set of used datastructures jinja has to import
self.used_data_structures = set()
#: set of used utils jinja has to import
self.used_utils = set()
#: flags for runtime error
self.require_runtime_error = False
#: do wee need a "set" object?
self.need_set_import = False
#: flag for regular expressions
self.compiled_regular_expressions = {}
#: bind the nodes to the callback functions. There are
#: some missing! A few are specified in the `unhandled`
#: mapping in order to disallow their usage, some of them
#: will not appear in the jinja parser output because
#: they are filtered out.
end_of_comment = StateTest.expect_token('comment_end',
msg='expected end of comment')
# internal tag callbacks
switch_for = StateTest.expect_token('else', 'endfor')
end_of_for = StateTest.expect_token('endfor')
switch_if = StateTest.expect_token('else', 'elif', 'endif')
end_of_if = StateTest.expect_token('endif')
end_of_filter = StateTest.expect_token('endfilter')
end_of_macro = StateTest.expect_token('endmacro')
end_of_call = StateTest.expect_token('endcall')
end_of_block_tag = StateTest.expect_token('endblock')
end_of_trans = StateTest.expect_token('endtrans')
# this ends a tuple
tuple_edge_tokens = set(['rparen', 'block_end', 'variable_end', 'in',
'recursive'])
class Parser(object):
"""
The template parser class.
Transforms sourcecode into an abstract syntax tree.
"""
def __init__(self, environment, source, filename=None):
self.environment = environment
if isinstance(source, str):
source = source.decode(environment.template_charset, 'ignore')
if isinstance(filename, unicode):
filename = filename.encode('utf-8')
def parse_compare_expression(self):
"""
Parse something like {{ foo == bar }}.
"""
known_operators = set(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq', 'in'])
lineno = self.stream.lineno
expr = self.parse_add_expression()
ops = []
while True:
if self.stream.current.type in known_operators:
op = self.stream.current.type
self.stream.next()
ops.append([op, self.parse_add_expression()])
elif self.stream.current.type == 'not' and \
self.stream.look().type == 'in':
self.stream.skip(2)
ops.append(['not in', self.parse_add_expression()])
else:
break
if not ops:
return expr
self.loader = environment.loader.get_controlled_loader()
self.node = node
self.source = source
self.closed = False
#: current level of indention
self.indention = 0
#: each {% cycle %} tag has a unique ID which increments
#: automatically for each tag.
self.last_cycle_id = 0
#: set of used shortcuts jinja has to make local automatically
self.used_shortcuts = set(['undefined_singleton'])
#: set of used datastructures jinja has to import
self.used_data_structures = set()
#: set of used utils jinja has to import
self.used_utils = set()
#: flags for runtime error
self.require_runtime_error = False
#: do wee need a "set" object?
self.need_set_import = False
#: flag for regular expressions
self.compiled_regular_expressions = {}
#: bind the nodes to the callback functions. There are
#: some missing! A few are specified in the `unhandled`
#: mapping in order to disallow their usage, some of them
#: will not appear in the jinja parser output because
#: they are filtered out.
self.handlers = {
# block nodes
nodes.Template: self.handle_template,
nodes.Text: self.handle_template_text,