blob: 7c1a430e83d9efbe5cecf9a742ab29e61b978d17 [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
24#
25#
26def yaml_load(filename):
27 """
28 Safely load a YAML document
29
30 Follows recomendations from
31 https://security.openstack.org/guidelines/dg_avoid-dangerous-input-parsing-libraries.html.
32
33 :param str filename: filename to load
34 :raises yaml.scanner: On YAML scan issues
35 :raises: any other exception on file access erors
36 :return: dictionary representing the YAML document
37 """
38 try:
39 with open(filename, 'r') as f:
Anas Nashifae61b7e2020-07-06 11:30:55 -040040 return yaml.load(f, Loader=SafeLoader)
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070041 except yaml.scanner.ScannerError as e: # For errors parsing schema.yaml
42 mark = e.problem_mark
43 cmark = e.context_mark
44 log.error("%s:%d:%d: error: %s (note %s context @%s:%d:%d %s)",
45 mark.name, mark.line, mark.column, e.problem,
46 e.note, cmark.name, cmark.line, cmark.column, e.context)
47 raise
48
49# If pykwalify is installed, then the validate functionw ill work --
50# otherwise, it is a stub and we'd warn about it.
51try:
52 import pykwalify.core
53 # Don't print error messages yourself, let us do it
54 logging.getLogger("pykwalify.core").setLevel(50)
55
56 def _yaml_validate(data, schema):
57 if not schema:
58 return
Ulf Magnusson0d39a102019-09-06 11:13:19 +020059 c = pykwalify.core.Core(source_data=data, schema_data=schema)
60 c.validate(raise_exception=True)
Inaky Perez-Gonzalez662dde62017-07-24 10:24:35 -070061
62except ImportError as e:
63 log.warning("can't import pykwalify; won't validate YAML (%s)", e)
64 def _yaml_validate(data, schema):
65 pass
66
67def yaml_load_verify(filename, schema):
68 """
69 Safely load a testcase/sample yaml document and validate it
70 against the YAML schema, returing in case of success the YAML data.
71
72 :param str filename: name of the file to load and process
73 :param dict schema: loaded YAML schema (can load with :func:`yaml_load`)
74
75 # 'document.yaml' contains a single YAML document.
76 :raises yaml.scanner.ScannerError: on YAML parsing error
77 :raises pykwalify.errors.SchemaError: on Schema violation error
78 """
79 # 'document.yaml' contains a single YAML document.
80 y = yaml_load(filename)
81 _yaml_validate(y, schema)
82 return y