From 37893e4421d900eaaab3891b02b7e6b2080c21c6 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 3 Mar 2025 15:43:34 +0000 Subject: lib: nb: fix bug with keyless list specific index lookup Signed-off-by: Christian Hopps --- lib/northbound_oper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c index b7815b001a..6a3c21b237 100644 --- a/lib/northbound_oper.c +++ b/lib/northbound_oper.c @@ -437,6 +437,7 @@ static enum nb_error nb_op_ys_finalize_node_info(struct nb_op_yield_state *ys, (index == 0 || ni[-1].lookup_next_ok); if (CHECK_FLAG(nn->flags, F_NB_NODE_KEYLESS_LIST)) { + const void *parent_list_entry; uint i; ni->position = nb_op_get_position_predicate(ys, ni); @@ -452,9 +453,10 @@ static enum nb_error nb_op_ys_finalize_node_info(struct nb_op_yield_state *ys, */ /* ni->list_entry starts as the parent entry of this node */ - ni->list_entry = nb_callback_get_next(nn, ni->list_entry, NULL); + parent_list_entry = ni->list_entry; + ni->list_entry = nb_callback_get_next(nn, parent_list_entry, NULL); for (i = 1; i < ni->position && ni->list_entry; i++) - ni->list_entry = nb_callback_get_next(nn, ni->list_entry, ni->list_entry); + ni->list_entry = nb_callback_get_next(nn, parent_list_entry, ni->list_entry); if (i != ni->position || !ni->list_entry) { flog_warn(EC_LIB_NB_OPERATIONAL_DATA, -- cgit v1.2.3 From a64ecbadcc83fd1040d9c355cb1bc3a9d03a0fc7 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 26 Feb 2025 13:34:59 +0000 Subject: lib: nb: fix bug with oper-state query on list data The capacity of the xpath string was not guaranteed to be sufficient to hold all the key predicates and so would truncate. Calculate the required space and guarantee that it is available. Signed-off-by: Christian Hopps --- lib/northbound_oper.c | 5 +++-- lib/yang.c | 17 +++++++++++++++-- lib/yang.h | 6 +++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c index 6a3c21b237..bde2228012 100644 --- a/lib/northbound_oper.c +++ b/lib/northbound_oper.c @@ -1492,8 +1492,9 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) */ len = darr_strlen(ys->xpath); if (ni->keys.num) { - yang_get_key_preds(ys->xpath + len, sib, - &ni->keys, + darr_ensure_avail(ys->xpath, + yang_get_key_pred_strlen(sib, &ni->keys) + 1); + yang_get_key_preds(ys->xpath + len, sib, &ni->keys, darr_cap(ys->xpath) - len); } else { /* add a position predicate (1s based?) */ diff --git a/lib/yang.c b/lib/yang.c index dd48d8861b..0e2f78979a 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -1357,9 +1357,22 @@ uint32_t yang_get_list_elements_count(const struct lyd_node *node) } while (node); return count; } +int yang_get_key_pred_strlen(const struct lysc_node *snode, const struct yang_list_keys *keys) +{ + const struct lysc_node_leaf *skey; + size_t len = 0; + size_t i = 0; + + LY_FOR_KEYS (snode, skey) { + /* [%s='%s'] */ + len += 5 + strlen(skey->name) + strlen(keys->key[i]); + i++; + } + return len; +} -int yang_get_key_preds(char *s, const struct lysc_node *snode, - struct yang_list_keys *keys, ssize_t space) +int yang_get_key_preds(char *s, const struct lysc_node *snode, const struct yang_list_keys *keys, + ssize_t space) { const struct lysc_node_leaf *skey; ssize_t len2, len = 0; diff --git a/lib/yang.h b/lib/yang.h index 748f089037..afad0023ad 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -879,7 +879,11 @@ bool yang_is_last_level_dnode(const struct lyd_node *dnode); /* Create a YANG predicate string based on the keys */ extern int yang_get_key_preds(char *s, const struct lysc_node *snode, - struct yang_list_keys *keys, ssize_t space); + const struct yang_list_keys *keys, ssize_t space); + +/* Get the length of the predicate string based on the keys */ +extern int yang_get_key_pred_strlen(const struct lysc_node *snode, + const struct yang_list_keys *keys); /* Get YANG keys from an existing dnode */ extern int yang_get_node_keys(struct lyd_node *node, struct yang_list_keys *keys); -- cgit v1.2.3