segv on multiple keys
This commit is contained in:
parent
e61a4dc7eb
commit
1fe7d916f4
2 changed files with 28 additions and 20 deletions
|
|
@ -144,8 +144,8 @@ expand_dbvar(void *h,
|
||||||
}
|
}
|
||||||
api_path_fmt = cv_string_get(cv);
|
api_path_fmt = cv_string_get(cv);
|
||||||
/* api_path_fmt = /interface/%s/address/%s
|
/* api_path_fmt = /interface/%s/address/%s
|
||||||
--> ^/interface/eth0/address/.*$
|
api_path: --> /interface/eth0/address/.*
|
||||||
--> /interface/[name="eth0"]/address
|
xpath: --> /interface/[name="eth0"]/address
|
||||||
*/
|
*/
|
||||||
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
|
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -2425,8 +2425,10 @@ api_path2xpath_cvv(cvec *api_path,
|
||||||
yang_stmt *y = NULL;
|
yang_stmt *y = NULL;
|
||||||
yang_stmt *ymod = NULL;
|
yang_stmt *ymod = NULL;
|
||||||
char *val;
|
char *val;
|
||||||
char *v;
|
|
||||||
cg_var *cvi;
|
cg_var *cvi;
|
||||||
|
char **valvec = NULL;
|
||||||
|
int vi;
|
||||||
|
int nvalvec;
|
||||||
|
|
||||||
for (i=offset; i<cvec_len(api_path); i++){
|
for (i=offset; i<cvec_len(api_path); i++){
|
||||||
cv = cvec_i(api_path, i);
|
cv = cvec_i(api_path, i);
|
||||||
|
|
@ -2457,20 +2459,22 @@ api_path2xpath_cvv(cvec *api_path,
|
||||||
goto done;
|
goto done;
|
||||||
switch (yang_keyword_get(y)){
|
switch (yang_keyword_get(y)){
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
v = val;
|
/* Transform value "a,b,c" to "a" "b" "c" (nvalvec=3)
|
||||||
while((v=index(v, ',')) != NULL){
|
* Note that vnr can be < length of cvk, due to empty or unset values
|
||||||
*v = '\0';
|
*/
|
||||||
v++;
|
if (valvec){ /* loop, valvec may have been used before */
|
||||||
|
free(valvec);
|
||||||
|
valvec = NULL;
|
||||||
}
|
}
|
||||||
|
if ((valvec = clicon_strsep(val, ",", &nvalvec)) == NULL)
|
||||||
|
goto done;
|
||||||
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
||||||
cvi = NULL;
|
cvi = NULL;
|
||||||
/* Iterate over individual yang keys */
|
/* Iterate over individual yang keys */
|
||||||
cprintf(xpath, "/%s", name);
|
cprintf(xpath, "/%s", name);
|
||||||
v = val;
|
vi = 0;
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL){
|
while ((cvi = cvec_each(cvk, cvi)) != NULL && vi<nvalvec)
|
||||||
cprintf(xpath, "[%s='%s']", cv_string_get(cvi), v);
|
cprintf(xpath, "[%s='%s']", cv_string_get(cvi), valvec[vi++]);
|
||||||
v += strlen(v)+1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Y_LEAF_LIST: /* XXX: LOOP? */
|
case Y_LEAF_LIST: /* XXX: LOOP? */
|
||||||
cprintf(xpath, "/%s", name);
|
cprintf(xpath, "/%s", name);
|
||||||
|
|
@ -2502,6 +2506,8 @@ api_path2xpath_cvv(cvec *api_path,
|
||||||
*namespace = yang_find_mynamespace(ymod);
|
*namespace = yang_find_mynamespace(ymod);
|
||||||
retval = 1; /* OK */
|
retval = 1; /* OK */
|
||||||
done:
|
done:
|
||||||
|
if (valvec)
|
||||||
|
free(valvec);
|
||||||
if (prefix)
|
if (prefix)
|
||||||
free(prefix);
|
free(prefix);
|
||||||
if (name)
|
if (name)
|
||||||
|
|
@ -2595,7 +2601,6 @@ api_path2xml_vec(char **vec,
|
||||||
yang_stmt **ypathp)
|
yang_stmt **ypathp)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int j;
|
|
||||||
char *nodeid;
|
char *nodeid;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
|
|
@ -2606,9 +2611,9 @@ api_path2xml_vec(char **vec,
|
||||||
cvec *cvk = NULL; /* vector of index keys */
|
cvec *cvk = NULL; /* vector of index keys */
|
||||||
cg_var *cvi;
|
cg_var *cvi;
|
||||||
char *keyname;
|
char *keyname;
|
||||||
char *val2;
|
|
||||||
char **valvec = NULL;
|
char **valvec = NULL;
|
||||||
int nvalvec;
|
int nvalvec;
|
||||||
|
int vi;
|
||||||
cxobj *x = NULL;
|
cxobj *x = NULL;
|
||||||
yang_stmt *y = NULL;
|
yang_stmt *y = NULL;
|
||||||
yang_stmt *ymod;
|
yang_stmt *ymod;
|
||||||
|
|
@ -2669,7 +2674,7 @@ api_path2xml_vec(char **vec,
|
||||||
break;
|
break;
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
||||||
if (valvec){
|
if (valvec){ /* loop, valvec may have been used before */
|
||||||
free(valvec);
|
free(valvec);
|
||||||
valvec = NULL;
|
valvec = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -2680,6 +2685,9 @@ api_path2xml_vec(char **vec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
/* Transform restval "a,b,c" to "a" "b" "c" (nvalvec=3)
|
||||||
|
* Note that vnr can be < length of cvk, due to empty or unset values
|
||||||
|
*/
|
||||||
if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL)
|
if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((nvalvec != cvec_len(cvk)) && strict){
|
if ((nvalvec != cvec_len(cvk)) && strict){
|
||||||
|
|
@ -2692,9 +2700,9 @@ api_path2xml_vec(char **vec,
|
||||||
if ((x = xml_new(name, x0, y)) == NULL)
|
if ((x = xml_new(name, x0, y)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
xml_type_set(x, CX_ELMNT);
|
xml_type_set(x, CX_ELMNT);
|
||||||
j = 0;
|
vi = 0;
|
||||||
/* Create keys */
|
/* Create keys */
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL) {
|
while ((cvi = cvec_each(cvk, cvi)) != NULL){
|
||||||
keyname = cv_string_get(cvi);
|
keyname = cv_string_get(cvi);
|
||||||
if ((ykey = yang_find(y, Y_LEAF, keyname)) == NULL){
|
if ((ykey = yang_find(y, Y_LEAF, keyname)) == NULL){
|
||||||
clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"",
|
clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"",
|
||||||
|
|
@ -2707,9 +2715,9 @@ api_path2xml_vec(char **vec,
|
||||||
if ((xb = xml_new("body", xn, NULL)) == NULL)
|
if ((xb = xml_new("body", xn, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
xml_type_set(xb, CX_BODY);
|
xml_type_set(xb, CX_BODY);
|
||||||
val2 = valvec?valvec[j++]:NULL;
|
if (vi < nvalvec)
|
||||||
if (xml_value_set(xb, val2) <0)
|
if (xml_value_set(xb, valvec[vi++]) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: /* eg Y_CONTAINER, Y_LEAF */
|
default: /* eg Y_CONTAINER, Y_LEAF */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue