sd-bus: drop D-Bus version 2 format support

It seems the format is used only by kdbus.
This commit is contained in:
Yu Watanabe
2022-06-01 03:41:15 +09:00
parent c0f664ca89
commit 0dd4876815
11 changed files with 437 additions and 2446 deletions
-8
View File
@@ -95,8 +95,6 @@ libsystemd_sources = files(
'sd-bus/bus-dump.h',
'sd-bus/bus-error.c',
'sd-bus/bus-error.h',
'sd-bus/bus-gvariant.c',
'sd-bus/bus-gvariant.h',
'sd-bus/bus-internal.c',
'sd-bus/bus-internal.h',
'sd-bus/bus-introspect.c',
@@ -262,12 +260,6 @@ tests += [
[files('sd-bus/test-bus-vtable.c',
'sd-bus/test-vtable-data.h')],
[files('sd-bus/test-bus-gvariant.c'),
[],
[libglib,
libgobject,
libgio]],
[files('sd-bus/test-bus-creds.c')],
[files('sd-bus/test-bus-match.c')],
-299
View File
@@ -1,299 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <string.h>
#include "sd-bus.h"
#include "bus-gvariant.h"
#include "bus-signature.h"
#include "bus-type.h"
int bus_gvariant_get_size(const char *signature) {
const char *p;
int sum = 0, r;
/* For fixed size structs. Fails for variable size structs. */
p = signature;
while (*p != 0) {
size_t n;
r = signature_element_length(p, &n);
if (r < 0)
return r;
else {
char t[n+1];
memcpy(t, p, n);
t[n] = 0;
r = bus_gvariant_get_alignment(t);
if (r < 0)
return r;
sum = ALIGN_TO(sum, r);
}
switch (*p) {
case SD_BUS_TYPE_BOOLEAN:
case SD_BUS_TYPE_BYTE:
sum += 1;
break;
case SD_BUS_TYPE_INT16:
case SD_BUS_TYPE_UINT16:
sum += 2;
break;
case SD_BUS_TYPE_INT32:
case SD_BUS_TYPE_UINT32:
case SD_BUS_TYPE_UNIX_FD:
sum += 4;
break;
case SD_BUS_TYPE_INT64:
case SD_BUS_TYPE_UINT64:
case SD_BUS_TYPE_DOUBLE:
sum += 8;
break;
case SD_BUS_TYPE_STRUCT_BEGIN:
case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
if (n == 2) {
/* unary type () has fixed size of 1 */
r = 1;
} else {
char t[n-1];
memcpy(t, p + 1, n - 2);
t[n - 2] = 0;
r = bus_gvariant_get_size(t);
if (r < 0)
return r;
}
sum += r;
break;
}
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
case SD_BUS_TYPE_SIGNATURE:
case SD_BUS_TYPE_ARRAY:
case SD_BUS_TYPE_VARIANT:
return -EINVAL;
default:
assert_not_reached();
}
p += n;
}
r = bus_gvariant_get_alignment(signature);
if (r < 0)
return r;
return ALIGN_TO(sum, r);
}
int bus_gvariant_get_alignment(const char *signature) {
size_t alignment = 1;
const char *p;
int r;
p = signature;
while (*p != 0 && alignment < 8) {
size_t n;
int a;
r = signature_element_length(p, &n);
if (r < 0)
return r;
switch (*p) {
case SD_BUS_TYPE_BYTE:
case SD_BUS_TYPE_BOOLEAN:
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
case SD_BUS_TYPE_SIGNATURE:
a = 1;
break;
case SD_BUS_TYPE_INT16:
case SD_BUS_TYPE_UINT16:
a = 2;
break;
case SD_BUS_TYPE_INT32:
case SD_BUS_TYPE_UINT32:
case SD_BUS_TYPE_UNIX_FD:
a = 4;
break;
case SD_BUS_TYPE_INT64:
case SD_BUS_TYPE_UINT64:
case SD_BUS_TYPE_DOUBLE:
case SD_BUS_TYPE_VARIANT:
a = 8;
break;
case SD_BUS_TYPE_ARRAY: {
char t[n];
memcpy(t, p + 1, n - 1);
t[n - 1] = 0;
a = bus_gvariant_get_alignment(t);
break;
}
case SD_BUS_TYPE_STRUCT_BEGIN:
case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
char t[n-1];
memcpy(t, p + 1, n - 2);
t[n - 2] = 0;
a = bus_gvariant_get_alignment(t);
break;
}
default:
assert_not_reached();
}
if (a < 0)
return a;
assert(a > 0 && a <= 8);
if ((size_t) a > alignment)
alignment = (size_t) a;
p += n;
}
return alignment;
}
int bus_gvariant_is_fixed_size(const char *signature) {
const char *p;
int r;
assert(signature);
p = signature;
while (*p != 0) {
size_t n;
r = signature_element_length(p, &n);
if (r < 0)
return r;
switch (*p) {
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
case SD_BUS_TYPE_SIGNATURE:
case SD_BUS_TYPE_ARRAY:
case SD_BUS_TYPE_VARIANT:
return 0;
case SD_BUS_TYPE_BYTE:
case SD_BUS_TYPE_BOOLEAN:
case SD_BUS_TYPE_INT16:
case SD_BUS_TYPE_UINT16:
case SD_BUS_TYPE_INT32:
case SD_BUS_TYPE_UINT32:
case SD_BUS_TYPE_UNIX_FD:
case SD_BUS_TYPE_INT64:
case SD_BUS_TYPE_UINT64:
case SD_BUS_TYPE_DOUBLE:
break;
case SD_BUS_TYPE_STRUCT_BEGIN:
case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
char t[n-1];
memcpy(t, p + 1, n - 2);
t[n - 2] = 0;
r = bus_gvariant_is_fixed_size(t);
if (r <= 0)
return r;
break;
}
default:
assert_not_reached();
}
p += n;
}
return true;
}
size_t bus_gvariant_determine_word_size(size_t sz, size_t extra) {
if (sz + extra <= 0xFF)
return 1;
else if (sz + extra*2 <= 0xFFFF)
return 2;
else if (sz + extra*4 <= 0xFFFFFFFF)
return 4;
else
return 8;
}
size_t bus_gvariant_read_word_le(void *p, size_t sz) {
union {
uint16_t u16;
uint32_t u32;
uint64_t u64;
} x;
assert(p);
if (sz == 1)
return *(uint8_t*) p;
memcpy(&x, p, sz);
if (sz == 2)
return le16toh(x.u16);
else if (sz == 4)
return le32toh(x.u32);
else if (sz == 8)
return le64toh(x.u64);
assert_not_reached();
}
void bus_gvariant_write_word_le(void *p, size_t sz, size_t value) {
union {
uint16_t u16;
uint32_t u32;
uint64_t u64;
} x;
assert(p);
assert(sz == 8 || (value < (1ULL << (sz*8))));
if (sz == 1) {
*(uint8_t*) p = value;
return;
} else if (sz == 2)
x.u16 = htole16((uint16_t) value);
else if (sz == 4)
x.u32 = htole32((uint32_t) value);
else if (sz == 8)
x.u64 = htole64((uint64_t) value);
else
assert_not_reached();
memcpy(p, &x, sz);
}
-12
View File
@@ -1,12 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "macro.h"
int bus_gvariant_get_size(const char *signature) _pure_;
int bus_gvariant_get_alignment(const char *signature) _pure_;
int bus_gvariant_is_fixed_size(const char *signature) _pure_;
size_t bus_gvariant_determine_word_size(size_t sz, size_t extra);
void bus_gvariant_write_word_le(void *p, size_t sz, size_t value);
size_t bus_gvariant_read_word_le(void *p, size_t sz);
File diff suppressed because it is too large Load Diff
+4 -21
View File
@@ -14,21 +14,16 @@
struct bus_container {
char enclosing;
bool need_offsets:1;
/* Indexes into the signature string */
/* Indexes into the signature string */
unsigned index, saved_index;
char *signature;
size_t before, begin, end;
/* dbus1: pointer to the array size value, if this is a value */
/* pointer to the array size value, if this is a value */
uint32_t *array_size;
/* gvariant: list of offsets to end of children if this is struct/dict entry/array */
size_t *offsets, n_offsets, offset_index;
size_t item_size;
char *peeked_signature;
};
@@ -86,13 +81,8 @@ struct sd_bus_message {
bool poisoned:1;
bool sensitive:1;
/* The first and last bytes of the message */
/* The first bytes of the message */
struct bus_header *header;
void *footer;
/* How many bytes are accessible in the above pointers */
size_t header_accessible;
size_t footer_accessible;
size_t fields_size;
size_t body_size;
@@ -148,10 +138,7 @@ static inline uint64_t BUS_MESSAGE_BSWAP64(sd_bus_message *m, uint64_t u) {
}
static inline uint64_t BUS_MESSAGE_COOKIE(sd_bus_message *m) {
if (m->header->version == 2)
return BUS_MESSAGE_BSWAP64(m, m->header->dbus2.cookie);
return BUS_MESSAGE_BSWAP32(m, m->header->dbus1.serial);
return BUS_MESSAGE_BSWAP32(m, m->header->serial);
}
static inline size_t BUS_MESSAGE_SIZE(sd_bus_message *m) {
@@ -171,10 +158,6 @@ static inline void* BUS_MESSAGE_FIELDS(sd_bus_message *m) {
return (uint8_t*) m->header + sizeof(struct bus_header);
}
static inline bool BUS_MESSAGE_IS_GVARIANT(sd_bus_message *m) {
return m->header->version == 2;
}
int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz);
int bus_message_read_strv_extend(sd_bus_message *m, char ***l);
+5 -22
View File
@@ -8,32 +8,15 @@
/* Packet header */
struct _packed_ bus_header {
/* The first four fields are identical for dbus1, and dbus2 */
uint8_t endian;
uint8_t type;
uint8_t flags;
uint8_t version;
union _packed_ {
/* dbus1: Used for SOCK_STREAM connections */
struct _packed_ {
uint32_t body_size;
/* Note that what the bus spec calls "serial" we'll call
"cookie" instead, because we don't want to imply that the
cookie was in any way monotonically increasing. */
uint32_t serial;
uint32_t fields_size;
} dbus1;
/* dbus2: Used for kdbus connections */
struct _packed_ {
uint32_t _reserved;
uint64_t cookie;
} dbus2;
/* Note that both header versions have the same size! */
};
uint32_t body_size;
/* Note that what the bus spec calls "serial" we'll call "cookie" instead, because we don't
* want to imply that the cookie was in any way monotonically increasing. */
uint32_t serial;
uint32_t fields_size;
};
/* Endianness */
+1 -3
View File
@@ -1966,9 +1966,7 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
* hence let's fill something in for synthetic messages. Since
* synthetic messages might have a fake sender and we don't
* want to interfere with the real sender's serial numbers we
* pick a fixed, artificial one. We use UINT32_MAX rather
* than UINT64_MAX since dbus1 only had 32bit identifiers,
* even though kdbus can do 64bit. */
* pick a fixed, artificial one. */
return sd_bus_message_seal(m, UINT32_MAX, 0);
}
-206
View File
@@ -1,206 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#if HAVE_GLIB
#include <glib.h>
#endif
#include "sd-bus.h"
#include "alloc-util.h"
#include "bus-dump.h"
#include "bus-gvariant.h"
#include "bus-internal.h"
#include "bus-message.h"
#include "macro.h"
#include "tests.h"
#include "util.h"
TEST(bus_gvariant_is_fixed_size) {
assert_se(bus_gvariant_is_fixed_size("") > 0);
assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL);
assert_se(bus_gvariant_is_fixed_size("y") > 0);
assert_se(bus_gvariant_is_fixed_size("u") > 0);
assert_se(bus_gvariant_is_fixed_size("b") > 0);
assert_se(bus_gvariant_is_fixed_size("n") > 0);
assert_se(bus_gvariant_is_fixed_size("q") > 0);
assert_se(bus_gvariant_is_fixed_size("i") > 0);
assert_se(bus_gvariant_is_fixed_size("t") > 0);
assert_se(bus_gvariant_is_fixed_size("d") > 0);
assert_se(bus_gvariant_is_fixed_size("s") == 0);
assert_se(bus_gvariant_is_fixed_size("o") == 0);
assert_se(bus_gvariant_is_fixed_size("g") == 0);
assert_se(bus_gvariant_is_fixed_size("h") > 0);
assert_se(bus_gvariant_is_fixed_size("ay") == 0);
assert_se(bus_gvariant_is_fixed_size("v") == 0);
assert_se(bus_gvariant_is_fixed_size("(u)") > 0);
assert_se(bus_gvariant_is_fixed_size("(uuuuy)") > 0);
assert_se(bus_gvariant_is_fixed_size("(uusuuy)") == 0);
assert_se(bus_gvariant_is_fixed_size("a{ss}") == 0);
assert_se(bus_gvariant_is_fixed_size("((u)yyy(b(iiii)))") > 0);
assert_se(bus_gvariant_is_fixed_size("((u)yyy(b(iiivi)))") == 0);
}
TEST(bus_gvariant_get_size) {
assert_se(bus_gvariant_get_size("") == 0);
assert_se(bus_gvariant_get_size("()") == -EINVAL);
assert_se(bus_gvariant_get_size("y") == 1);
assert_se(bus_gvariant_get_size("u") == 4);
assert_se(bus_gvariant_get_size("b") == 1);
assert_se(bus_gvariant_get_size("n") == 2);
assert_se(bus_gvariant_get_size("q") == 2);
assert_se(bus_gvariant_get_size("i") == 4);
assert_se(bus_gvariant_get_size("t") == 8);
assert_se(bus_gvariant_get_size("d") == 8);
assert_se(bus_gvariant_get_size("s") < 0);
assert_se(bus_gvariant_get_size("o") < 0);
assert_se(bus_gvariant_get_size("g") < 0);
assert_se(bus_gvariant_get_size("h") == 4);
assert_se(bus_gvariant_get_size("ay") < 0);
assert_se(bus_gvariant_get_size("v") < 0);
assert_se(bus_gvariant_get_size("(u)") == 4);
assert_se(bus_gvariant_get_size("(uuuuy)") == 20);
assert_se(bus_gvariant_get_size("(uusuuy)") < 0);
assert_se(bus_gvariant_get_size("a{ss}") < 0);
assert_se(bus_gvariant_get_size("((u)yyy(b(iiii)))") == 28);
assert_se(bus_gvariant_get_size("((u)yyy(b(iiivi)))") < 0);
assert_se(bus_gvariant_get_size("((b)(t))") == 16);
assert_se(bus_gvariant_get_size("((b)(b)(t))") == 16);
assert_se(bus_gvariant_get_size("(bt)") == 16);
assert_se(bus_gvariant_get_size("((t)(b))") == 16);
assert_se(bus_gvariant_get_size("(tb)") == 16);
assert_se(bus_gvariant_get_size("((b)(b))") == 2);
assert_se(bus_gvariant_get_size("((t)(t))") == 16);
}
TEST(bus_gvariant_get_alignment) {
assert_se(bus_gvariant_get_alignment("") == 1);
assert_se(bus_gvariant_get_alignment("()") == -EINVAL);
assert_se(bus_gvariant_get_alignment("y") == 1);
assert_se(bus_gvariant_get_alignment("b") == 1);
assert_se(bus_gvariant_get_alignment("u") == 4);
assert_se(bus_gvariant_get_alignment("s") == 1);
assert_se(bus_gvariant_get_alignment("o") == 1);
assert_se(bus_gvariant_get_alignment("g") == 1);
assert_se(bus_gvariant_get_alignment("v") == 8);
assert_se(bus_gvariant_get_alignment("h") == 4);
assert_se(bus_gvariant_get_alignment("i") == 4);
assert_se(bus_gvariant_get_alignment("t") == 8);
assert_se(bus_gvariant_get_alignment("x") == 8);
assert_se(bus_gvariant_get_alignment("q") == 2);
assert_se(bus_gvariant_get_alignment("n") == 2);
assert_se(bus_gvariant_get_alignment("d") == 8);
assert_se(bus_gvariant_get_alignment("ay") == 1);
assert_se(bus_gvariant_get_alignment("as") == 1);
assert_se(bus_gvariant_get_alignment("au") == 4);
assert_se(bus_gvariant_get_alignment("an") == 2);
assert_se(bus_gvariant_get_alignment("ans") == 2);
assert_se(bus_gvariant_get_alignment("ant") == 8);
assert_se(bus_gvariant_get_alignment("(ss)") == 1);
assert_se(bus_gvariant_get_alignment("(ssu)") == 4);
assert_se(bus_gvariant_get_alignment("a(ssu)") == 4);
assert_se(bus_gvariant_get_alignment("(u)") == 4);
assert_se(bus_gvariant_get_alignment("(uuuuy)") == 4);
assert_se(bus_gvariant_get_alignment("(uusuuy)") == 4);
assert_se(bus_gvariant_get_alignment("a{ss}") == 1);
assert_se(bus_gvariant_get_alignment("((u)yyy(b(iiii)))") == 4);
assert_se(bus_gvariant_get_alignment("((u)yyy(b(iiivi)))") == 8);
assert_se(bus_gvariant_get_alignment("((b)(t))") == 8);
assert_se(bus_gvariant_get_alignment("((b)(b)(t))") == 8);
assert_se(bus_gvariant_get_alignment("(bt)") == 8);
assert_se(bus_gvariant_get_alignment("((t)(b))") == 8);
assert_se(bus_gvariant_get_alignment("(tb)") == 8);
assert_se(bus_gvariant_get_alignment("((b)(b))") == 1);
assert_se(bus_gvariant_get_alignment("((t)(t))") == 8);
}
TEST_RET(marshal) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *n = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_free_ void *blob = NULL;
size_t sz;
int r;
r = sd_bus_open_user(&bus);
if (r < 0)
r = sd_bus_open_system(&bus);
if (r < 0)
return log_tests_skipped_errno(r, "Failed to connect to bus");
bus->message_version = 2; /* dirty hack to enable gvariant */
r = sd_bus_message_new_method_call(bus, &m, "a.service.name",
"/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works",
"an.interface.name", "AMethodName");
assert_se(r >= 0);
assert_cc(sizeof(struct bus_header) == 16);
assert_se(sd_bus_message_append(m,
"a(usv)", 3,
4711, "first-string-parameter", "(st)", "X", (uint64_t) 1111,
4712, "second-string-parameter", "(a(si))", 2, "Y", 5, "Z", 6,
4713, "third-string-parameter", "(uu)", 1, 2) >= 0);
assert_se(sd_bus_message_seal(m, 4711, 0) >= 0);
#if HAVE_GLIB
{
GVariant *v;
char *t;
#if !defined(GLIB_VERSION_2_36)
g_type_init();
#endif
v = g_variant_new_from_data(G_VARIANT_TYPE("(yyyyuta{tv})"), m->header, sizeof(struct bus_header) + m->fields_size, false, NULL, NULL);
assert_se(g_variant_is_normal_form(v));
t = g_variant_print(v, TRUE);
printf("%s\n", t);
g_free(t);
g_variant_unref(v);
v = g_variant_new_from_data(G_VARIANT_TYPE("(a(usv))"), m->body.data, m->user_body_size, false, NULL, NULL);
assert_se(g_variant_is_normal_form(v));
t = g_variant_print(v, TRUE);
printf("%s\n", t);
g_free(t);
g_variant_unref(v);
}
#endif
assert_se(sd_bus_message_dump(m, NULL, SD_BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
assert_se(bus_message_get_blob(m, &blob, &sz) >= 0);
#if HAVE_GLIB
{
GVariant *v;
char *t;
v = g_variant_new_from_data(G_VARIANT_TYPE("(yyyyuta{tv}v)"), blob, sz, false, NULL, NULL);
assert_se(g_variant_is_normal_form(v));
t = g_variant_print(v, TRUE);
printf("%s\n", t);
g_free(t);
g_variant_unref(v);
}
#endif
assert_se(bus_message_from_malloc(bus, blob, sz, NULL, 0, NULL, &n) >= 0);
blob = NULL;
assert_se(sd_bus_message_dump(n, NULL, SD_BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
m = sd_bus_message_unref(m);
assert_se(sd_bus_message_new_method_call(bus, &m, "a.x", "/a/x", "a.x", "Ax") >= 0);
assert_se(sd_bus_message_append(m, "as", 0) >= 0);
assert_se(sd_bus_message_seal(m, 4712, 0) >= 0);
assert_se(sd_bus_message_dump(m, NULL, SD_BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
return EXIT_SUCCESS;
}
DEFINE_TEST_MAIN(LOG_DEBUG);