Enforce maximum length for HomeKit characteristics (#53913)

This commit is contained in:
J. Nick Koston 2021-08-03 12:09:10 -05:00 committed by GitHub
parent fa9ac71c3a
commit df03cce471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 20 deletions

View File

@ -64,6 +64,11 @@ from .const import (
HK_NOT_CHARGABLE,
HK_NOT_CHARGING,
MANUFACTURER,
MAX_MANUFACTURER_LENGTH,
MAX_MODEL_LENGTH,
MAX_NAME_LENGTH,
MAX_SERIAL_LENGTH,
MAX_VERSION_LENGTH,
SERV_BATTERY_SERVICE,
SERVICE_HOMEKIT_RESET_ACCESSORY,
TYPE_FAUCET,
@ -217,7 +222,9 @@ class HomeAccessory(Accessory):
**kwargs,
):
"""Initialize a Accessory object."""
super().__init__(driver=driver, display_name=name, aid=aid, *args, **kwargs)
super().__init__(
driver=driver, display_name=name[:MAX_NAME_LENGTH], aid=aid, *args, **kwargs
)
self.config = config or {}
domain = split_entity_id(entity_id)[0].replace("_", " ")
@ -237,10 +244,10 @@ class HomeAccessory(Accessory):
sw_version = __version__
self.set_info_service(
manufacturer=manufacturer,
model=model,
serial_number=entity_id,
firmware_revision=sw_version,
manufacturer=manufacturer[:MAX_MANUFACTURER_LENGTH],
model=model[:MAX_MODEL_LENGTH],
serial_number=entity_id[:MAX_SERIAL_LENGTH],
firmware_revision=sw_version[:MAX_VERSION_LENGTH],
)
self.category = category

View File

@ -293,3 +293,10 @@ CONFIG_OPTIONS = [
CONF_ENTITY_CONFIG,
CONF_HOMEKIT_MODE,
]
# ### Maximum Lengths ###
MAX_NAME_LENGTH = 64
MAX_SERIAL_LENGTH = 64
MAX_MODEL_LENGTH = 64
MAX_VERSION_LENGTH = 64
MAX_MANUFACTURER_LENGTH = 64

View File

@ -39,6 +39,7 @@ from .const import (
CHAR_ROTATION_DIRECTION,
CHAR_ROTATION_SPEED,
CHAR_SWING_MODE,
MAX_NAME_LENGTH,
PROP_MIN_STEP,
SERV_FANV2,
SERV_SWITCH,
@ -100,7 +101,8 @@ class Fan(HomeAccessory):
preset_serv = self.add_preload_service(SERV_SWITCH, CHAR_NAME)
serv_fan.add_linked_service(preset_serv)
preset_serv.configure_char(
CHAR_NAME, value=f"{self.display_name} {preset_mode}"
CHAR_NAME,
value=f"{self.display_name} {preset_mode}"[:MAX_NAME_LENGTH],
)
self.preset_mode_chars[preset_mode] = preset_serv.configure_char(

View File

@ -55,6 +55,7 @@ from .const import (
FEATURE_PLAY_STOP,
FEATURE_TOGGLE_MUTE,
KEY_PLAY_PAUSE,
MAX_NAME_LENGTH,
SERV_SWITCH,
SERV_TELEVISION_SPEAKER,
)
@ -134,7 +135,7 @@ class MediaPlayer(HomeAccessory):
def generate_service_name(self, mode):
"""Generate name for individual service."""
return f"{self.display_name} {MODE_FRIENDLY_NAME[mode]}"
return f"{self.display_name} {MODE_FRIENDLY_NAME[mode]}"[:MAX_NAME_LENGTH]
def set_on_off(self, value):
"""Move switch state to value if call came from HomeKit."""

View File

@ -47,6 +47,7 @@ from .const import (
KEY_PREVIOUS_TRACK,
KEY_REWIND,
KEY_SELECT,
MAX_NAME_LENGTH,
SERV_INPUT_SOURCE,
SERV_TELEVISION,
)
@ -120,8 +121,10 @@ class RemoteInputSelectAccessory(HomeAccessory):
SERV_INPUT_SOURCE, [CHAR_IDENTIFIER, CHAR_NAME]
)
serv_tv.add_linked_service(serv_input)
serv_input.configure_char(CHAR_CONFIGURED_NAME, value=source)
serv_input.configure_char(CHAR_NAME, value=source)
serv_input.configure_char(
CHAR_CONFIGURED_NAME, value=source[:MAX_NAME_LENGTH]
)
serv_input.configure_char(CHAR_NAME, value=source[:MAX_NAME_LENGTH])
serv_input.configure_char(CHAR_IDENTIFIER, value=index)
serv_input.configure_char(CHAR_IS_CONFIGURED, value=True)
input_type = 3 if "hdmi" in source.lower() else 0

View File

@ -66,7 +66,7 @@ async def test_accessory_cancels_track_state_change_on_stop(hass, hk_driver):
async def test_home_accessory(hass, hk_driver):
"""Test HomeAccessory class."""
entity_id = "sensor.accessory"
entity_id2 = "light.accessory"
entity_id2 = "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum_maximum_maximum_maximum_allowed_length"
hass.states.async_set(entity_id, None)
hass.states.async_set(entity_id2, STATE_UNAVAILABLE)
@ -94,27 +94,42 @@ async def test_home_accessory(hass, hk_driver):
assert serv.get_characteristic(CHAR_NAME).value == "Home Accessory"
assert serv.get_characteristic(CHAR_MANUFACTURER).value == f"{MANUFACTURER} Light"
assert serv.get_characteristic(CHAR_MODEL).value == "Light"
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == "light.accessory"
assert (
serv.get_characteristic(CHAR_SERIAL_NUMBER).value
== "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum"
)
acc3 = HomeAccessory(
hass,
hk_driver,
"Home Accessory",
"Home Accessory that exceeds the maximum maximum maximum maximum maximum maximum length",
entity_id2,
3,
{
ATTR_MODEL: "Awesome",
ATTR_MANUFACTURER: "Lux Brands",
ATTR_SW_VERSION: "0.4.3",
ATTR_INTEGRATION: "luxe",
ATTR_MODEL: "Awesome Model that exceeds the maximum maximum maximum maximum maximum maximum length",
ATTR_MANUFACTURER: "Lux Brands that exceeds the maximum maximum maximum maximum maximum maximum length",
ATTR_SW_VERSION: "0.4.3 that exceeds the maximum maximum maximum maximum maximum maximum length",
ATTR_INTEGRATION: "luxe that exceeds the maximum maximum maximum maximum maximum maximum length",
},
)
assert acc3.available is False
serv = acc3.services[0] # SERV_ACCESSORY_INFO
assert serv.get_characteristic(CHAR_NAME).value == "Home Accessory"
assert serv.get_characteristic(CHAR_MANUFACTURER).value == "Lux Brands"
assert serv.get_characteristic(CHAR_MODEL).value == "Awesome"
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == "light.accessory"
assert (
serv.get_characteristic(CHAR_NAME).value
== "Home Accessory that exceeds the maximum maximum maximum maximum "
)
assert (
serv.get_characteristic(CHAR_MANUFACTURER).value
== "Lux Brands that exceeds the maximum maximum maximum maximum maxi"
)
assert (
serv.get_characteristic(CHAR_MODEL).value
== "Awesome Model that exceeds the maximum maximum maximum maximum m"
)
assert (
serv.get_characteristic(CHAR_SERIAL_NUMBER).value
== "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum"
)
hass.states.async_set(entity_id, "on")
await hass.async_block_till_done()