Fixed: Search function checked only own not for config false statement, should have checked all ancestors.

This commit is contained in:
Olof hagsand 2020-02-28 14:05:56 +01:00
parent 451adfaf1f
commit 760cdda49a
7 changed files with 142 additions and 100 deletions

View file

@ -611,6 +611,46 @@ xml_search_indexvar_binary_pos(cxobj *x1,
done:
return retval;
}
static int
xml_search_indexvar(cxobj *xp,
cxobj *x1,
int yangi,
int low,
int upper,
char *indexvar,
cxobj ***xvec,
size_t *xlen)
{
int retval = -1;
clixon_xvec *ivec = NULL;
int ilen;
int pos;
int eq = 0;
/* Check if (exactly one) explicit indexes in cvk */
if (xml_search_vector_get(xp, indexvar, &ivec) < 0)
goto done;
if (ivec){
ilen = clixon_xvec_len(ivec);
if ((pos = xml_search_indexvar_binary_pos(x1, indexvar,
ivec, 0,
ilen, ilen, &eq)) < 0)
goto done;
if (eq){ /* Found */
if (cxvec_append(clixon_xvec_i(ivec,pos), xvec, xlen) < 0)
goto done;
/* there may be more? */
if (search_multi_equals_xvec(ivec, x1, yangi, pos,
0, xvec, xlen) < 0)
goto done;
}
}
retval = 0;
done:
return retval;
}
#endif /* XML_EXPLICIT_INDEX */
/*! Find XML child under xp matching x1 using binary search
@ -657,40 +697,13 @@ xml_search_binary(cxobj *xp,
/* Here is right yang order == same yang? */
if (cmp == 0){
#ifdef XML_EXPLICIT_INDEX
if (indexvar != NULL){
clixon_xvec *ivec = NULL;
int ilen;
int pos;
int eq = 0;
/* Check if (exactly one) explicit indexes in cvk */
if (xml_search_vector_get(xp, indexvar, &ivec) < 0)
if (indexvar){
if (xml_search_indexvar(xp, x1, yangi, low, upper, indexvar, xvec, xlen) < 0)
goto done;
if (ivec){
ilen = clixon_xvec_len(ivec);
#if 1 /* XXX This needs some heavy testing */
if ((pos = xml_search_indexvar_binary_pos(x1, indexvar,
ivec, 0,
ilen, ilen, &eq)) < 0)
goto done;
if (eq){ /* Found */
if (cxvec_append(clixon_xvec_i(ivec,pos), xvec, xlen) < 0)
goto done;
/* there may be more? */
if (search_multi_equals_xvec(ivec, x1, yangi, pos,
0, xvec, xlen) < 0)
goto done;
}
#else
if (xml_search_indexvar_binary(x1, indexvar,
ivec, 0,
ilen, ilen,
xvec, xlen) < 0)
goto done;
#endif
}
goto ok;
}
#endif
/* >0 means search upper interval, <0 lower interval, = 0 is equal */
cmp = xml_cmp(x1, xc, 0, skip1, NULL);
if (cmp && !sorted){ /* Ordered by user (if not equal) */
retval = xml_find_keys_notsorted(xp, x1, yangi, mid, skip1, xvec, xlen);
@ -753,7 +766,7 @@ xml_search_yang(cxobj *xp,
if ((xa = xml_child_i(xp, low)) == NULL || xml_type(xa) != CX_ATTR)
break;
/* Find if non-config and if ordered-by-user */
if (yang_config(yc)==0)
if (yang_config_ancestor(yc)==0)
sorted = 0;
else if (yang_keyword_get(yc) == Y_LIST || yang_keyword_get(yc) == Y_LEAF_LIST)
sorted = (yang_find(yc, Y_ORDERED_BY, "user") == NULL);
@ -989,7 +1002,7 @@ xml_insert(cxobj *xp,
if ((xa = xml_child_i(xp, low)) == NULL || xml_type(xa)!=CX_ATTR)
break;
/* Find if non-config and if ordered-by-user */
if (yang_config(y)==0)
if (yang_config_ancestor(y)==0)
userorder = 1;
else if (yang_keyword_get(y) == Y_LIST || yang_keyword_get(y) == Y_LEAF_LIST)
userorder = (yang_find(y, Y_ORDERED_BY, "user") != NULL);
@ -1026,7 +1039,7 @@ xml_sort_verify(cxobj *x0,
yang_stmt *ys;
/* Abort sort if non-config (=state) data */
if ((ys = xml_spec(x0)) != 0 && yang_config(ys)==0){
if ((ys = xml_spec(x0)) != 0 && yang_config_ancestor(ys)==0){
retval = 1;
goto done;
}

View file

@ -249,7 +249,7 @@ xpath_list_optimize_fn(xpath_tree *xt,
if ((yp = xml_spec(xv)) == NULL)
goto ok;
/* or if not config data (state data should not be ordered) */
if (yang_config(yp) == 0)
if (yang_config_ancestor(yp) == 0)
goto ok;
/* Check yang and that only a list with key as index is a special case can do bin search
* That is, ONLY check optimize cases of this type:_x[_y='_z']

View file

@ -2346,11 +2346,10 @@ yang_mandatory(yang_stmt *ys)
}
/*! Return config state of this node
* config statement is default true.
* @note a node with config=false may not have a sub statement where
* config=true. And this function does not check the status of a parent.
* @retval 0 if node has a config sub-statement and it is false
* @retval 1 node has not config sub-statement or it is true
* @param[in] ys Yang statement
* @retval 0 If node has a config sub-statement and it is false
* @retval 1 If node has not config sub-statement or it is true
* @see yang_config_ancestor which also takes ancestors into account, which you should normally do.
*/
int
yang_config(yang_stmt *ys)
@ -2365,6 +2364,26 @@ yang_config(yang_stmt *ys)
return 1;
}
/*! Return config state of this node taking parent into account
*
* config statement is default true.
* @param[in] ys Yang statement
* @retval 0 Node or one of its ancestor has config false
* @retval 1 Neither node nor any of its ancestors has config false
*/
int
yang_config_ancestor(yang_stmt *ys)
{
yang_stmt *yp;
yp = ys;
do {
if (yang_config(yp) == 0)
return 0;
} while((yp = yang_parent_get(yp)) != NULL);
return 1;
}
/*! Given a yang node, translate the argument string to a cv vector
*
* @param[in] ys Yang statement