Bluetooth-Devices / dbus-fast

A faster version of dbus-next
MIT License
35 stars 8 forks source link

Service crash when handling messages with OR-ed message flags #239

Closed miccoli closed 12 months ago

miccoli commented 1 year ago

Bug Description

Line 707 below https://github.com/Bluetooth-Devices/dbus-fast/blob/91ad8200691094dd76b29e51dd0c20bde066d3af/src/dbus_fast/_private/unmarshaller.py#L705-L711 assumes that self._flag has only a single bit set, but this is not necessarily the case.

To Reproduce When sending

busctl --user call --expect-reply=no --allow-interactive-authorization=yes test.name /test/path test.interface Echo s Hi

the below code

import asyncio

from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, method

class ExampleInterface(ServiceInterface):
    def __init__(self, name):
        super().__init__(name)

    @method()
    def Echo(self, what: "s") -> "s":  # noqa: F821
        return what

async def main():
    bus = await MessageBus().connect()
    interface = ExampleInterface("test.interface")
    bus.export("/test/path", interface)
    await bus.request_name("test.name")
    await bus.wait_for_disconnect()

asyncio.run(main())

fails with

Traceback (most recent call last):
  File "/home/miccoli/bug/dbus-fast/service.py", line 23, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/miccoli/bug/dbus-fast/service.py", line 20, in main
    await bus.wait_for_disconnect()
  File "/home/miccoli/venv/dev/lib/python3.11/site-packages/dbus_fast/aio/message_bus.py", line 429, in wait_for_disconnect
    return await self._disconnect_future
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "src/dbus_fast/aio/message_reader.py", line 22, in dbus_fast.aio.message_reader.build_message_reader._message_reader
  File "src/dbus_fast/_private/unmarshaller.py", line 740, in dbus_fast._private.unmarshaller.Unmarshaller._unmarshall
  File "src/dbus_fast/_private/unmarshaller.py", line 707, in dbus_fast._private.unmarshaller.Unmarshaller._read_body
KeyError: 5

Additional context

For busctl the default value of --allow-interactive-authorization is yes, so sending

busctl --user call --expect-reply=no test.name /test/path test.interface Echo s Hi

causes the service to crash.