diff options
author | Pavel Březina <pbrezina@redhat.com> | 2014-07-01 11:55:41 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-07-16 17:31:42 +0200 |
commit | 973be642f3d33ba21ea9c06791295f09efcdba46 (patch) | |
tree | c3e19464ced6ed68ef3ffa2c7ba7249c365c4920 | |
parent | b7080f1a2c6c97224c41f6347ca3743e1054faec (diff) | |
download | sssd-973be642f3d33ba21ea9c06791295f09efcdba46.tar.gz sssd-973be642f3d33ba21ea9c06791295f09efcdba46.tar.xz sssd-973be642f3d33ba21ea9c06791295f09efcdba46.zip |
sss_sifp: set output parameters if attribute is NULL
There are two cases that may happen when a user calls Get or GetAll:
1) the attribute is missing
2) the attribute is empty
sss_sifp has two error code to distinguish between those two cases:
1) SSS_SIFP_ATTR_MISSING
2) SSS_SIFP_ATTR_NULL
Usually the caller is not interested on situations when the attribute
is empty and it can be considered as error. Having it as a separate
error code instead of setting the output value to NULL is necesarry
since attribute does not have to be a pointer.
This patch however sets pointer type attributes to NULL since it may
simplify the code path when the caller is actually interested in
this information (e. g. empty server list on domain objects).
It is not possible to send a NULL string over a D-Bus nor it is
possible to have hash table NULL with current code so these two
scenarios are not tested. However, it is handled in sss_sifp_attr
code for completeness.
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
-rw-r--r-- | src/lib/sifp/sss_sifp_attrs.c | 120 | ||||
-rw-r--r-- | src/tests/cmocka/test_sss_sifp.c | 338 |
2 files changed, 415 insertions, 43 deletions
diff --git a/src/lib/sifp/sss_sifp_attrs.c b/src/lib/sifp/sss_sifp_attrs.c index 6d10c4611..1004252e3 100644 --- a/src/lib/sifp/sss_sifp_attrs.c +++ b/src/lib/sifp/sss_sifp_attrs.c @@ -23,41 +23,54 @@ #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_private.h" -#define GET_ATTR(attrs, name, rtype, field, out) do { \ +#define GET_ATTR(attrs, name, rtype, field, out, ret) do { \ sss_sifp_attr *attr = sss_sifp_find_attr(attrs, name); \ \ if (attr == NULL) { \ - return SSS_SIFP_ATTR_MISSING; \ + ret = SSS_SIFP_ATTR_MISSING; \ + break; \ } \ \ if (attr->type != rtype) { \ - return SSS_SIFP_INCORRECT_TYPE; \ + ret = SSS_SIFP_INCORRECT_TYPE; \ + break; \ } \ \ if (attr->data.field == NULL) { \ - return SSS_SIFP_ATTR_NULL; \ + ret = SSS_SIFP_ATTR_NULL; \ + break; \ } \ \ out = attr->data.field[0]; \ + \ + ret = SSS_SIFP_OK; \ } while (0) -#define GET_ATTR_ARRAY(attrs, name, rtype, field, out_num, out_val) do { \ +#define GET_ATTR_ARRAY(attrs, name, rtype, field, out_num, out_val, ret) \ +do { \ sss_sifp_attr *attr = sss_sifp_find_attr(attrs, name); \ \ if (attr == NULL) { \ - return SSS_SIFP_ATTR_MISSING; \ + ret = SSS_SIFP_ATTR_MISSING; \ + break; \ } \ \ if (attr->type != rtype) { \ - return SSS_SIFP_INCORRECT_TYPE; \ + ret = SSS_SIFP_INCORRECT_TYPE; \ + break; \ } \ \ if (attr->data.field == NULL) { \ - return SSS_SIFP_ATTR_NULL; \ + out_num = 0; \ + out_val = NULL; \ + ret = SSS_SIFP_ATTR_NULL; \ + break; \ } \ \ out_num = attr->num_values; \ out_val = attr->data.field; \ + \ + ret = SSS_SIFP_OK; \ } while (0) static sss_sifp_attr *sss_sifp_find_attr(sss_sifp_attr **attrs, @@ -83,8 +96,9 @@ sss_sifp_find_attr_as_bool(sss_sifp_attr **attrs, const char *name, bool *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_BOOL, boolean, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_BOOL, boolean, *_value, ret); + return ret; } sss_sifp_error @@ -92,8 +106,9 @@ sss_sifp_find_attr_as_int16(sss_sifp_attr **attrs, const char *name, int16_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT16, int16, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT16, int16, *_value, ret); + return ret; } sss_sifp_error @@ -101,8 +116,9 @@ sss_sifp_find_attr_as_uint16(sss_sifp_attr **attrs, const char *name, uint16_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT16, uint16, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT16, uint16, *_value, ret); + return ret; } sss_sifp_error @@ -110,8 +126,9 @@ sss_sifp_find_attr_as_int32(sss_sifp_attr **attrs, const char *name, int32_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT32, int32, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT32, int32, *_value, ret); + return ret; } sss_sifp_error @@ -119,8 +136,9 @@ sss_sifp_find_attr_as_uint32(sss_sifp_attr **attrs, const char *name, uint32_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT32, uint32, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT32, uint32, *_value, ret); + return ret; } sss_sifp_error @@ -128,8 +146,9 @@ sss_sifp_find_attr_as_int64(sss_sifp_attr **attrs, const char *name, int64_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT64, int64, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT64, int64, *_value, ret); + return ret; } sss_sifp_error @@ -137,8 +156,9 @@ sss_sifp_find_attr_as_uint64(sss_sifp_attr **attrs, const char *name, uint64_t *_value) { - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT64, uint64, *_value); - return SSS_SIFP_OK; + sss_sifp_error ret; + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT64, uint64, *_value, ret); + return ret; } sss_sifp_error @@ -146,16 +166,18 @@ sss_sifp_find_attr_as_string(sss_sifp_attr **attrs, const char *name, const char **_value) { + sss_sifp_error ret; const char *value = NULL; - GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_STRING, str, value); + GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_STRING, str, value, ret); - if (value == NULL) { - return SSS_SIFP_ATTR_NULL; + if (ret == SSS_SIFP_ATTR_NULL) { + *_value = NULL; + return ret; } *_value = value; - return SSS_SIFP_OK; + return ret; } sss_sifp_error @@ -174,6 +196,7 @@ sss_sifp_find_attr_as_string_dict(sss_sifp_attr **attrs, } if (attr->data.str_dict == NULL) { + *_value = NULL; return SSS_SIFP_ATTR_NULL; } @@ -196,9 +219,10 @@ sss_sifp_find_attr_as_bool_array(sss_sifp_attr **attrs, unsigned int *_num_values, bool **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_BOOL, boolean, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -207,9 +231,10 @@ sss_sifp_find_attr_as_int16_array(sss_sifp_attr **attrs, unsigned int *_num_values, int16_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT16, int16, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -218,9 +243,10 @@ sss_sifp_find_attr_as_uint16_array(sss_sifp_attr **attrs, unsigned int *_num_values, uint16_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT16, uint16, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -229,9 +255,10 @@ sss_sifp_find_attr_as_int32_array(sss_sifp_attr **attrs, unsigned int *_num_values, int32_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT32, int32, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -240,9 +267,10 @@ sss_sifp_find_attr_as_uint32_array(sss_sifp_attr **attrs, unsigned int *_num_values, uint32_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT32, uint32, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -251,9 +279,10 @@ sss_sifp_find_attr_as_int64_array(sss_sifp_attr **attrs, unsigned int *_num_values, int64_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT64, int64, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -262,9 +291,10 @@ sss_sifp_find_attr_as_uint64_array(sss_sifp_attr **attrs, unsigned int *_num_values, uint64_t **_value) { + sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT64, uint64, - *_num_values, *_value); - return SSS_SIFP_OK; + *_num_values, *_value, ret); + return ret; } sss_sifp_error @@ -273,11 +303,15 @@ sss_sifp_find_attr_as_string_array(sss_sifp_attr **attrs, unsigned int *_num_values, const char * const **_value) { + sss_sifp_error ret; char **value; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_STRING, str, - *_num_values, value); - *_value = (const char * const *)value; + *_num_values, value, ret); - return SSS_SIFP_OK; + if (ret == SSS_SIFP_OK || ret == SSS_SIFP_ATTR_NULL) { + *_value = (const char * const *)value; + } + + return ret; } diff --git a/src/tests/cmocka/test_sss_sifp.c b/src/tests/cmocka/test_sss_sifp.c index 384bae416..3c009d978 100644 --- a/src/tests/cmocka/test_sss_sifp.c +++ b/src/tests/cmocka/test_sss_sifp.c @@ -730,6 +730,42 @@ void test_sss_sifp_parse_attr_bool_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_bool_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + bool *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_BOOLEAN_AS_STRING, num_values, + NULL, sizeof(dbus_bool_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_BOOL); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_bool_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_int16_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -772,6 +808,42 @@ void test_sss_sifp_parse_attr_int16_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_int16_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + int16_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_INT16_AS_STRING, num_values, + NULL, sizeof(int16_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT16); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_int16_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_uint16_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -814,6 +886,42 @@ void test_sss_sifp_parse_attr_uint16_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_uint16_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + uint16_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_UINT16_AS_STRING, num_values, + NULL, sizeof(uint16_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT16); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_uint16_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_int32_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -856,6 +964,42 @@ void test_sss_sifp_parse_attr_int32_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_int32_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + int32_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_INT32_AS_STRING, num_values, + NULL, sizeof(int32_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT32); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_int32_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_uint32_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -898,6 +1042,42 @@ void test_sss_sifp_parse_attr_uint32_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_uint32_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + uint32_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_UINT32_AS_STRING, num_values, + NULL, sizeof(uint32_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT32); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_uint32_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_int64_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -940,6 +1120,42 @@ void test_sss_sifp_parse_attr_int64_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_int64_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + int64_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_INT64_AS_STRING, num_values, + NULL, sizeof(int64_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT64); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_int64_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_uint64_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -982,6 +1198,42 @@ void test_sss_sifp_parse_attr_uint64_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_uint64_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + uint64_t *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_UINT64_AS_STRING, num_values, + NULL, sizeof(uint64_t)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT64); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_uint64_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_string_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -1024,6 +1276,42 @@ void test_sss_sifp_parse_attr_string_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_string_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + const char * const *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_STRING_AS_STRING, num_values, + NULL, sizeof(const char*)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_object_path_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; @@ -1066,6 +1354,42 @@ void test_sss_sifp_parse_attr_object_path_array(void **state) assert_null(attrs); } +void test_sss_sifp_parse_attr_object_path_array_empty(void **state) +{ + sss_sifp_ctx *ctx = test_ctx.dbus_ctx; + DBusMessage *reply = test_ctx.reply; + sss_sifp_error ret; + sss_sifp_attr **attrs = NULL; + const char *name = "test-attr"; + unsigned int num_values = 0; + unsigned int out_num; + const char * const *out; + + /* prepare message */ + reply_variant_array(reply, DBUS_TYPE_OBJECT_PATH_AS_STRING, num_values, + NULL, sizeof(const char*)); + + /* test */ + ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); + + assert_int_equal(ret, SSS_SIFP_OK); + assert_non_null(attrs); + assert_non_null(attrs[0]); + assert_null(attrs[1]); + + assert_int_equal(attrs[0]->num_values, num_values); + assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); + assert_string_equal(attrs[0]->name, name); + + ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); + assert_int_equal(ret, SSS_SIFP_ATTR_NULL); + assert_int_equal(num_values, out_num); + assert_null(out); + + sss_sifp_free_attrs(ctx, &attrs); + assert_null(attrs); +} + void test_sss_sifp_parse_attr_string_dict_array(void **state) { return; @@ -1869,18 +2193,32 @@ int main(int argc, const char *argv[]) test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array, test_setup, test_teardown_parser), + unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array_empty, + test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict_array, test_setup, test_teardown_parser), unit_test_setup_teardown(test_sss_sifp_parse_attr_list, |