mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 18:28:14 +02:00
Move state length validation to StateMachine APIs (#143681)
* Move state length validation to StateMachine async_set method We call validate_state to make sure we do not allow any states into the state machine that have a length>255 so we do not break the recorder. Since async_set_internal already requires callers to pre-validate the state, we can move the check to async_set instead of at State object creation time to avoid needing to check it twice in the hot path (entity write state) * move check in async_set_internal so it only happens on state change * no need to check if same_state
This commit is contained in:
@ -72,6 +72,7 @@ from .const import (
|
||||
MAX_EXPECTED_ENTITY_IDS,
|
||||
MAX_LENGTH_EVENT_EVENT_TYPE,
|
||||
MAX_LENGTH_STATE_STATE,
|
||||
STATE_UNKNOWN,
|
||||
__version__,
|
||||
)
|
||||
from .exceptions import (
|
||||
@ -1794,18 +1795,13 @@ class State:
|
||||
) -> None:
|
||||
"""Initialize a new state."""
|
||||
self._cache: dict[str, Any] = {}
|
||||
state = str(state)
|
||||
|
||||
if validate_entity_id and not valid_entity_id(entity_id):
|
||||
raise InvalidEntityFormatError(
|
||||
f"Invalid entity id encountered: {entity_id}. "
|
||||
"Format should be <domain>.<object_id>"
|
||||
)
|
||||
|
||||
validate_state(state)
|
||||
|
||||
self.entity_id = entity_id
|
||||
self.state = state
|
||||
self.state = state if type(state) is str else str(state)
|
||||
# State only creates and expects a ReadOnlyDict so
|
||||
# there is no need to check for subclassing with
|
||||
# isinstance here so we can use the faster type check.
|
||||
@ -2270,9 +2266,11 @@ class StateMachine:
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
state = str(new_state)
|
||||
validate_state(state)
|
||||
self.async_set_internal(
|
||||
entity_id.lower(),
|
||||
str(new_state),
|
||||
state,
|
||||
attributes or {},
|
||||
force_update,
|
||||
context,
|
||||
@ -2298,6 +2296,8 @@ class StateMachine:
|
||||
breaking changes to this function in the future and it
|
||||
should not be used in integrations.
|
||||
|
||||
Callers are responsible for ensuring the entity_id is lower case.
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
# Most cases the key will be in the dict
|
||||
@ -2356,6 +2356,16 @@ class StateMachine:
|
||||
assert old_state is not None
|
||||
attributes = old_state.attributes
|
||||
|
||||
if not same_state and len(new_state) > MAX_LENGTH_STATE_STATE:
|
||||
_LOGGER.error(
|
||||
"State %s for %s is longer than %s, falling back to %s",
|
||||
new_state,
|
||||
entity_id,
|
||||
MAX_LENGTH_STATE_STATE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
new_state = STATE_UNKNOWN
|
||||
|
||||
# This is intentionally called with positional only arguments for performance
|
||||
# reasons
|
||||
state = State(
|
||||
|
Reference in New Issue
Block a user