1#! /usr/bin/python 2# 3# SPDX-License-Identifier: Apache-2.0 4# Zephyr's Twister library 5# 6# pylint: disable=unused-import 7# 8# Set of code that other projects can also import to do things on 9# Zephyr's sanity check testcases. 10 11import logging 12import yaml 13try: 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 21 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: 40 return yaml.load(f, Loader=SafeLoader) 41 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 59 c = pykwalify.core.Core(source_data=data, schema_data=schema) 60 c.validate(raise_exception=True) 61 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 83