Skip to content

Commit

Permalink
state/SSID: handle non-ascii SSIDs
Browse files Browse the repository at this point in the history
This workaround is intended to properly decode non-ascii SSIDs returned
by networkctl.

In such a case, a sequence of bytes (in octal notation) will be returned
and we were displaying this string in netplan status.
  • Loading branch information
daniloegea committed Sep 25, 2024
1 parent ad3757f commit 0a57af5
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
7 changes: 7 additions & 0 deletions netplan_cli/cli/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,18 @@ def ssid(self) -> str:
if self.type == 'wifi':
# XXX: available from networkctl's JSON output as of v250:
# https://github.com/systemd/systemd/commit/da7c995
# TODO: Retrieving the SSID from systemd seems to not be reliable.
# Sometimes it will return "(null)".
for line in self._networkctl.splitlines():
line = line.strip()
key = r'^Wi-?Fi access point: (.*) \(.*\)'
if match := re.match(key, line):
ssid = match.group(1)
# TODO: Find a better way to retrieve the SSID
# networkctl will return a non-ascii SSID using the octal notation below:
# '\\303\\241\\303\\251\\303\\255\\303\\263\\303...
# Here we handle the escaping, the encoding of individual bytes and the final decoding to utf-8
ssid = ssid.encode('latin1').decode('unicode-escape').encode('latin1').decode('utf-8')
return ssid if ssid else None
return None

Expand Down
11 changes: 6 additions & 5 deletions tests/cli/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,22 +440,23 @@ def test_json_nm_wlan0_2(self, networkctl_mock, nm_ssid_mock):

@patch('netplan_cli.cli.state.Interface.query_nm_ssid')
@patch('netplan_cli.cli.state.Interface.query_networkctl')
def test_json_nm_wlan1(self, networkctl_mock, nm_ssid_mock):
SSID = 'áéíóúççção€€€'
nm_ssid_mock.return_value = SSID
def test_json_nm_wlan1_non_ascii(self, networkctl_mock, nm_ssid_mock):
ND_SSID = '\\303\\241\\303\\251\\303\\255\\303\\263\\303\\272\\302\\242\\302\\242\\302\\242\\302\\243\\302\\243\\302\\243'
NM_SSID = 'áéíóú¢¢¢£££'
nm_ssid_mock.return_value = NM_SSID
# networkctl mock output reduced to relevant lines
# Newer versions of systemd changed WiFi to Wi-Fi
# See systemd commit 8fff78a1dded105e1ee87bc66e29ef2fd61bf8c9
networkctl_mock.return_value = \
'Wi-Fi access point: {} (b4:fb:e4:75:c6:21)'.format(SSID)
'Wi-Fi access point: {} (b4:fb:e4:75:c6:21)'.format(ND_SSID)

data = {'ifname': 'wlan1', 'ifindex': 123}
nd = [{'Index': 123, 'Type': 'wlan', 'Name': 'wlan1'}]
nm = SystemConfigState.process_nm(NMCLI)

itf = Interface(data, nd, nm, (None, None), (None, None))
_, json = itf.json()
self.assertEqual(json.get('ssid'), SSID)
self.assertEqual(json.get('ssid'), NM_SSID)

@patch('netplan_cli.cli.state.Interface.query_networkctl')
def test_json_nd_enp0s31f6(self, networkctl_mock):
Expand Down

0 comments on commit 0a57af5

Please sign in to comment.