Fix recorder crash for long state string - enforce at core level (#9696)

* Recorder exception catch for long state string

* Revert - Recorder exception catch for long state string

* Validate state length at core level

* Revert - this reverts commit 9d6bd017d96f20c10204d9bcb71573e3bc005ee3.

* Revert - Recorder exception catch for long state string

* Fix state TypeError

* Test for long state exception
This commit is contained in:
milanvo 2017-10-25 18:05:30 +02:00 committed by Paulus Schoutsen
parent fc8940111d
commit 7987065ad7
3 changed files with 26 additions and 3 deletions

View File

@ -32,7 +32,7 @@ from homeassistant.const import (
EVENT_SERVICE_REMOVED, __version__)
from homeassistant import loader
from homeassistant.exceptions import (
HomeAssistantError, InvalidEntityFormatError)
HomeAssistantError, InvalidEntityFormatError, InvalidStateError)
from homeassistant.util.async import (
run_coroutine_threadsafe, run_callback_threadsafe,
fire_coroutine_threadsafe)
@ -65,6 +65,11 @@ def valid_entity_id(entity_id: str) -> bool:
return ENTITY_ID_PATTERN.match(entity_id) is not None
def valid_state(state: str) -> bool:
"""Test if an state is valid."""
return len(state) < 256
def callback(func: Callable[..., None]) -> Callable[..., None]:
"""Annotation to mark method as safe to call from within the event loop."""
# pylint: disable=protected-access
@ -520,13 +525,20 @@ class State(object):
def __init__(self, entity_id, state, attributes=None, last_changed=None,
last_updated=None):
"""Initialize a new state."""
state = str(state)
if not valid_entity_id(entity_id):
raise InvalidEntityFormatError((
"Invalid entity id encountered: {}. "
"Format should be <domain>.<object_id>").format(entity_id))
if not valid_state(state):
raise InvalidStateError((
"Invalid state encountered for entity id: {}. "
"State max length is 255 characters.").format(entity_id))
self.entity_id = entity_id.lower()
self.state = str(state)
self.state = state
self.attributes = MappingProxyType(attributes or {})
self.last_updated = last_updated or dt_util.utcnow()
self.last_changed = last_changed or self.last_updated

View File

@ -32,3 +32,9 @@ class PlatformNotReady(HomeAssistantError):
"""Error to indicate that platform is not ready."""
pass
class InvalidStateError(HomeAssistantError):
"""When an invalid state is encountered."""
pass

View File

@ -12,7 +12,8 @@ import pytz
import pytest
import homeassistant.core as ha
from homeassistant.exceptions import InvalidEntityFormatError
from homeassistant.exceptions import (InvalidEntityFormatError,
InvalidStateError)
from homeassistant.util.async import run_coroutine_threadsafe
import homeassistant.util.dt as dt_util
from homeassistant.util.unit_system import (METRIC_SYSTEM)
@ -421,6 +422,10 @@ class TestState(unittest.TestCase):
InvalidEntityFormatError, ha.State,
'invalid_entity_format', 'test_state')
self.assertRaises(
InvalidStateError, ha.State,
'domain.long_state', 't' * 256)
def test_domain(self):
"""Test domain."""
state = ha.State('some_domain.hello', 'world')