* Augment target node check strict, instead of printing a warning, it will terminate with error.

* Fixed: [Augment that reference a submodule as target node fails #178](https://github.com/clicon/clixon/issues/178)
* Fixed a memory error that was reported in slack by Pawel Maslanka
  * The crash printout was: `realloc(): invalid next size Aborted`
This commit is contained in:
Olof hagsand 2021-02-19 15:46:55 +01:00
parent 108f94cfad
commit 9840e248c6
12 changed files with 227 additions and 130 deletions

View file

@ -97,6 +97,7 @@ static int yang_search_index_extension(clicon_handle h, yang_stmt *yext, yang_st
* Here is also the place where doc on some types store variables (cv)
*/
static const map_str2int ykmap[] = {
{"action", Y_ACTION},
{"anydata", Y_ANYDATA},
{"anyxml", Y_ANYXML},
{"argument", Y_ARGUMENT},
@ -497,12 +498,15 @@ ys_prune(yang_stmt *yp,
if (i >= yp->ys_len)
goto done;
size = (yp->ys_len - i - 1)*sizeof(struct yang_stmt *);
yc = yp->ys_stmt[i];
memmove(&yp->ys_stmt[i],
&yp->ys_stmt[i+1],
size);
yp->ys_stmt[yp->ys_len--] = NULL;
if (i < yp->ys_len - 1){
size = (yp->ys_len - i - 1)*sizeof(struct yang_stmt *);
memmove(&yp->ys_stmt[i],
&yp->ys_stmt[i+1],
size);
}
yp->ys_len--;
yp->ys_stmt[yp->ys_len] = NULL;
done:
return yc;
}
@ -931,10 +935,16 @@ yang_find_schemanode(yang_stmt *yn,
for (i=0; i<yn->ys_len; i++){
ys = yn->ys_stmt[i];
if (ys->ys_keyword == Y_CHOICE){ /* Look for its children */
if (yang_keyword_get(ys) == Y_CHOICE){
/* First check choice itself */
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0){
ysmatch = ys;
goto match;
}
/* Then look for its children (case) */
for (j=0; j<ys->ys_len; j++){
yc = ys->ys_stmt[j];
if (yc->ys_keyword == Y_CASE) /* Look for its children */
if (yang_keyword_get(yc) == Y_CASE) /* Look for its children */
ysmatch = yang_find_schemanode(yc, argument);
else
if (yang_schemanode(yc)){
@ -950,7 +960,9 @@ yang_find_schemanode(yang_stmt *yn,
} /* Y_CHOICE */
else
if (yang_schemanode(ys)){
if (argument == NULL)
if (yang_keyword_get(ys) == Y_INPUT || yang_keyword_get(ys) == Y_OUTPUT)
ysmatch = ys;
else if (argument == NULL)
ysmatch = ys;
else
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0)
@ -1070,7 +1082,7 @@ yang_find_prefix_by_namespace(yang_stmt *ys,
yang_stmt *yimport;
yang_stmt *yprefix;
clicon_debug(1, "%s", __FUNCTION__);
clicon_debug(2, "%s", __FUNCTION__);
/* First check if namespace is my own module */
myns = yang_find_mynamespace(ys);
if (strcmp(myns, ns) == 0){
@ -2559,7 +2571,6 @@ schema_nodeid_iterate(yang_stmt *yn,
char *prefix; /* node-identifier = [prefix ":"] identifier */
char *id;
yang_stmt *ys;
yang_stmt *ym2;
yang_stmt *yp;
cg_var *cv;
char *ns;
@ -2586,34 +2597,28 @@ schema_nodeid_iterate(yang_stmt *yn,
clicon_err(OE_YANG, EFAULT, "No module for namespace: %s", ns);
goto done;
}
/* Iterate over children of current node to get a match
* XXX namespace?????
*/
ys = NULL;
while ((ys = yn_each(yp, ys)) != NULL) {
if (!yang_schemanode(ys))
continue;
/* some keys dont have arguments, match on key */
if (ys->ys_keyword == Y_INPUT || ys->ys_keyword == Y_OUTPUT){
if (strcmp(id, yang_key2str(ys->ys_keyword)) == 0){
break;
}
}
else {
if (ys->ys_argument && strcmp(id, ys->ys_argument) == 0){
/* Also check for right prefix/module */
ym2 = ys->ys_mymodule?ys->ys_mymodule:ys_module(ys);
if (ym2 == ymod)
break;
}
}
} /* while ys */
ys = yang_find_schemanode(yp, id);
/* Special case: if rpc/action, an empty input/output may need to be created, it is optional but may
* still be referenced.
* XXX: maybe input/output should always be created when rpc/action is created?
*/
if (ys == NULL &&
(yang_keyword_get(yp) == Y_RPC || yang_keyword_get(yp) == Y_ACTION) &&
(strcmp(id, "input") == 0 || strcmp(id, "output") == 0)){
enum rfc_6020 kw;
kw = clicon_str2int(ykmap, id);
/* Add ys as id to yp */
if ((ys = ys_new(kw)) == NULL)
goto done;
if (yn_insert(yp, ys) < 0) /* Insert into hierarchy */
goto done;
}
if (ys == NULL){
clicon_debug(1, "%s: %s not found", __FUNCTION__, id);
goto ok;
}
yp = ys;
yp = ys; /* ys is matched */
} /* while cv */
assert(yp && yang_schemanode((yang_stmt*)yp));
*yres = (yang_stmt*)yp;

View file

@ -1791,7 +1791,7 @@ desc_schema_nodeid_str : desc_schema_nodeid
desc_schema_nodeid : node_identifier
{ $$= $1; clicon_debug(3,"descendant-schema-nodeid -> node_identifier"); }
| node_identifier abs_schema_nodeid
{ if (($$=string_del_join($1, " ", $2)) == NULL) _YYERROR("desc_schema_nodeid");clicon_debug(3,"descendant-schema-nodeid -> node_identifier abs_schema_nodeid"); }
{ if (($$=string_del_join($1, "", $2)) == NULL) _YYERROR("desc_schema_nodeid");clicon_debug(3,"descendant-schema-nodeid -> node_identifier abs_schema_nodeid"); }
;
identifier_str : '"' IDENTIFIER '"' { $$ = $2;

View file

@ -238,12 +238,18 @@ yang_augment_node(yang_stmt *ys)
goto done;
if (ytarget == NULL){
#if 0 /* Lots of yang models fail here */
#if 1
/* Fail with fatal error if augment target not found
* This is "correct"
*/
clicon_err(OE_YANG, 0, "Augment failed in module %s: target node %s not found",
yang_argument_get(ys_module(ys)),
schema_nodeid);
goto done;
#else
/* Log a warning and proceed if augment target not found
* This may be necessary with some broken models
*/
clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: target node %s not found",
yang_argument_get(ys_module(ys)),
schema_nodeid);
@ -276,7 +282,7 @@ yang_augment_node(yang_stmt *ys)
if (childkey != Y_ACTION && childkey != Y_NOTIFICATION && childkey != Y_UNKNOWN &&
childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST &&
childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE){
clicon_log(LOG_WARNING, "Warning: A Augment failed in module %s: node %s %d cannot be added to target node %s",
clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s",
yang_argument_get(ys_module(ys)),
yang_key2str(childkey),
childkey,
@ -295,7 +301,7 @@ yang_augment_node(yang_stmt *ys)
if (childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST &&
childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE &&
childkey != Y_UNKNOWN){
clicon_log(LOG_WARNING, "Warning: B Augment failed in module %s: node %s %d cannot be added to target node %s",
clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s",
yang_argument_get(ys_module(ys)),
yang_key2str(childkey),
childkey,
@ -316,7 +322,7 @@ yang_augment_node(yang_stmt *ys)
childkey != Y_CHOICE && childkey != Y_CONTAINER && childkey != Y_LEAF &&
childkey != Y_LIST && childkey != Y_LEAF_LIST){
clicon_log(LOG_WARNING, "Warning: C Augment failed in module %s: node %s %d cannot be added to target node %s",
clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s",
yang_argument_get(ys_module(ys)),
yang_key2str(childkey),
childkey,