Skip to content

Fix empty array serialization and silent error swallowing#10

Merged
jmacato merged 1 commit into
mainfrom
fix/empty-array-and-error-handling
Apr 2, 2026
Merged

Fix empty array serialization and silent error swallowing#10
jmacato merged 1 commit into
mainfrom
fix/empty-array-and-error-handling

Conversation

@jmacato
Copy link
Copy Markdown
Member

@jmacato jmacato commented Apr 2, 2026

Empty arrays of struct types (e.g. List<AtSpiObjectReference> with 0 items) caused signature inference failures during native marshaling. The server would throw during reply serialization, the error was silently swallowed, and the client would hang forever waiting for a reply that was never sent.

Root cause: AppendArray re-inferred the D-Bus signature from the value even when the message already had a known signature set via SetBodyWithSignature. For empty arrays of IDBusStructConvertible, there is no element to peek at, so inference throws.

Fixes:

  • Add CreateReplyWithSignature/CreateSignalWithSignature to DBusMessage
  • Add explicit-signature constructor to DBusVariant
  • Source generator emits compile-time-known signatures for method replies, property getters, and GetAllProperties
  • AppendBody uses the message's known signature to drive serialization, bypassing inference for arrays/dicts
  • HandleMessage in LibDBusWireWorker now fails pending TCS on deserialization errors instead of silently dropping them
  • NormalizePath failure now sends an error reply instead of silently returning
  • All diagnostics-only error paths now fall back to stderr when diagnostics is null, ensuring errors are never completely invisible

…ndling

Empty arrays of struct types (e.g. List<AtSpiObjectReference> with 0 items)
caused signature inference failures during native marshaling. The server would
throw during reply serialization, the error was silently swallowed, and the
client would hang forever waiting for a reply that was never sent.

Root cause: AppendArray re-inferred the D-Bus signature from the value even
when the message already had a known signature set via SetBodyWithSignature.
For empty arrays of IDBusStructConvertible, there is no element to peek at,
so inference throws.

Fixes:
- Add CreateReplyWithSignature/CreateSignalWithSignature to DBusMessage
- Add explicit-signature constructor to DBusVariant
- Source generator emits compile-time-known signatures for method replies,
  property getters, and GetAllProperties
- AppendBody uses the message's known signature to drive serialization,
  bypassing inference for arrays/dicts
- HandleMessage in LibDBusWireWorker now fails pending TCS on deserialization
  errors instead of silently dropping them
- NormalizePath failure now sends an error reply instead of silently returning
- All diagnostics-only error paths now fall back to stderr when diagnostics
  is null, ensuring errors are never completely invisible
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes critical issues with empty array serialization and silent error handling in the D-Bus marshaling layer. The root cause was that empty arrays of struct types couldn't be inferred during serialization, causing the server to crash during reply serialization with the error being silently swallowed, leaving clients hanging indefinitely.

Changes:

  • Added explicit-signature versions of reply and signal creation methods to DBusMessage to bypass inference
  • Extended DBusVariant with an explicit-signature constructor for property values
  • Refactored serialization in LibDBusMessageMarshaler to use known signatures when available
  • Enhanced error handling to fail pending TCS on deserialization errors and ensure all errors have visible logging
  • Updated the source generator to emit compile-time-known D-Bus signatures for method replies, property getters, and GetAllProperties

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Avalonia.DBus/DBusMessage.cs Added CreateReplyWithSignature and CreateSignalWithSignature methods to enable explicit signature specification
src/Avalonia.DBus/DBusVariant.cs Added explicit-signature constructor to support compile-time-known signatures for property values
src/Avalonia.DBus/LibDBusMessageMarshaler.cs Refactored AppendBody to use known signatures; added AppendValueWithSignature, AppendArrayWithSignature, and AppendDictWithSignature methods
src/Avalonia.DBus/LibDBusWireWorker.cs Enhanced error handling to fail pending TCS on deserialization errors; added fallback stderr logging via new LogOrTrace method
src/Avalonia.DBus/DBusConnection.Worker.cs Added error replies for NormalizePath failures; enhanced error logging with stderr fallback
src/Avalonia.DBus.SourceGen/DBusSourceGenerator.Handler.cs Updated handler generation to emit compile-time-known signatures for method replies and property values

Now let me verify that there are no issues I might have missed by doing a final check on the logic. Looking at the code one more time to ensure correctness:

  1. ✓ The message's known signature is correctly used to drive serialization
  2. ✓ Error handling properly fails pending TCS on deserialization errors
  3. ✓ Stderr logging is used as fallback when diagnostics is null
  4. ✓ The source generator correctly computes and formats signatures
  5. ✓ The new API methods follow existing conventions

Everything looks good!


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jmacato jmacato merged commit 864a052 into main Apr 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants