Validating Message Parameters

Lawrence D'Oliveiro ldo at geek-central.gen.nz
Sun Aug 20 22:22:02 UTC 2017


In libdbus, when you call one of the dbus_message_new_xxx methods and
pass something invalid for the destination, path, interface or
method/member arguments, all you get back is a result of false, with no
indication of what you did wrong. It is up to you to make prior calls
as necessary to dbus_validate_{bus_name,path,interface,member} to
ensure that all these strings have the valid form.

My Python wrappers for these validation calls in DBussy
<https://github.com/ldo/dbussy>, as with all the wrappers for calls that
take a DBusError argument, let you omit the corresponding Python Error
object. If you do this, they will create a temporary one internally, and
automatically raise an exception if it gets filled in with an error
indication. Luckily, this gives you a much better description of what
you did wrong:

    ldo at theon:dbussy> python3 -ic "import dbussy as dbus"
    >>> dbus.validate_bus_name("nosuch")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/ldo/projects/dbussy/dbussy.py", line 5259, in validate_bus_name
        my_error.raise_if_set()
      File "/home/ldo/projects/dbussy/dbussy.py", line 4474, in raise_if_set
        raise DBusError(self.name, self.message)
    dbussy.DBusError: org.freedesktop.DBus.Error.InvalidArgs -- Bus name was not valid: 'nosuch'
    >>> dbus.validate_path("nosuch")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/ldo/projects/dbussy/dbussy.py", line 5172, in validate_path
        my_error.raise_if_set()
      File "/home/ldo/projects/dbussy/dbussy.py", line 4474, in raise_if_set
        raise DBusError(self.name, self.message)
    dbussy.DBusError: org.freedesktop.DBus.Error.InvalidArgs -- Object path was not valid: 'nosuch'
    >>> dbus.validate_interface("nosuch")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/ldo/projects/dbussy/dbussy.py", line 5214, in validate_interface
        my_error.raise_if_set()
      File "/home/ldo/projects/dbussy/dbussy.py", line 4474, in raise_if_set
        raise DBusError(self.name, self.message)
    dbussy.DBusError: org.freedesktop.DBus.Error.InvalidArgs -- Interface name was not valid: 'nosuch'
    >>> dbus.validate_member("no.such")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/ldo/projects/dbussy/dbussy.py", line 5229, in validate_member
        my_error.raise_if_set()
      File "/home/ldo/projects/dbussy/dbussy.py", line 4474, in raise_if_set
        raise DBusError(self.name, self.message)
    dbussy.DBusError: org.freedesktop.DBus.Error.InvalidArgs -- Member name was not valid: 'no.such'

This makes it easy to put in validation of user-supplied input. For
example <https://github.com/ldo/dbussy_examples> in the “call” script,
after extracting the command-line arguments for targeting the message:

    which_bus, destination, object_path, interface_name, method_name = args[:5]
    args = args[5:]
    dbus.validate_bus_name(destination)
    dbus.validate_path(object_path)
    dbus.validate_interface(interface_name)
    dbus.validate_member(method_name)

I also added inline versions of the validation calls (called
“valid_xxx” rather than “validate_xxx”), that return the argument being
validated on success. These allow you to insert the validation directly
into the Message creation call, as in the “introspect” example script:

    message = dbus.Message.new_method_call \
      (
        destination = dbus.valid_bus_name(sys.argv[2]),
        path = dbus.valid_path(sys.argv[3]),
        iface = DBUS.INTERFACE_INTROSPECTABLE,
        method = "Introspect"
      )


More information about the dbus mailing list