def getXML(self):
vars = {
"id": self.id,
"type": self.type,
"meta": self.meta,
"actions": list(map(self._getBitRenderer('actions'), self.actions)),
"properties": list(map(self._getBitRenderer('properties'), self.properties)),
"scms": list(map(self._getBitRenderer('scms'), self.scms)),
"triggers": list(map(self._getBitRenderer('triggers'), self.triggers)),
"builders": list(map(self._getBitRenderer('builders'), self.builders)),
"publishers": list(map(self._getBitRenderer('publishers'), self.publishers)),
"wrappers": list(map(self._getBitRenderer('wrappers'), self.wrappers)),
}
vars = {**vars, **self.vars}
try:
return env.get_template(self._getTypeTemplate()).render(vars)
except UndefinedError as e:
log.fatal("Failed to render job '{}' ({}):\n{}".format(self.id, self.type, e))
exit(-1)
except TemplateNotFound as e:
log.fatal("Failed to find job template 'jobtypes/{}.j2' in following locations:\n{}".format(
self.type, ',\n'.join(env.loader.searchpath)))
exit(-1)
python类UndefinedError()的实例源码
def render_template(template_name, **kwargs):
"""
Simple utility function to render out a specified template, using
**kwargs to fill in variables.
Args:
template_path (str): The directory where we can find the template.
template_name (str): The actual name of the template we want to
render.
**kwargs (dict): Key Value pairs of any variables we want rendered
out into the template.
Raises:
AncillaryFileNotFound: If we cannot find the template.
AncillaryUndefinedError: If we run across an undefined variable.
"""
# Attempt to load a Tempalte file from within the 'Zapper' package
# and raise an IOError if I'm unable to find it.
try:
env = Environment(loader=PackageLoader('zapper', 'templates'))
template = env.get_template(template_name)
except TemplateNotFound:
raise IOError('Unable to find template {} in zapper!'
.format(template_name))
# Attempt to render our template, and raise a Value Error if we
# run into any undefined variables.
try:
template_data = template.render(**kwargs)
except UndefinedError as e:
raise ValueError('Undefined variable found in {}! Error: {}'
.format(template_name, e))
return template_data
def test_chart_data_template(self):
"""Protect chart_data from being able to do RCE."""
session = settings.Session()
Chart = models.Chart
chart1 = Chart(
label='insecure_chart',
conn_id='airflow_db',
chart_type='bar',
sql="SELECT {{ ''.__class__.__mro__[1].__subclasses__() }}"
)
chart2 = Chart(
label="{{ ''.__class__.__mro__[1].__subclasses__() }}",
conn_id='airflow_db',
chart_type='bar',
sql="SELECT 1"
)
chart3 = Chart(
label="{{ subprocess.check_output('ls') }}",
conn_id='airflow_db',
chart_type='bar',
sql="SELECT 1"
)
session.add(chart1)
session.add(chart2)
session.add(chart3)
session.commit()
chart1_id = session.query(Chart).filter(Chart.label=='insecure_chart').first().id
with self.assertRaises(SecurityError):
response = self.app.get("/admin/airflow/chart_data?chart_id={}".format(chart1_id))
chart2_id = session.query(Chart).filter(Chart.label=="{{ ''.__class__.__mro__[1].__subclasses__() }}").first().id
with self.assertRaises(SecurityError):
response = self.app.get("/admin/airflow/chart_data?chart_id={}".format(chart2_id))
chart3_id = session.query(Chart).filter(Chart.label=="{{ subprocess.check_output('ls') }}").first().id
with self.assertRaises(UndefinedError):
response = self.app.get("/admin/airflow/chart_data?chart_id={}".format(chart3_id))
def template(self, temp):
try:
template = jinja2.Template(temp)
return template.render(my=self._my, mod=self)
except jinja2.UndefinedError as err:
self._logger.error('Module template. Render Jinja2 error. ', err)
except:
self._logger.error('Module template. Render Jinja2 error. Unknown error')
def _render(self, my, temp):
if type(temp).__name__ == 'str':
data = None
try:
template = jinja2.Template(temp)
data = template.render(my=my, mod=LoadModules(_my=my))
except jinja2.UndefinedError as err:
self._logger.error('Render Jinja2 error. ', err)
except:
self._logger.error('Render Jinja2 error. Unknown error')
return data
def test_extract_jinja_error_undefined_variable(data_dir):
tpl_name = 'template.txt'
tpl_path = data_dir.join(tpl_name)
try:
templates.render(unicode(data_dir), tpl_name, {})
except jinja2.UndefinedError:
stack, error = templates.extract_jinja_error(sys.exc_info())
assert stack == [
' File "%s", line 1' % tpl_path,
' My name is {{ name }}',
]
assert error == "Undefined variable: 'name' is undefined"
def test_extract_jinja_error_with_fnames_prefix(data_dir):
tpl_name = 'template.txt'
try:
templates.render(unicode(data_dir), tpl_name, {})
except jinja2.UndefinedError:
stack, error = templates.extract_jinja_error(sys.exc_info(),
unicode(data_dir))
assert stack == [
' File "template.txt", line 1',
' My name is {{ name }}',
]
assert error == "Undefined variable: 'name' is undefined"
def extract_jinja_error(exc_info, fnames_prefix=None):
'''
Extract relevant informations from a Jinja2 exception.
*exc_info* should be a ``(exc_type, exc_value, traceback)`` tuple, as
returned by :func:`sys.exc_info`.
Return a ``(stack, error)`` tuple, where *stack* a list of lines describing
the stack that led to the error, and *error* the description of the error.
Raise a :class:`TypeError` if the error is not a supported Jinja2 error.
'''
exc_type, exc_value, tb = exc_info
if exc_type is jinja2.UndefinedError:
prefix = u'Undefined variable'
elif exc_type is jinja2.TemplateSyntaxError:
prefix = u'Syntax error'
else:
raise TypeError(exc_type)
stack_lines = []
jinja_tb = [x for x in traceback.extract_tb(tb)
if x[2] in ('top-level template code', 'template')]
for file_name, line, func_name, text in jinja_tb:
if fnames_prefix is not None:
file_name = file_name[len(fnames_prefix) + 1:]
stack_lines.append(u' File "%s", line %s' % (file_name, line))
stack_lines.append(u' %s' % text)
error_details = unicode(exc_value)
error_details = error_details.rstrip('.')
return stack_lines, u'%s: %s' % (prefix, error_details)
def warn(self):
try:
self._fail_with_undefined_error()
except UndefinedError, e:
msg = str(e)
task.echo(task.terminal().bold_red("warning: %s (this will become an error soon)" % msg))
def _getBitXML(self, bit_class, bit):
bit_name, bit_data = bit
try:
template = env.get_template("{}/{}.j2".format(bit_class, bit_name))
return template.render(bit_data)
except UndefinedError as e:
log.fatal("Failed to render bit '{}' in job '{}':\n{}".format(bit_class, self.id, bit))
exit(-1)
except TemplateNotFound as e:
log.fatal("Failed to find bit '{}/{}.j2' for job '{}' in following locations:\n{}".format(
bit_class, bit_name, self.id, ',\n'.join(env.loader.searchpath)))
exit(-1)
def test_template_error(host):
with pytest.raises(jinja2.UndefinedError):
await file.put([dict(src='error.j2', dst='/tmp/xx0')])
def get_parsed_lines(self):
''' Returns a set of lines with all variables filed in '''
try:
return Template(self.profile, undefined=StrictUndefined).render(self.variables)
except UndefinedError as e:
raise Exception(e)
def run(self, results):
"""Writes report.
@param results: Cuckoo results dict.
@raise CuckooReportError: if fails to write report.
"""
if not HAVE_JINJA2:
raise CuckooReportError("Failed to generate HTML report: "
"Jinja2 Python library is not installed")
shots_path = os.path.join(self.analysis_path, "shots")
if os.path.exists(shots_path):
shots = []
counter = 1
for shot_name in os.listdir(shots_path):
if not shot_name.endswith(".jpg"):
continue
shot_path = os.path.join(shots_path, shot_name)
if os.path.getsize(shot_path) == 0:
continue
shot = {}
shot["id"] = os.path.splitext(File(shot_path).get_name())[0]
shot["data"] = base64.b64encode(open(shot_path, "rb").read())
shots.append(shot)
counter += 1
shots.sort(key=lambda shot: shot["id"])
results["shots"] = shots
else:
results["shots"] = []
env = Environment(autoescape=True)
env.loader = FileSystemLoader(os.path.join(CUCKOO_ROOT,
"data", "html"))
try:
tpl = env.get_template("report.html")
html = tpl.render({"results": results, "summary_report" : False})
except UndefinedError as e:
raise CuckooReportError("Failed to generate summary HTML report: {} ".format(e))
except TemplateNotFound as e:
raise CuckooReportError("Failed to generate summary HTML report: {} {} ".format(e, e.name))
except (TemplateSyntaxError, TemplateAssertionError) as e:
raise CuckooReportError("Failed to generate summary HTML report: {} on {}, line {} ".format(e, e.name,
e.lineno))
try:
with codecs.open(os.path.join(self.reports_path, "report.html"), "w", encoding="utf-8") as report:
report.write(html)
except (TypeError, IOError) as e:
raise CuckooReportError("Failed to write HTML report: %s" % e)
return True