X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-message.c;h=32af8609b3d0c0264aac21e99e33a389f02cf073;hp=9b4da3d3d3be90690f971dceec5ff24ab610af69;hb=041b85cf01ac2783d61b22da4eea8503cf8b0d5a;hpb=18f5b48f3f0679be4d23d0c279d5d780a9fa4e30 diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 9b4da3d3d..32af8609b 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -1131,9 +1131,7 @@ static void message_extend_containers(sd_bus_message *m, size_t expand) { } static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) { - struct bus_body_part *part = NULL; - size_t start_body, end_body, padding, start_part, end_part, added; - bool add_new_part; + size_t start_body, end_body, padding, added; void *p; int r; @@ -1156,54 +1154,61 @@ static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, boo return NULL; } - add_new_part = - m->n_body_parts <= 0 || - m->body_end->sealed || - padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size; + if (added > 0) { + struct bus_body_part *part = NULL; + bool add_new_part; + + add_new_part = + m->n_body_parts <= 0 || + m->body_end->sealed || + padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size; + + if (add_new_part) { + if (padding > 0) { + part = message_append_part(m); + if (!part) + return NULL; + + part_zero(part, padding); + } - if (add_new_part) { - if (padding > 0) { part = message_append_part(m); if (!part) return NULL; - part_zero(part, padding); - } + r = part_make_space(m, part, sz, &p); + if (r < 0) + return NULL; + } else { + struct bus_container *c; + void *op; + size_t os, start_part, end_part; - part = message_append_part(m); - if (!part) - return NULL; + part = m->body_end; + op = part->data; + os = part->size; - r = part_make_space(m, part, sz, &p); - if (r < 0) - return NULL; - } else { - struct bus_container *c; - void *op; - size_t os; + start_part = ALIGN_TO(part->size, align); + end_part = start_part + sz; - part = m->body_end; - op = part->data; - os = part->size; + r = part_make_space(m, part, end_part, &p); + if (r < 0) + return NULL; - start_part = ALIGN_TO(part->size, align); - end_part = start_part + sz; + if (padding > 0) { + memset(p, 0, padding); + p = (uint8_t*) p + padding; + } - r = part_make_space(m, part, end_part, &p); - if (r < 0) - return NULL; + /* Readjust pointers */ + for (c = m->containers; c < m->containers + m->n_containers; c++) + c->array_size = adjust_pointer(c->array_size, op, os, part->data); - if (padding > 0) { - memset(p, 0, padding); - p = (uint8_t*) p + padding; + m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data); } - - /* Readjust pointers */ - for (c = m->containers; c < m->containers + m->n_containers; c++) - c->array_size = adjust_pointer(c->array_size, op, os, part->data); - - m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data); - } + } else + /* Return something that is not NULL and is aligned */ + p = (uint8_t *) NULL + align; m->header->body_size = end_body; message_extend_containers(m, added); @@ -2021,7 +2026,7 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, if (!BUS_MESSAGE_IS_GVARIANT(m)) return 0; - p = c->signature; + p = strempty(c->signature); while (*p != 0) { size_t n; @@ -2069,7 +2074,7 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, if (!a) return -ENOMEM; - p = c->signature; + p = strempty(c->signature); for (i = 0, j = 0; i < c->n_offsets; i++) { unsigned k; size_t n; @@ -2399,10 +2404,12 @@ _public_ int sd_bus_message_append_array_space( assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - assert_return(bus_type_is_trivial(type), -EINVAL); + assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL); assert_return(ptr || size == 0, -EINVAL); assert_return(!m->poisoned, -ESTALE); + /* alignment and size of the trivial types (except bool) is + * identical for gvariant and dbus1 marshalling */ align = bus_type_get_alignment(type); sz = bus_type_get_size(type); @@ -2549,8 +2556,8 @@ _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m, part->size = size; copy_fd = -1; - message_extend_containers(m, size); m->header->body_size += size; + message_extend_containers(m, size); return sd_bus_message_close_container(m); } @@ -2964,8 +2971,12 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_ *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment); c->item_size = c->offsets[c->offset_index+1] - *rindex; } else { + + if (c->offset_index+1 >= (c->end-c->begin)/sz) + goto end; + /* Fixed-size array */ - *rindex += sz; + *rindex = c->begin + (c->offset_index+1) * sz; c->item_size = sz; } @@ -3549,12 +3560,20 @@ static int build_struct_offsets( int r; assert(m); - assert(signature); assert(item_size); assert(offsets); assert(n_offsets); + if (isempty(signature)) { + *item_size = 0; + *offsets = NULL; + *n_offsets = 0; + return 0; + } + sz = determine_word_size(size, 0); + if (sz <= 0) + return -EBADMSG; /* First, loop over signature and count variable elements and * elements in general. We use this to know how large the @@ -3892,6 +3911,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, _public_ int sd_bus_message_exit_container(sd_bus_message *m) { struct bus_container *c; + unsigned saved; int r; assert_return(m, -EINVAL); @@ -3923,7 +3943,10 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) { c = message_get_container(m); + saved = c->index; + c->index = c->saved_index; r = container_next_item(m, c, &m->rindex); + c->index = saved; if (r < 0) return r; @@ -4127,6 +4150,9 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) { m->rindex = c->begin; } + c->offset_index = 0; + c->item_size = c->n_offsets > 0 ? c->offsets[0] : c->end; + return !isempty(c->signature); } @@ -4825,7 +4851,7 @@ int bus_message_parse_fields(sd_bus_message *m) { uint32_t unix_fds = 0; void *offsets = NULL; unsigned n_offsets = 0; - size_t sz; + size_t sz = 0; unsigned i = 0; assert(m); @@ -5059,9 +5085,6 @@ int bus_message_parse_fields(sd_bus_message *m) { if (m->n_fds != unix_fds) return -EBADMSG; - if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0)) - return -EBADMSG; - switch (m->header->type) { case SD_BUS_MESSAGE_SIGNAL: @@ -5276,7 +5299,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet assert_return(m, NULL); c = complete ? &m->root_container : message_get_container(m); - return c->signature ?: ""; + return strempty(c->signature); } _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {