diff --git a/man/sd_bus_message_read_strv.xml b/man/sd_bus_message_read_strv.xml index a90ae840983..50580d86bcc 100644 --- a/man/sd_bus_message_read_strv.xml +++ b/man/sd_bus_message_read_strv.xml @@ -36,11 +36,13 @@ Description - sd_bus_message_read_strv() gives access to an array of strings in message - m. The "read pointer" in the message must be right before an array of strings. On - success, a pointer to the NULL-terminated array of strings is returned in the output - parameter l. Note that ownership of this array is transferred to the caller. - Hence, the caller is responsible for freeing this array and its contents. + sd_bus_message_read_strv() gives access to an array of string-like items in + message m. The "read pointer" in the message must be right before an array of + strings (D-Bus type as), object paths (D-Bus type ao), or + signatures (D-Bus type ag). On success, a pointer to a + NULL-terminated array of strings is returned in the output parameter + l. Note that ownership of this array is transferred to the caller. Hence, the + caller is responsible for freeing this array and its contents. @@ -73,6 +75,13 @@ The message cannot be parsed. + + + -ENXIO + + The message "read pointer" is not right before an array of the appropriate type. + + diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index f358a8699e8..894d681260f 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -5587,17 +5587,26 @@ 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) { - const char *s; + char type; + const char *contents, *s; int r; assert(m); assert(l); - r = sd_bus_message_enter_container(m, 'a', "s"); + r = sd_bus_message_peek_type(m, &type, &contents); + if (r < 0) + return r; + + if (type != SD_BUS_TYPE_ARRAY || !STR_IN_SET(contents, "s", "o", "g")) + return -ENXIO; + + r = sd_bus_message_enter_container(m, 'a', NULL); if (r <= 0) return r; - while ((r = sd_bus_message_read_basic(m, 's', &s)) > 0) { + /* sd_bus_message_read_basic() does content validation for us. */ + while ((r = sd_bus_message_read_basic(m, *contents, &s)) > 0) { r = strv_extend(l, s); if (r < 0) return r;