From ee74f95371623b888885728b9b110a4dd0810488 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Wed, 22 Jan 2020 00:24:59 -0500 Subject: [PATCH] Enhance info_from_service function in zeroconf integration (#31059) * enhance zeroconf service info decoding to include raw bytes * Update homeassistant/components/zeroconf/__init__.py Co-Authored-By: Paulus Schoutsen * fix test based on last commit * fix test based on last commit * remove .keys() when asserting processed and raw service info properties Co-authored-by: Paulus Schoutsen --- homeassistant/components/zeroconf/__init__.py | 13 +++++++++---- tests/components/zeroconf/test_init.py | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index d6be4cdf6a0..b4dbbda51f1 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -148,15 +148,20 @@ def handle_homekit(hass, info) -> bool: def info_from_service(service): """Return prepared info from mDNS entries.""" - properties = {} + properties = {"_raw": {}} for key, value in service.properties.items(): + # See https://ietf.org/rfc/rfc6763.html#section-6.4 and + # https://ietf.org/rfc/rfc6763.html#section-6.5 for expected encodings + # for property keys and values + key = key.decode("ascii") + properties["_raw"][key] = value + try: if isinstance(value, bytes): - value = value.decode("utf-8") - properties[key.decode("utf-8")] = value + properties[key] = value.decode("utf-8") except UnicodeDecodeError: - _LOGGER.warning("Unicode decode error on %s: %s", key, value) + pass address = service.addresses[0] diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index 34a500f1733..c5790dc718c 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -31,7 +31,7 @@ def get_service_info_mock(service_type, name): weight=0, priority=0, server="name.local.", - properties={b"macaddress": b"ABCDEF012345"}, + properties={b"macaddress": b"ABCDEF012345", b"non-utf8-value": b"ABCDEF\x8a"}, ) @@ -93,3 +93,16 @@ async def test_homekit_match_full(hass, mock_zeroconf): assert len(mock_service_browser.mock_calls) == 1 assert len(mock_config_flow.mock_calls) == 2 assert mock_config_flow.mock_calls[0][1][0] == "hue" + + +async def test_info_from_service_non_utf8(hass): + """Test info_from_service handles non UTF-8 property values correctly.""" + service_type = "_test._tcp.local." + info = zeroconf.info_from_service( + get_service_info_mock(service_type, f"test.{service_type}") + ) + raw_info = info["properties"].pop("_raw", False) + assert raw_info + assert len(info["properties"]) <= len(raw_info) + assert "non-utf8-value" not in info["properties"] + assert raw_info["non-utf8-value"] is not None