Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/flb_cfl_ra_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,
{
int levels;
int matched = 0;
cfl_sds_t found = NULL;
cfl_sds_t key = NULL;
struct cfl_variant *val = NULL;
struct cfl_kvpair *kvpair = NULL;
Expand All @@ -142,6 +141,11 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,
/* Expected number of map levels in the map */
levels = mk_list_size(subkeys);

/* Early return if no subkeys */
if (levels == 0) {
return -1;
}

cur = *vobj;

mk_list_foreach(head, subkeys) {
Expand All @@ -157,14 +161,20 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,

/* Index limit and ensure no overflow */
if (entry->array_id == INT_MAX ||
cfl_array_size(cur.data.as_array) < entry->array_id + 1) {
entry->array_id >= cfl_array_size(cur.data.as_array)) {
return -1;
}

val = cur.data.as_array->entries[entry->array_id];
cur = *val;
key = NULL; /* fill NULL since the type is array. */
goto next;
matched++;

if (levels == matched) {
break;
}

continue;
}

if (cur.type != CFL_VARIANT_KVLIST) {
Expand All @@ -173,17 +183,13 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,

kvpair = cfl_variant_kvpair_get(&cur, entry->str);
if (kvpair == NULL) {
found = NULL;
continue;
continue; /* Try next entry */
}

key = kvpair->key;
val = kvpair->val;

found = key;
cur = *val;

next:
matched++;

if (levels == matched) {
Expand All @@ -192,7 +198,7 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,
}

/* No matches */
if (found == NULL || (matched > 0 && levels != matched)) {
if (matched == 0 || (matched > 0 && levels != matched)) {
return -1;
}

Expand All @@ -202,7 +208,6 @@ static int subkey_to_variant(struct cfl_variant *vobj, struct mk_list *subkeys,
return 0;
}


struct flb_cfl_ra_value *flb_cfl_ra_key_to_value(flb_sds_t ckey,
struct cfl_variant vobj,
struct mk_list *subkeys)
Expand Down
37 changes: 21 additions & 16 deletions src/flb_ra_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,11 @@ static int msgpack_object_strcmp(msgpack_object o, char *str, int len)

/* Lookup perfect match of sub-keys and map content */
static int subkey_to_object(msgpack_object *map, struct mk_list *subkeys,
msgpack_object **out_key, msgpack_object **out_val)
msgpack_object **out_key, msgpack_object **out_val)
{
int i = 0;
int levels;
int matched = 0;
msgpack_object *found = NULL;
msgpack_object *key = NULL;
msgpack_object *val = NULL;
msgpack_object cur;
Expand All @@ -136,6 +135,11 @@ static int subkey_to_object(msgpack_object *map, struct mk_list *subkeys,
/* Expected number of map levels in the map */
levels = mk_list_size(subkeys);

/* Early return if no subkeys */
if (levels == 0) {
return -1;
}

cur = *map;

mk_list_foreach(head, subkeys) {
Expand All @@ -150,40 +154,41 @@ static int subkey_to_object(msgpack_object *map, struct mk_list *subkeys,
}

/* Index limit and ensure no overflow */
if (entry->array_id == INT_MAX ||
cur.via.array.size < entry->array_id + 1) {
if (entry->array_id == INT_MAX || entry->array_id >= cur.via.array.size) {
return -1;
}

val = &cur.via.array.ptr[entry->array_id];
cur = *val;
key = NULL; /* fill NULL since the type is array. */
goto next;
matched++;

if (levels == matched) {
break;
}

continue;
}

/* Handle map objects */
if (cur.type != MSGPACK_OBJECT_MAP) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case, what will happen if the accessed value is another array ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. When the accessed value is another array, the function will process it in the next iteration through if (entry->type == FLB_RA_KEY_ARRAY), which runs before the map type check. This is validated in cb_nested_array_access() test, which successfully accesses $matrix[1][2] from {"matrix": [[1, 2, 3], [4, 5, 6], [7, 8, 9]]} to get the value 6.

break;
}

i = ra_key_val_id(entry->str, cur);
if (i == -1) {
found = NULL;
continue;
continue; /* Try next entry */
}

key = &cur.via.map.ptr[i].key;
val = &cur.via.map.ptr[i].val;

/* A bit obvious, but it's better to validate data type */
if (key->type != MSGPACK_OBJECT_STR) {
found = NULL;
continue;
continue; /* Try next entry */
}

found = key;
cur = cur.via.map.ptr[i].val;

next:
cur = *val;
matched++;

if (levels == matched) {
Expand All @@ -192,12 +197,12 @@ static int subkey_to_object(msgpack_object *map, struct mk_list *subkeys,
}

/* No matches */
if (!found || (matched > 0 && levels != matched)) {
if (matched == 0 || (matched > 0 && levels != matched)) {
return -1;
}

*out_key = (msgpack_object *) key;
*out_val = (msgpack_object *) val;
*out_key = key;
*out_val = val;

return 0;
}
Expand Down
Loading
Loading