Ignore invalid zeroconf names from devices with broken firmwares (#87414)

This commit is contained in:
J. Nick Koston 2023-02-04 16:29:03 -06:00 committed by GitHub
parent 3be6d4dcfb
commit 4d0e236c6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 3 deletions

View file

@ -15,7 +15,12 @@ import sys
from typing import Any, Final, cast from typing import Any, Final, cast
import voluptuous as vol import voluptuous as vol
from zeroconf import InterfaceChoice, IPVersion, ServiceStateChange from zeroconf import (
BadTypeInNameException,
InterfaceChoice,
IPVersion,
ServiceStateChange,
)
from zeroconf.asyncio import AsyncServiceInfo from zeroconf.asyncio import AsyncServiceInfo
from homeassistant import config_entries from homeassistant import config_entries
@ -399,7 +404,13 @@ class ZeroconfDiscovery:
self, zeroconf: HaZeroconf, service_type: str, name: str self, zeroconf: HaZeroconf, service_type: str, name: str
) -> None: ) -> None:
"""Process a zeroconf update.""" """Process a zeroconf update."""
try:
async_service_info = AsyncServiceInfo(service_type, name) async_service_info = AsyncServiceInfo(service_type, name)
except BadTypeInNameException as ex:
# Some devices broadcast a name that is not a valid DNS name
# This is a bug in the device firmware and we should ignore it
_LOGGER.debug("Bad name in zeroconf record: %s: %s", name, ex)
return
await async_service_info.async_request(zeroconf, 3000) await async_service_info.async_request(zeroconf, 3000)
info = info_from_service(async_service_info) info = info_from_service(async_service_info)

View file

@ -3,7 +3,12 @@ from ipaddress import ip_address
from typing import Any from typing import Any
from unittest.mock import call, patch from unittest.mock import call, patch
from zeroconf import InterfaceChoice, IPVersion, ServiceStateChange from zeroconf import (
BadTypeInNameException,
InterfaceChoice,
IPVersion,
ServiceStateChange,
)
from zeroconf.asyncio import AsyncServiceInfo from zeroconf.asyncio import AsyncServiceInfo
from homeassistant.components import zeroconf from homeassistant.components import zeroconf
@ -564,6 +569,37 @@ async def test_homekit_match_partial_space(hass, mock_async_zeroconf):
} }
async def test_device_with_invalid_name(hass, mock_async_zeroconf, caplog):
"""Test we ignore devices with an invalid name."""
with patch.dict(
zc_gen.ZEROCONF,
{"_hap._tcp.local.": [{"domain": "homekit_controller"}]},
clear=True,
), patch.dict(
zc_gen.HOMEKIT,
{"LIFX": "lifx"},
clear=True,
), patch.object(
hass.config_entries.flow, "async_init"
) as mock_config_flow, patch.object(
zeroconf,
"HaAsyncServiceBrowser",
side_effect=lambda *args, **kwargs: service_update_mock(
*args, **kwargs, limit_service="_hap._tcp.local."
),
) as mock_service_browser, patch(
"homeassistant.components.zeroconf.AsyncServiceInfo",
side_effect=BadTypeInNameException,
):
assert await async_setup_component(hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {}})
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done()
assert len(mock_service_browser.mock_calls) == 1
assert len(mock_config_flow.mock_calls) == 0
assert "Bad name in zeroconf record" in caplog.text
async def test_homekit_match_partial_dash(hass, mock_async_zeroconf): async def test_homekit_match_partial_dash(hass, mock_async_zeroconf):
"""Test configured options for a device are loaded via config entry.""" """Test configured options for a device are loaded via config entry."""
with patch.dict( with patch.dict(