]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: nb: fix bug with oper-state query on list data
authorChristian Hopps <chopps@labn.net>
Wed, 26 Feb 2025 13:34:59 +0000 (13:34 +0000)
committerChristian Hopps <chopps@labn.net>
Wed, 26 Feb 2025 13:38:42 +0000 (13:38 +0000)
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 <chopps@labn.net>
lib/northbound_oper.c
lib/yang.c
lib/yang.h

index 5c2d3ed8c8496da26c17c12ca7b19925a7a17874..ad495b6f9c33fab00c4bc5c1a4051693c44d1e9b 100644 (file)
@@ -1723,8 +1723,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?) */
index 955f49b00c023abdf1aff5e25af46b1da9a3a72d..a57b24763454bf63c92eea8cb3ba2fab92030fa8 100644 (file)
@@ -1357,9 +1357,21 @@ 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, const 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;
index afd3d5e0fc2f0b6132bd1e67b3f45b625be6d093..3877a421c51497372e7a0496fa09f3e96978d3ae 100644 (file)
@@ -884,6 +884,10 @@ bool yang_is_last_level_dnode(const struct lyd_node *dnode);
 extern int yang_get_key_preds(char *s, const struct lysc_node *snode,
                              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);