From 2b62285eeea5fce546337114066957b45895e6a7 Mon Sep 17 00:00:00 2001 From: Mike Degatano Date: Tue, 12 Sep 2023 09:59:12 -0400 Subject: [PATCH] Fix addon slug validation (#100070) * Fix addon slug validation * Don't redefine compile --- homeassistant/components/hassio/__init__.py | 5 ++- tests/components/hassio/test_init.py | 35 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/hassio/__init__.py b/homeassistant/components/hassio/__init__.py index 72fb5ce5110..270309149ef 100644 --- a/homeassistant/components/hassio/__init__.py +++ b/homeassistant/components/hassio/__init__.py @@ -6,6 +6,7 @@ from contextlib import suppress from datetime import datetime, timedelta import logging import os +import re from typing import Any, NamedTuple import voluptuous as vol @@ -149,10 +150,12 @@ SERVICE_BACKUP_PARTIAL = "backup_partial" SERVICE_RESTORE_FULL = "restore_full" SERVICE_RESTORE_PARTIAL = "restore_partial" +VALID_ADDON_SLUG = vol.Match(re.compile(r"^[-_.A-Za-z0-9]+$")) + def valid_addon(value: Any) -> str: """Validate value is a valid addon slug.""" - value = cv.slug(value) + value = VALID_ADDON_SLUG(value) hass: HomeAssistant | None = None with suppress(HomeAssistantError): diff --git a/tests/components/hassio/test_init.py b/tests/components/hassio/test_init.py index 31ee73013da..48f52ee7c24 100644 --- a/tests/components/hassio/test_init.py +++ b/tests/components/hassio/test_init.py @@ -633,6 +633,41 @@ async def test_invalid_service_calls( ) +async def test_addon_service_call_with_complex_slug( + hass: HomeAssistant, + aioclient_mock: AiohttpClientMocker, +) -> None: + """Addon slugs can have ., - and _, confirm that passes validation.""" + supervisor_mock_data = { + "version_latest": "1.0.0", + "version": "1.0.0", + "auto_update": True, + "addons": [ + { + "name": "test.a_1-2", + "slug": "test.a_1-2", + "state": "stopped", + "update_available": False, + "version": "1.0.0", + "version_latest": "1.0.0", + "repository": "core", + "icon": False, + }, + ], + } + with patch.dict(os.environ, MOCK_ENVIRON), patch( + "homeassistant.components.hassio.HassIO.is_connected", + return_value=None, + ), patch( + "homeassistant.components.hassio.HassIO.get_supervisor_info", + return_value=supervisor_mock_data, + ): + assert await async_setup_component(hass, "hassio", {}) + await hass.async_block_till_done() + + await hass.services.async_call("hassio", "addon_start", {"addon": "test.a_1-2"}) + + async def test_service_calls_core( hassio_env, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: