Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"expected the value signature" error somehow ignored with DeserializeDict, causing confusing "Unexpected non-0 padding byte" error #856

Open
ids1024 opened this issue Jun 21, 2024 · 5 comments

Comments

@ids1024
Copy link
Contributor

ids1024 commented Jun 21, 2024

I was getting a weird "Unexpected non-0 padding byte" error. It seems another parse error somehow occurred earlier but was ignored, and it tried to continue parsing, naturally not finding the bytes it expected...

After some debugging, here's a minimal test case:

use std::future::pending;
use zbus::{connection, interface, zvariant};

#[derive(Debug, zvariant::DeserializeDict, zvariant::Type)]
#[zvariant(signature = "a{sv}")]
pub struct Props {
    foo: String,
}

struct Test;

#[interface(name = "com.ids1024.test")]
impl Test {
    fn test(&mut self, props: Props) {
        dbg!(props);
    }
}

#[tokio::main]
async fn main() -> zbus::Result<()> {
    let _conn = connection::Builder::session()?
        .name("com.ids1024.test")?
        .serve_at("/com/ids1024/test", Test)?
        .build()
        .await?;

    pending::<()>().await;

    Ok(())
}

If this is invoked in d-feet with {"foo": GLib.Variant("u", 42)}, it produces:

('g-io-error-quark: GDBus.Error:org.freedesktop.zbus.Error: Unexpected non-0 '
 'padding byte `42` (36)')

This is a rather confusing error. Is something not aligned properly? But in reality, an error occured earlier in:

let value_de = ValueDeserializer::new(self);
visitor.visit_seq(value_de)

If this is changed to Ok(visitor.visit_seq(value_de).unwrap()), it outputs:

called `Result::unwrap()` on an `Err` value: Message("invalid value: string \"u\", expected the value signature")

So given the code and the message it was trying to parse, that makes sense. But why was that error not propagated properly, and it instead tried to continue parsing? I guess the error isn't being handled properly somewhere up the stack...

@ids1024
Copy link
Contributor Author

ids1024 commented Jun 21, 2024

Ah, so ignoring the error is part of the derive macro, and is intentional. Which makes a lot of sense... although it doesn't work for this particular error.

// FIXME: add an option about strict parsing (instead of silently skipping the field)
#name = access.next_value::<#zv::DeserializeValue<_>>().map(|v| v.0).ok();

Ignoring a parse error won't work properly if it means the bytes have not been consumed, and will be interpreted as something else. Not sure if there's a simple way to address this with how things currently work.

ids1024 added a commit to pop-os/cosmic-applets that referenced this issue Jun 23, 2024
If this has the wrong type, it causes a parse error due to
dbus2/zbus#856.

This fixes the status icon for Slack, and probably other applications.
Not sure how this field is defined in general, but with Slack it is
an `aas`.

`gnome-shell-extension-appindicator` doesn't seem to use the `shortcut`
field either.
@zeenix
Copy link
Contributor

zeenix commented Jun 23, 2024

Ah, so ignoring the error is part of the derive macro, and is intentional. Which makes a lot of sense... although it doesn't work for this particular error.

I am not sure if it makes sense actually. Seems like an oversight to me (unless @elmarco happen to remember when he wrote this code?). IMO, it should just error out if deserialization fails. The D-Bus format is very much context-sensitive and deserialization depends completely on the signature provided.

@ids1024
Copy link
Contributor Author

ids1024 commented Jun 24, 2024

This is for DeserializeDict, so it's entirely possible for the dict to contain a different type. Since it's deserializing from variant types. And ignoring the field if it has an unexpected type may be reasonable for some uses, though silently doing that could definitely be unexpected.

In this case I fixed the issue by just removing the field, which I wasn't using anyway. pop-os/cosmic-applets@09b2616 (I think I did see that with type type s elsewhere; but with the app that I ran into this with it's an aas).

@zeenix
Copy link
Contributor

zeenix commented Jun 24, 2024

This is for DeserializeDict, so it's entirely possible for the dict to contain a different type.

Not sure I follow. The outer encoding is a variant but in practice you'll have specific types for each key. The *Dict macros are there for exactly that reason: allowing you to map your dict entries to specific names and types. So I'm not seeing the value in ignoring conversion errors (unless user explicitly ask us to though some annotation).

@ids1024
Copy link
Contributor Author

ids1024 commented Jun 24, 2024

I mean it probably does make sense to have the option to ignore dict entries with the wrong type, as the current implementation attempts to do. Maybe not by default though; only with some explicit annotation.

jackpot51 pushed a commit to pop-os/cosmic-applets that referenced this issue Jun 24, 2024
If this has the wrong type, it causes a parse error due to
dbus2/zbus#856.

This fixes the status icon for Slack, and probably other applications.
Not sure how this field is defined in general, but with Slack it is
an `aas`.

`gnome-shell-extension-appindicator` doesn't seem to use the `shortcut`
field either.
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

No branches or pull requests

2 participants