diff --git a/hassio/utils/gdbus.py b/hassio/utils/gdbus.py index bd064d75e..44296fe7f 100644 --- a/hassio/utils/gdbus.py +++ b/hassio/utils/gdbus.py @@ -24,13 +24,13 @@ RE_GVARIANT_TYPE: re.Match = re.compile( r"(?:boolean|byte|int16|uint16|int32|uint32|handle|int64|uint64|double|" r"string|objectpath|signature) " ) -RE_GVARIANT_VARIANT: re.Match = re.compile( - r"(?<=(?: |{|\[))<((?:'|\").*?(?:'|\")|\d+(?:\.\d+)?)>(?=(?:|]|}|,))" -) +RE_GVARIANT_VARIANT: re.Match = re.compile(r"\"[^\"\\]*(?:\\.[^\"\\]*)*\"|(<|>)") RE_GVARIANT_STRING_ESC: re.Match = re.compile( - r"(?<=(?: |{|\[|\())'[^']*?\"[^']*?'(?=(?:|]|}|,|\)))" + r"(?<=(?: |{|\[|\(|<))'[^']*?\"[^']*?'(?=(?:|]|}|,|\)|>))" +) +RE_GVARIANT_STRING: re.Match = re.compile( + r"(?<=(?: |{|\[|\(|<))'(.*?)'(?=(?:|]|}|,|\)|>))" ) -RE_GVARIANT_STRING: re.Match = re.compile(r"(?<=(?: |{|\[|\())'(.*?)'(?=(?:|]|}|,|\)))") RE_GVARIANT_TUPLE_O: re.Match = re.compile(r"\"[^\"\\]*(?:\\.[^\"\\]*)*\"|(\()") RE_GVARIANT_TUPLE_C: re.Match = re.compile(r"\"[^\"\\]*(?:\\.[^\"\\]*)*\"|(,?\))") @@ -110,11 +110,13 @@ class DBus: def parse_gvariant(raw: str) -> Any: """Parse GVariant input to python.""" json_raw: str = RE_GVARIANT_TYPE.sub("", raw) - json_raw = RE_GVARIANT_VARIANT.sub(r"\1", json_raw) json_raw = RE_GVARIANT_STRING_ESC.sub( lambda x: x.group(0).replace('"', '\\"'), json_raw ) json_raw = RE_GVARIANT_STRING.sub(r'"\1"', json_raw) + json_raw = RE_GVARIANT_VARIANT.sub( + lambda x: x.group(0) if not x.group(1) else "", json_raw + ) json_raw = RE_GVARIANT_TUPLE_O.sub( lambda x: x.group(0) if not x.group(1) else "[", json_raw ) diff --git a/tests/utils/test_gvariant_parser.py b/tests/utils/test_gvariant_parser.py index 62f0df60c..a993f9abf 100644 --- a/tests/utils/test_gvariant_parser.py +++ b/tests/utils/test_gvariant_parser.py @@ -276,3 +276,27 @@ def test_systemd_unitlist_complex(): ], ] ] + + +def test_networkmanager_dns_properties(): + """Test NetworkManager DNS properties.""" + raw = "({'Mode': <'default'>, 'RcManager': <'file'>, 'Configuration': <[{'nameservers': <['192.168.23.30']>, 'domains': <['syshack.local']>, 'interface': <'eth0'>, 'priority': <100>, 'vpn': }]>},)" + + # parse data + data = DBus.parse_gvariant(raw) + + assert data == [ + { + "Mode": "default", + "RcManager": "file", + "Configuration": [ + { + "nameservers": ["192.168.23.30"], + "domains": ["syshack.local"], + "interface": "eth0", + "priority": 100, + "vpn": False, + } + ], + } + ]