Handle !include without arguments in configuration.yaml (#124399)

* Prevent !include without arguments in configuration.yaml from crashing core

* Add test
pull/124406/head
Erik Montnemery 2024-08-22 12:08:24 +02:00 committed by GitHub
parent 480e748b04
commit ab6d0e3277
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 0 deletions

View File

@ -348,6 +348,20 @@ def _add_reference_to_node_class(
return obj
def _raise_if_no_value[NodeT: yaml.nodes.Node, _R](
func: Callable[[LoaderType, NodeT], _R],
) -> Callable[[LoaderType, NodeT], _R]:
def wrapper(loader: LoaderType, node: NodeT) -> _R:
if not node.value:
raise HomeAssistantError(
f"{node.start_mark}: {node.tag} needs an argument."
)
return func(loader, node)
return wrapper
@_raise_if_no_value
def _include_yaml(loader: LoaderType, node: yaml.nodes.Node) -> JSON_TYPE:
"""Load another YAML file and embed it using the !include tag.
@ -382,6 +396,7 @@ def _find_files(directory: str, pattern: str) -> Iterator[str]:
yield filename
@_raise_if_no_value
def _include_dir_named_yaml(loader: LoaderType, node: yaml.nodes.Node) -> NodeDictClass:
"""Load multiple files from directory as a dictionary."""
mapping = NodeDictClass()
@ -399,6 +414,7 @@ def _include_dir_named_yaml(loader: LoaderType, node: yaml.nodes.Node) -> NodeDi
return _add_reference_to_node_class(mapping, loader, node)
@_raise_if_no_value
def _include_dir_merge_named_yaml(
loader: LoaderType, node: yaml.nodes.Node
) -> NodeDictClass:
@ -414,6 +430,7 @@ def _include_dir_merge_named_yaml(
return _add_reference_to_node_class(mapping, loader, node)
@_raise_if_no_value
def _include_dir_list_yaml(
loader: LoaderType, node: yaml.nodes.Node
) -> list[JSON_TYPE]:
@ -427,6 +444,7 @@ def _include_dir_list_yaml(
]
@_raise_if_no_value
def _include_dir_merge_list_yaml(
loader: LoaderType, node: yaml.nodes.Node
) -> JSON_TYPE:

View File

@ -726,3 +726,23 @@ def test_load_yaml_dict_fail() -> None:
"""Test item without a key."""
with pytest.raises(yaml_loader.YamlTypeError):
yaml_loader.load_yaml_dict(YAML_CONFIG_FILE)
@pytest.mark.parametrize(
"tag",
[
"!include",
"!include_dir_named",
"!include_dir_merge_named",
"!include_dir_list",
"!include_dir_merge_list",
],
)
@pytest.mark.usefixtures("try_both_loaders")
def test_include_without_parameter(tag: str) -> None:
"""Test include extensions without parameters."""
with (
io.StringIO(f"key: {tag}") as file,
pytest.raises(HomeAssistantError, match=f"{tag} needs an argument"),
):
yaml_loader.parse_yaml(file)