blob: 25a3210b141f0091d138ee16537920ce0616a3ff [file] [log] [blame]
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -07001#! /usr/bin/python
2#
Anas Nashif3ae52622019-04-06 09:08:09 -04003# SPDX-License-Identifier: Apache-2.0
Anas Nashif45943702020-12-11 17:55:15 -05004# Zephyr's Twister library
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -07005#
Anas Nashif5725ed82020-12-10 09:48:12 -05006# pylint: disable=unused-import
7#
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -07008# Set of code that other projects can also import to do things on
9# Zephyr's sanity check testcases.
10
11import logging
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070012import yaml
Anas Nashifae61b7e2020-07-06 11:30:55 -040013try:
14 # Use the C LibYAML parser if available, rather than the Python parser.
15 # It's much faster.
16 from yaml import CLoader as Loader
17 from yaml import CSafeLoader as SafeLoader
18 from yaml import CDumper as Dumper
19except ImportError:
20 from yaml import Loader, SafeLoader, Dumper
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070021
22log = logging.getLogger("scl")
23
Grzegorz Chwierutf53a0e92023-09-15 15:21:06 +020024
25class EmptyYamlFileException(Exception):
26 pass
27
28
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070029#
30#
31def yaml_load(filename):
32 """
33 Safely load a YAML document
34
Nazar Kazakovf483b1b2022-03-16 21:07:43 +000035 Follows recommendations from
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070036 https://security.openstack.org/guidelines/dg_avoid-dangerous-input-parsing-libraries.html.
37
38 :param str filename: filename to load
39 :raises yaml.scanner: On YAML scan issues
Nazar Kazakovf483b1b2022-03-16 21:07:43 +000040 :raises: any other exception on file access errors
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070041 :return: dictionary representing the YAML document
42 """
43 try:
Pavlo Havrylyukfa563662023-09-12 09:38:52 -070044 with open(filename, 'r', encoding='utf-8') as f:
Anas Nashifae61b7e2020-07-06 11:30:55 -040045 return yaml.load(f, Loader=SafeLoader)
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070046 except yaml.scanner.ScannerError as e: # For errors parsing schema.yaml
47 mark = e.problem_mark
48 cmark = e.context_mark
49 log.error("%s:%d:%d: error: %s (note %s context @%s:%d:%d %s)",
50 mark.name, mark.line, mark.column, e.problem,
51 e.note, cmark.name, cmark.line, cmark.column, e.context)
52 raise
53
Nazar Kazakovf483b1b2022-03-16 21:07:43 +000054# If pykwalify is installed, then the validate function will work --
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070055# otherwise, it is a stub and we'd warn about it.
56try:
57 import pykwalify.core
58 # Don't print error messages yourself, let us do it
59 logging.getLogger("pykwalify.core").setLevel(50)
60
61 def _yaml_validate(data, schema):
62 if not schema:
63 return
Ulf Magnusson0d39a102019-09-06 11:13:19 +020064 c = pykwalify.core.Core(source_data=data, schema_data=schema)
65 c.validate(raise_exception=True)
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070066
67except ImportError as e:
68 log.warning("can't import pykwalify; won't validate YAML (%s)", e)
69 def _yaml_validate(data, schema):
70 pass
71
72def yaml_load_verify(filename, schema):
73 """
74 Safely load a testcase/sample yaml document and validate it
Nazar Kazakovf483b1b2022-03-16 21:07:43 +000075 against the YAML schema, returning in case of success the YAML data.
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070076
77 :param str filename: name of the file to load and process
78 :param dict schema: loaded YAML schema (can load with :func:`yaml_load`)
79
80 # 'document.yaml' contains a single YAML document.
81 :raises yaml.scanner.ScannerError: on YAML parsing error
82 :raises pykwalify.errors.SchemaError: on Schema violation error
83 """
84 # 'document.yaml' contains a single YAML document.
85 y = yaml_load(filename)
Grzegorz Chwierutf53a0e92023-09-15 15:21:06 +020086 if not y:
87 raise EmptyYamlFileException('No data in YAML file: %s' % filename)
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070088 _yaml_validate(y, schema)
89 return y