Forbid float NaN in JSON (#18757)

This commit is contained in:
Paulus Schoutsen 2018-11-28 13:25:23 +01:00 committed by Pascal Vizeli
parent 5c3a4e3d10
commit a2386f871d
4 changed files with 28 additions and 7 deletions

View File

@ -45,8 +45,9 @@ class HomeAssistantView:
"""Return a JSON response."""
try:
msg = json.dumps(
result, sort_keys=True, cls=JSONEncoder).encode('UTF-8')
except TypeError as err:
result, sort_keys=True, cls=JSONEncoder, allow_nan=False
).encode('UTF-8')
except (ValueError, TypeError) as err:
_LOGGER.error('Unable to serialize to JSON: %s\n%s', err, result)
raise HTTPInternalServerError
response = web.Response(

View File

@ -13,11 +13,12 @@ from homeassistant.core import callback
from homeassistant.components.http import HomeAssistantView
from homeassistant.helpers.json import JSONEncoder
from .const import MAX_PENDING_MSG, CANCELLATION_ERRORS, URL
from .const import MAX_PENDING_MSG, CANCELLATION_ERRORS, URL, ERR_UNKNOWN_ERROR
from .auth import AuthPhase, auth_required_message
from .error import Disconnect
from .messages import error_message
JSON_DUMP = partial(json.dumps, cls=JSONEncoder)
JSON_DUMP = partial(json.dumps, cls=JSONEncoder, allow_nan=False)
class WebsocketAPIView(HomeAssistantView):
@ -58,9 +59,12 @@ class WebSocketHandler:
self._logger.debug("Sending %s", message)
try:
await self.wsock.send_json(message, dumps=JSON_DUMP)
except TypeError as err:
except (ValueError, TypeError) as err:
self._logger.error('Unable to serialize to JSON: %s\n%s',
err, message)
await self.wsock.send_json(error_message(
message['id'], ERR_UNKNOWN_ERROR,
'Invalid JSON in response'))
@callback
def _send_message(self, message):

View File

@ -10,6 +10,6 @@ async def test_invalid_json(caplog):
view = HomeAssistantView()
with pytest.raises(HTTPInternalServerError):
view.json(object)
view.json(float("NaN"))
assert str(object) in caplog.text
assert str(float("NaN")) in caplog.text

View File

@ -300,3 +300,19 @@ async def test_states_filters_visible(hass, hass_admin_user, websocket_client):
assert len(msg['result']) == 1
assert msg['result'][0]['entity_id'] == 'test.entity'
async def test_get_states_not_allows_nan(hass, websocket_client):
"""Test get_states command not allows NaN floats."""
hass.states.async_set('greeting.hello', 'world', {
'hello': float("NaN")
})
await websocket_client.send_json({
'id': 5,
'type': commands.TYPE_GET_STATES,
})
msg = await websocket_client.receive_json()
assert not msg['success']
assert msg['error']['code'] == const.ERR_UNKNOWN_ERROR