From 881dd56ee141e3ddeb8e45615c67d7944ad0a8c7 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 10 Apr 2019 17:35:36 +0200 Subject: [PATCH] Empty leaf values, eg are now checked at vlidation. --- CHANGELOG.md | 3 +++ lib/src/clixon_xml_map.c | 24 ++++++++++++++++++------ lib/src/clixon_yang_type.c | 33 ++++++++++++++++++++------------- test/test_stream.sh | 2 +- test/test_type.sh | 14 ++++++++++++++ 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ced2f8e..124100f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,6 +92,9 @@ ``` ### Minor changes +* Empty leaf values, eg are now checked at vlidation. + * Empty values were skipped in validation. + * They are now checked and invalid for ints, dec64, etc, but are treated as empty string "" for string types. * Optimized validation by making xml_diff work on raw cache tree (not copies) * Added syntactic check for yang status: current, deprecated or obsolete. * Added `xml_wrap` function that adds an XML node above a node as a wrapper diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index ff85a4d2..2c33fa89 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -663,6 +663,7 @@ xml_yang_validate_add(cxobj *xt, char *body; int ret; cxobj *x; + enum cv_type cvtype; /* if not given by argument (overide) use default link and !Node has a config sub-statement and it is false */ @@ -688,17 +689,28 @@ xml_yang_validate_add(cxobj *xt, /* In the union case, value is parsed as generic REST type, * needs to be reparsed when concrete type is selected */ - if ((body = xml_body(xt)) != NULL){ + if ((body = xml_body(xt)) == NULL){ + /* We do not allow ints to be empty. Otherwise NULL strings + * are considered as "" */ + cvtype = cv_type_get(cv); + if (cv_isint(cvtype) || cvtype == CGV_BOOL || cvtype == CGV_DEC64){ + if (netconf_bad_element(cbret, "application", yt->ys_argument, "Invalid NULL value") < 0) + goto done; + goto fail; + } + } + else{ if (cv_parse1(body, cv, &reason) != 1){ if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0) goto done; goto fail; } - if ((ys_cv_validate(cv, yt, &reason)) != 1){ - if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0) - goto done; - goto fail; - } + } + + if ((ys_cv_validate(cv, yt, &reason)) != 1){ + if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0) + goto done; + goto fail; } break; default: diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index 378c9d98..413d4e8e 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -364,7 +364,7 @@ cv_validate1(cg_var *cv, cg_var *cv2; int retval2; yang_stmt *yi = NULL; - char *str; + char *str = NULL; int found; char **vec = NULL; int nvec; @@ -435,8 +435,9 @@ cv_validate1(cg_var *cv, case CGV_STRING: case CGV_REST: if ((str = cv_string_get(cv)) == NULL) - break; - uu = strlen(str); + uu = 0; /* equal no string with empty string for range check */ + else + uu = strlen(str); rets = range_check(uu, cv1, cv2, uint64); break; default: @@ -470,29 +471,34 @@ cv_validate1(cg_var *cv, case CGV_STRING: case CGV_REST: str = cv_string_get(cv); + /* Note, if there is no value, eg , str is NULL. + */ if (restype){ if (strcmp(restype, "enumeration") == 0){ found = 0; yi = NULL; - while ((yi = yn_each(yrestype, yi)) != NULL){ - if (yi->ys_keyword != Y_ENUM) - continue; - if (strcmp(yi->ys_argument, str) == 0){ - found++; - break; + if (str != NULL) + while ((yi = yn_each(yrestype, yi)) != NULL){ + if (yi->ys_keyword != Y_ENUM) + continue; + if (strcmp(yi->ys_argument, str) == 0){ + found++; + break; + } } - } if (!found){ if (reason) *reason = cligen_reason("'%s' does not match enumeration", str); goto fail; } } - if (strcmp(restype, "bits") == 0){ + if (strcmp(restype, "bits") == 0 && str != NULL){ /* The lexical representation of the bits type is a space-separated list * of the names of the bits that are set. A zero-length string thus * represents a value where no bits are set. */ + + nvec = 0; if ((vec = clicon_strsep(str, " \t", &nvec)) == NULL) goto done; for (i=0; iEXAMPLE]]>]]>' '^]]>]]>20' $NCWAIT new "netconf subscription with empty startTime" -expectwait "$clixon_netconf -qf $cfg -y $fyang" 'EXAMPLE]]>]]>' '^]]>]]>20' $NCWAIT +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'EXAMPLE]]>]]>' '^applicationbad-elementstartTimeerrorregexp match fail:' new "netconf EXAMPLE subscription with simple filter" expectwait "$clixon_netconf -qf $cfg -y $fyang" 'EXAMPLE]]>]]>' '^]]>]]>20' $NCWAIT diff --git a/test/test_type.sh b/test/test_type.sh index 132e6a59..4a4c9bc3 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -123,6 +123,9 @@ module example{ enum down; } } + leaf num0 { + type int32; + } leaf num1 { type int32 { range "1"; @@ -315,6 +318,17 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ']]>]]>' "^]]>]]>$" + +new "netconf validate no value wrong" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" 'applicationbad-elementnum0errorInvalid NULL value]]>]]>' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + #-------- num1 single range (1) new "cli range test num1 1 OK"