diff --git a/frontend/ui/network/manager.lua b/frontend/ui/network/manager.lua index 1503ba651..e8de416d1 100644 --- a/frontend/ui/network/manager.lua +++ b/frontend/ui/network/manager.lua @@ -943,7 +943,7 @@ function NetworkMgr:reconnectOrShowNetworkMenu(complete_callback, interactive) end UIManager:show(InfoMessage:new{ tag = "NetworkMgr", -- for crazy KOSync purposes - text = T(_("Connected to network %1"), BD.wrap(ssid)), + text = T(_("Connected to network %1"), BD.wrap(self.decodeSSID(ssid))), timeout = 3, }) else @@ -995,6 +995,23 @@ function NetworkMgr:setWirelessBackend(name, options) require("ui/network/"..name).init(self, options) end +function NetworkMgr.decodeSSID(text) + local decode = function(b) + local c = string.char(tonumber(b, 16)) + -- This is a hack that allows us to make sure that any decoded backslash + -- does not get replaced in the step that replaces double backslashes. + if c == "\\" then + return "\\\\" + else + return c + end + end + + local decoded = text:gsub("%f[\\]\\x(%x%x)", decode) + decoded = decoded:gsub("\\\\", "\\") + return util.fixUtf8(decoded, "�") +end + -- set network proxy if global variable G_defaults:readSetting("NETWORK_PROXY") is defined if G_defaults:readSetting("NETWORK_PROXY") then NetworkMgr:setHTTPProxy(G_defaults:readSetting("NETWORK_PROXY")) diff --git a/frontend/ui/widget/networksetting.lua b/frontend/ui/widget/networksetting.lua index efb06c94e..5e7890f3c 100644 --- a/frontend/ui/widget/networksetting.lua +++ b/frontend/ui/widget/networksetting.lua @@ -106,6 +106,7 @@ local NetworkItem = InputContainer:extend{ icon_size = Screen:scaleBySize(32), width = nil, info = nil, + decoded_ssid = nil, background = Blitbuffer.COLOR_WHITE, } @@ -114,6 +115,7 @@ function NetworkItem:init() if not self.info.ssid then self.info.ssid = "[hidden]" end + self.decoded_ssid = NetworkMgr.decodeSSID(self.info.ssid) local wifi_icon if string.find(self.info.flags, "WPA") then @@ -149,7 +151,7 @@ function NetworkItem:init() }, horizontal_space, TextWidget:new{ - text = self.info.ssid, + text = self.decoded_ssid, face = Font:getFace("cfont"), }, }, @@ -283,7 +285,7 @@ end function NetworkItem:onEditNetwork() local password_input password_input = InputDialog:new{ - title = self.info.ssid, + title = self.decoded_ssid, input = self.info.password, input_hint = _("password (leave empty for open networks)"), input_type = "text", @@ -326,7 +328,7 @@ end function NetworkItem:onAddNetwork() local password_input password_input = InputDialog:new{ - title = self.info.ssid, + title = self.decoded_ssid, input = "", input_hint = _("password (leave empty for open networks)"), input_type = "text", @@ -488,7 +490,7 @@ function NetworkSetting:init() UIManager:close(self, "ui", self.dimen) end UIManager:show(InfoMessage:new{ - text = T(_("Connected to network %1"), BD.wrap(connected_item.info.ssid)), + text = T(_("Connected to network %1"), BD.wrap(connected_item.decoded_ssid)), timeout = 3, }) if self.connect_callback then diff --git a/spec/unit/network_manager_spec.lua b/spec/unit/network_manager_spec.lua index e0e795dd7..91be3d358 100644 --- a/spec/unit/network_manager_spec.lua +++ b/spec/unit/network_manager_spec.lua @@ -73,6 +73,30 @@ describe("network_manager module", function() assert.is.same(release_ip_called, 0) end) + describe("decodeSSID()", function() + local NetworkMgr = require("ui/network/manager") + + it("should correctly unescape emoji", function() + assert.is_equal("📚", NetworkMgr.decodeSSID("\\xf0\\x9f\\x93\\x9a")) + end) + + it("should correctly unescape multiple characters", function() + assert.is_equal("神舟五号", NetworkMgr.decodeSSID("\\xe7\\xa5\\x9e\\xe8\\x88\\x9f\\xe4\\xba\\x94\\xe5\\x8f\\xb7")) + end) + + it("should ignore escaped backslashes", function() + assert.is_equal("\\x61", NetworkMgr.decodeSSID("\\\\x61")) + end) + + it("should not remove encoded backslashes", function() + assert.is_equal("\\\\", NetworkMgr.decodeSSID("\\x5c\\")) + end) + + it("should deal with invalid UTF-8 (relatively) gracefully", function() + assert.is_equal("��", NetworkMgr.decodeSSID("\\xe2\\x82")) + end) + end) + teardown(function() function Device:initNetworkManager() end function Device:hasWifiRestore() return false end