Fix prometheus component to fully sanitize Unicode characters (#31037)

* Fix prometheus component to fully santize Unicode characters.

Sanitization used isdigit() to match numerics but that also matches 
Unicode "digit" characters that require special handling, like 
superscripts. Failures would look like this:

ValueError: Invalid metric name: sensor_unit_u0x23_per_m³

Changed sanitize to use string.digits, which matches only ascii digits, 
and added test.

See 
https://stackoverflow.com/questions/44891070/whats-the-difference-between-str-isdigit-isnumeric-and-isdecimal-in-python 
for discussion.

https://docs.python.org/3/library/stdtypes.html#str.isdigit

https://docs.python.org/3.7/library/string.html#string.digits

* fix formatting to comply with black
This commit is contained in:
Joe Gross 2020-01-21 16:03:42 -08:00 committed by Martin Hjelmare
parent ff7d2ac681
commit 3b4c3e6e17
2 changed files with 17 additions and 1 deletions

View file

@ -168,7 +168,10 @@ class PrometheusMetrics:
return "".join(
[
c
if c in string.ascii_letters or c.isdigit() or c == "_" or c == ":"
if c in string.ascii_letters
or c in string.digits
or c == "_"
or c == ":"
else f"u{hex(ord(c))}"
for c in metric
]

View file

@ -46,6 +46,13 @@ async def prometheus_client(loop, hass, hass_client):
sensor4.entity_id = "sensor.wind_direction"
await sensor4.async_update_ha_state()
sensor5 = DemoSensor(
None, "SPS30 PM <1µm Weight concentration", 3.7069, None, "µg/m³", None
)
sensor5.hass = hass
sensor5.entity_id = "sensor.sps30_pm_1um_weight_concentration"
await sensor5.async_update_ha_state()
return await hass_client()
@ -113,3 +120,9 @@ async def test_view(prometheus_client): # pylint: disable=redefined-outer-name
'entity="sensor.wind_direction",'
'friendly_name="Wind Direction"} 25.0' in body
)
assert (
'sensor_unit_u0xb5g_per_mu0xb3{domain="sensor",'
'entity="sensor.sps30_pm_1um_weight_concentration",'
'friendly_name="SPS30 PM <1µm Weight concentration"} 3.7069' in body
)