From f24cb6dc66b4750cd9bf49d451d7d34fc0f97998 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 24 Aug 2018 14:03:17 +1000 Subject: [PATCH] ratbagd: always return an empty list for array-like properties [] In some cases we get Piper trying to use None as a list, see https://github.com/libratbag/piper/issues/237 This can be reproduced by returning an error (e.g. -ENOMEM) from ratbagd_get_devices(). That error isn't handled anywhere on the client side, the effective result is that the property is None when calling proxy.get_cached_property(). The error is visible on the bus: method call time=1535084121.223284 sender=:1.1311 -> destination=:1.1310 serial=7 path=/org/freedesktop/ratbag1; interface=org.freedesktop.DBus.Properties; member=GetAll string "org.freedesktop.ratbag1.Manager" error time=1535084121.223433 sender=:1.1310 -> destination=:1.1311 error_name=org.freedesktop.DBus.Error.NoMemory reply_serial=7 string "Cannot allocate memory" Make ratbagd.py more robust here and always return an empty list for those properties where we expect an array. This papers over the real bug which is that a) we need better logging in ratbagd on errors and b) something on the other side needs to handle this error. Signed-off-by: Peter Hutterer --- tools/ratbagd.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/ratbagd.py b/tools/ratbagd.py index 611e3aeb..528290bb 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -253,7 +253,7 @@ class Ratbagd(_RatbagdDBus): def __init__(self): _RatbagdDBus.__init__(self, "Manager", None) - result = self._get_dbus_property("Devices") + result = self._get_dbus_property("Devices") or [] self._devices = [RatbagdDevice(objpath) for objpath in result] def _on_properties_changed(self, proxy, changed_props, invalidated_props): @@ -286,7 +286,7 @@ class Ratbagd(_RatbagdDBus): def themes(self): """A list of theme names. The theme 'default' is guaranteed to be available.""" - return self._get_dbus_property("Themes") + return self._get_dbus_property("Themes") or [] def __enter__(self): return self @@ -321,7 +321,7 @@ class RatbagdDevice(_RatbagdDBus): # FIXME: if we start adding and removing objects from this list, # things will break! - result = self._get_dbus_property("Profiles") + result = self._get_dbus_property("Profiles") or [] self._profiles = [RatbagdProfile(objpath) for objpath in result] for profile in self._profiles: profile.connect("notify::is-active", self._on_active_profile_changed) @@ -343,7 +343,7 @@ class RatbagdDevice(_RatbagdDBus): if RatbagdDevice.CAP_SWITCHABLE_RESOLUTION is in device.capabilities: do something """ - return self._get_dbus_property("Capabilities") + return self._get_dbus_property("Capabilities") or [] @GObject.Property def name(self): @@ -448,7 +448,7 @@ class RatbagdProfile(_RatbagdDBus): if RatbagdProfile.CAP_WRITABLE_NAME is in profile.capabilities: do something """ - return self._get_dbus_property("Capabilities") + return self._get_dbus_property("Capabilities") or [] @GObject.Property def name(self): @@ -565,7 +565,7 @@ class RatbagdResolution(_RatbagdDBus): if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION is in resolution.capabilities: do something """ - return self._get_dbus_property("Capabilities") + return self._get_dbus_property("Capabilities") or [] @GObject.Property def resolution(self): @@ -596,12 +596,12 @@ class RatbagdResolution(_RatbagdDBus): @GObject.Property def resolutions(self): """The list of supported DPI values""" - return self._get_dbus_property("Resolutions") + return self._get_dbus_property("Resolutions") or [] @GObject.Property def report_rates(self): """The list of supported report rates""" - return self._get_dbus_property("ReportRates") + return self._get_dbus_property("ReportRates") or [] @GObject.Property def is_active(self):