Byte arrays that represent encoded strings should be 0-terminated
Here's a sample program that shows obviously wrong behaviour:
const {Gio, GLib} = imports.gi;
const ByteArray = imports.byteArray;
const byteArray = ByteArray.fromString('pizza');
const byteArrayVariant = new GLib.Variant('ay', byteArray);
const out = Gio.dbus_gvariant_to_gvalue(byteArrayVariant);
print(JSON.stringify(out));
This behaviour can crop up in unexpected places; for example, calling a DBus method with an argument of type ay
, with a ByteArray created in this way, will cause the argument to appear as an empty string on the remote side.
Bytestring GVariant types are intended to have a terminating \0
, according to the documentation. The problem is that bytestrings share the same GVariant type as byte arrays, which need not be strings and may contain embedded 0 bytes.
It's not entirely straightforward what has to be fixed here. I see two options:
- Make
new GLib.Variant('ay', someString)
add a terminating\0
and thereby behave differently fromnew GLib.Variant('ay', someByteArray)
. - Make
ByteArray.fromString()
ensure that the byte array has a terminating\0
.
Both of these would be a small compatibility break.
I would argue that option 2, is the more correct behaviour, and probably the existing behaviour is a source of hard-to-find bugs, so it's worth changing.
Option 1 is also a compatibility break, but the existing behaviour of new GLib.Variant('ay', someString)
is to always strip the terminating \0
and this is probably never what client code intends, so I don't feel bad about changing this.