From d469dd44c4f49bafe839c6e0bceb6ce4bfe7b3fe Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Tue, 12 Jan 2016 17:19:51 -0500 Subject: basic,bus-error: return negative error from errno_from_name errno_from_name used an unusual return convention where 0 meant "not found". This tripped up config_parse_syscall_errno(), which would treat that as success. Return -EINVAL instead, and adjust bus_error_name_to_errno() for the new convention. Also remove a goto which was used as a simple if and clean up surroudning code a bit. --- src/libsystemd/sd-bus/bus-error.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'src/libsystemd/sd-bus/bus-error.c') diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 404eaa3c89..a99d55c47a 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -93,14 +93,14 @@ static int bus_error_name_to_errno(const char *name) { p = startswith(name, "System.Error."); if (p) { r = errno_from_name(p); - if (r <= 0) + if (r < 0) return EIO; return r; } - if (additional_error_maps) { - for (map = additional_error_maps; *map; map++) { + if (additional_error_maps) + for (map = additional_error_maps; *map; map++) for (m = *map;; m++) { /* For additional error maps the end marker is actually the end marker */ if (m->code == BUS_ERROR_MAP_END_MARKER) @@ -109,15 +109,13 @@ static int bus_error_name_to_errno(const char *name) { if (streq(m->name, name)) return m->code; } - } - } m = __start_BUS_ERROR_MAP; while (m < __stop_BUS_ERROR_MAP) { /* For magic ELF error maps, the end marker might * appear in the middle of things, since multiple maps * might appear in the same section. Hence, let's skip - * over it, but realign the pointer to the netx 8byte + * over it, but realign the pointer to the next 8 byte * boundary, which is the selected alignment for the * arrays. */ if (m->code == BUS_ERROR_MAP_END_MARKER) { @@ -258,25 +256,24 @@ int bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_li if (!name) return 0; - if (!e) - goto finish; - assert_return(!bus_error_is_dirty(e), -EINVAL); + if (e) { + assert_return(!bus_error_is_dirty(e), -EINVAL); - e->name = strdup(name); - if (!e->name) { - *e = BUS_ERROR_OOM; - return -ENOMEM; - } + e->name = strdup(name); + if (!e->name) { + *e = BUS_ERROR_OOM; + return -ENOMEM; + } - /* If we hit OOM on formatting the pretty message, we ignore - * this, since we at least managed to write the error name */ - if (format) - (void) vasprintf((char**) &e->message, format, ap); + /* If we hit OOM on formatting the pretty message, we ignore + * this, since we at least managed to write the error name */ + if (format) + (void) vasprintf((char**) &e->message, format, ap); - e->_need_free = 1; + e->_need_free = 1; + } -finish: return -bus_error_name_to_errno(name); } -- cgit v1.2.3-54-g00ecf From 45ea658326ad0208031a335de8e52a8a22c6bbfa Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Wed, 13 Jan 2016 14:23:54 -0500 Subject: bus-error: verify additional error maps during installation Go over the entries in the map and check that they make sense. Tests are added. In the future we might want to do additional checks, e.g. verifying that the error names are in the expected format. --- src/libsystemd/sd-bus/bus-error.c | 18 ++++++++++-------- src/libsystemd/sd-bus/test-bus-error.c | 13 +++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/libsystemd/sd-bus/bus-error.c') diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index a99d55c47a..c77eb5fd03 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -579,27 +579,29 @@ const char *bus_error_message(const sd_bus_error *e, int error) { return strerror(error); } +static bool map_ok(const sd_bus_error_map *map) { + for (; map->code != BUS_ERROR_MAP_END_MARKER; map++) + if (!map->name || map->code <=0) + return false; + return true; +} + _public_ int sd_bus_error_add_map(const sd_bus_error_map *map) { const sd_bus_error_map **maps = NULL; unsigned n = 0; assert_return(map, -EINVAL); + assert_return(map_ok(map), -EINVAL); - if (additional_error_maps) { - for (;; n++) { - if (additional_error_maps[n] == NULL) - break; - + if (additional_error_maps) + for (; additional_error_maps[n] != NULL; n++) if (additional_error_maps[n] == map) return 0; - } - } maps = realloc_multiply(additional_error_maps, sizeof(struct sd_bus_error_map*), n + 2); if (!maps) return -ENOMEM; - maps[n] = map; maps[n+1] = NULL; diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index c52405463e..786b6d5b0f 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -167,6 +167,16 @@ static const sd_bus_error_map test_errors4[] = { SD_BUS_ERROR_MAP_END }; +static const sd_bus_error_map test_errors_bad1[] = { + SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-1", 0), + SD_BUS_ERROR_MAP_END +}; + +static const sd_bus_error_map test_errors_bad2[] = { + SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-1", -1), + SD_BUS_ERROR_MAP_END +}; + static void test_errno_mapping_custom(void) { assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error", NULL) == -5); assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-2", NULL) == -52); @@ -190,6 +200,9 @@ static void test_errno_mapping_custom(void) { assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-y", NULL) == -EIO); assert_se(sd_bus_error_set(NULL, BUS_ERROR_NO_SUCH_UNIT, NULL) == -ENOENT); + + assert_se(sd_bus_error_add_map(test_errors_bad1) == -EINVAL); + assert_se(sd_bus_error_add_map(test_errors_bad2) == -EINVAL); } int main(int argc, char *argv[]) { -- cgit v1.2.3-54-g00ecf