]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: nb: fix bug with oper-state query on list data 18302/head
authorChristian Hopps <chopps@labn.net>
Wed, 26 Feb 2025 13:34:59 +0000 (13:34 +0000)
committerChristian Hopps <chopps@labn.net>
Mon, 3 Mar 2025 15:44:33 +0000 (15:44 +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 6a3c21b237866ed819ac6bbd28dff2679ba3e73c..bde222801288b8599ccd0c7093d4407cc22fdc91 100644 (file)
@@ -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?) */
index dd48d8861b7dd83b8dd6d2d057f75064b13a1498..0e2f78979a73d2f2c5ca98d7994e07e563586a1b 100644 (file)
@@ -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;
index 748f089037d03d358ee6c7ce49d94ae47b4e4ac7..afad0023adb2039fd72dc668229280e98b76cdea 100644 (file)
@@ -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);