Mqtt fix issue with displaying non UTF-8 payload (#67471)

* Mqtt fix issue with displaying non UTF-8 payload

* None or binary

* Casting and additional test

* casting
This commit is contained in:
Jan Bouwhuis 2022-03-02 17:01:47 +01:00 committed by GitHub
parent 9f51fd7c6f
commit a97fe7aae0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 2 deletions

View file

@ -1206,20 +1206,29 @@ async def websocket_subscribe(hass, connection, msg):
async def forward_messages(mqttmsg: ReceiveMessage):
"""Forward events to websocket."""
try:
payload = cast(bytes, mqttmsg.payload).decode(
DEFAULT_ENCODING
) # not str because encoding is set to None
except (AttributeError, UnicodeDecodeError):
# Convert non UTF-8 payload to a string presentation
payload = str(mqttmsg.payload)
connection.send_message(
websocket_api.event_message(
msg["id"],
{
"topic": mqttmsg.topic,
"payload": mqttmsg.payload,
"payload": payload,
"qos": mqttmsg.qos,
"retain": mqttmsg.retain,
},
)
)
# Perform UTF-8 decoding directly in callback routine
connection.subscriptions[msg["id"]] = await async_subscribe(
hass, msg["topic"], forward_messages
hass, msg["topic"], forward_messages, encoding=None
)
connection.send_message(websocket_api.result_message(msg["id"]))

View file

@ -1647,6 +1647,7 @@ async def test_mqtt_ws_subscription(hass, hass_ws_client, mqtt_mock):
async_fire_mqtt_message(hass, "test-topic", "test1")
async_fire_mqtt_message(hass, "test-topic", "test2")
async_fire_mqtt_message(hass, "test-topic", b"\xDE\xAD\xBE\xEF")
response = await client.receive_json()
assert response["event"]["topic"] == "test-topic"
@ -1656,6 +1657,10 @@ async def test_mqtt_ws_subscription(hass, hass_ws_client, mqtt_mock):
assert response["event"]["topic"] == "test-topic"
assert response["event"]["payload"] == "test2"
response = await client.receive_json()
assert response["event"]["topic"] == "test-topic"
assert response["event"]["payload"] == "b'\\xde\\xad\\xbe\\xef'"
# Unsubscribe
await client.send_json({"id": 8, "type": "unsubscribe_events", "subscription": 5})
response = await client.receive_json()