blueman-project / blueman

Blueman is a GTK+ Bluetooth Manager
GNU General Public License v3.0
1.27k stars 192 forks source link

Gtk-WARNING when device name contains "markup" #2429

Closed XeCycle closed 3 months ago

XeCycle commented 3 months ago

blueman: 2.4.2 BlueZ: 5.77 Distribution: Arch Linux Desktop environment: awesome wm, notification daemon dunst

My headset, Creative Zen Hybrid Pro, reports a weird name. As an example this reporter says their device name is "ZenHybridPro (SX:A0l9g7[m[`)"; mine is "ZenHybridPro (SX:p<>v......)". (I'm not sure whether this name can be linked to MAC or whatever, allow me to mask part of it). And blueman-applet frequently logs

(blueman-tray:15759): Gtk-WARNING **: 10:44:17.326: Failed to set text '音频和输入配置文件 on ZenHybridPro (SX:p<>v......)' from markup due to error parsing markup: Error on line 1 char 59: “>” is not a valid character following a “<” character; it may not begin an element name

The Chinese part means "audio and input profile". This is shown 3 times at applet startup, and also several times when device connects. I tried --loglevel debug but no relevant logs for this one.

infirit commented 3 months ago

Ugh, looks like we can't trust the name we get from BlueZ. I suspect the error is from here. https://github.com/blueman-project/blueman/blob/42110d9c305868f853a455ecdb821a120d560fb9/blueman/main/indicators/StatusNotifierItem.py#L75

We probably need to escape here https://github.com/blueman-project/blueman/blob/42110d9c305868f853a455ecdb821a120d560fb9/blueman/plugins/applet/RecentConns.py#L171

infirit commented 3 months ago

Can you try below debugging (and possible fix) patch. It logs the the device name (alias) to the applet log so there may be something interesting in blueman-applet --loglevel debug.

diff --git a/blueman/plugins/applet/RecentConns.py b/blueman/plugins/applet/RecentConns.py
index 84ec37a07..28e825da5 100644
--- a/blueman/plugins/applet/RecentConns.py
+++ b/blueman/plugins/applet/RecentConns.py
@@ -1,5 +1,6 @@
 from gettext import gettext as _
 from operator import itemgetter
+import html
 import time
 import logging
 from typing import List, TYPE_CHECKING, Optional, Callable, cast, Union
@@ -167,8 +168,10 @@ class RecentConns(AppletPlugin, PowerStateListener):
         self.parent.Plugins.DBusService.connect_service(item["device"], item["uuid"], reply, err)

     def _build_menu_item(self, item: "Item") -> "SubmenuItemDict":
+        logging.debug(f"{item['name']} - {item['alias']}")
+        alias = html.escape(item["alias"])
         mitem: "SubmenuItemDict" = {
-            "text": _("%(service)s on %(device)s") % {"service": item["name"], "device": item["alias"]},
+            "text": _("%(service)s on %(device)s") % {"service": item["name"], "device": alias},
             "markup": True,
             "icon_name": item["mitem"]["icon_name"] if item["mitem"] is not None else item["icon"],
             "sensitive": item["device"] is not None,
XeCycle commented 3 months ago

@infirit Yes that fixes it!