From 2dcc14a0db6ff5df7a707b6b57d044a7fd56b827 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 9 Nov 2021 20:02:40 +0100 Subject: [PATCH] Added error handling in yang_path_arg triggered by no filter in get paginated Fixed cornercase of restconf error return when no body Fixed cornercase when exactly / given as xpath Better error message when YANG not found: added which YANG file imports it --- apps/backend/backend_get.c | 2 +- apps/backend/clixon_backend_plugin.h | 2 +- apps/backend/clixon_backend_transaction.c | 1 - apps/restconf/restconf_nghttp2.c | 2 +- lib/src/clixon_xpath.c | 4 ++++ lib/src/clixon_xpath_yang.c | 14 +++++++++++-- lib/src/clixon_yang_parse_lib.c | 25 ++++++++++++++++------- test/nacm.sh | 1 + test/test_augment.sh | 2 +- 9 files changed, 39 insertions(+), 14 deletions(-) diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index b9bf3384..c24b44ec 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -467,7 +467,7 @@ get_list_pagination(clicon_handle h, #endif /* Check if list/leaf-list */ - if (yang_path_arg(yspec, xpath, &ylist) < 0) + if (yang_path_arg(yspec, xpath?xpath:"/", &ylist) < 0) goto done; if (ylist == NULL){ if ((cbmsg = cbuf_new()) == NULL){ diff --git a/apps/backend/clixon_backend_plugin.h b/apps/backend/clixon_backend_plugin.h index f88bb41f..04e1ba31 100644 --- a/apps/backend/clixon_backend_plugin.h +++ b/apps/backend/clixon_backend_plugin.h @@ -84,7 +84,7 @@ typedef struct { */ typedef struct { uint32_t pd_offset; /* Start of pagination interval */ - uint32_t pd_limit; /* Number of elemenents (limit) */ + uint32_t pd_limit; /* Number of elements (limit) */ int pd_locked; /* Running datastore is locked by this caller */ cxobj *pd_xstate; /* Returned xml state tree */ } pagination_data_t; diff --git a/apps/backend/clixon_backend_transaction.c b/apps/backend/clixon_backend_transaction.c index 0a7889ce..a43ddad5 100644 --- a/apps/backend/clixon_backend_transaction.c +++ b/apps/backend/clixon_backend_transaction.c @@ -286,7 +286,6 @@ transaction_log(clicon_handle h, return 0; } - /*! Get pagination data: offset parameter * * @param[in] pd Pagination userdata diff --git a/apps/restconf/restconf_nghttp2.c b/apps/restconf/restconf_nghttp2.c index 92f65dd3..2b5768c9 100644 --- a/apps/restconf/restconf_nghttp2.c +++ b/apps/restconf/restconf_nghttp2.c @@ -487,7 +487,7 @@ http2_exec(restconf_conn *rc, * (Successful) response to a CONNECT request (Section 4.3.6 of * [RFC7231]). */ - if (sd->sd_code != 204 && sd->sd_code > 199) + if (sd->sd_code != 204 && sd->sd_code > 199 && sd->sd_body_len) if (restconf_reply_header(sd, "Content-Length", "%zu", sd->sd_body_len) < 0) goto done; if (sd->sd_code){ diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index baa655f0..a79592c2 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -526,6 +526,10 @@ xpath_parse(const char *xpath, clixon_xpath_yacc xpy = {0,}; cbuf *cb = NULL; + if (xpath == NULL){ + clicon_err(OE_XML, EINVAL, "XPath is NULL"); + goto done; + } xpy.xpy_parse_string = xpath; xpy.xpy_name = "xpath parser"; xpy.xpy_linenum = 1; diff --git a/lib/src/clixon_xpath_yang.c b/lib/src/clixon_xpath_yang.c index 4aafb2c8..18dd5fde 100644 --- a/lib/src/clixon_xpath_yang.c +++ b/lib/src/clixon_xpath_yang.c @@ -397,8 +397,14 @@ xp_yang_eval(xp_yang_ctx *xy, } } if (xy0 == NULL && xy1 == NULL && xy2 == NULL){ - clicon_err(OE_XML, EFAULT, "Internal error: no result produced"); - goto done; + if (xptree->xs_type == XP_ABSPATH){ + if ((*xyr = xy_dup(xy)) == NULL) + goto done; + } + else { + clicon_err(OE_XML, EFAULT, "Internal error: no result produced"); + goto done; + } } if (xy2){ *xyr = xy2; @@ -460,6 +466,10 @@ yang_path_arg(yang_stmt *ys, xp_yang_ctx *xyr = NULL; xp_yang_ctx *xy = NULL; + if (path_arg == NULL){ + clicon_err(OE_XML, EINVAL, "path-arg is NULL"); + goto done; + } if (xpath_parse(path_arg, &xptree) < 0) goto done; if ((xy = xy_dup(NULL)) == NULL) diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index 1f634bfd..f8c7fea7 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -1035,6 +1035,7 @@ yang_parse_filename(const char *filename, * @param[in] module Module name * @param[in] revision Revision (or NULL) * @param[in] yspec Yang statement + * @param[in] origname Name of yang module triggering this parsing, for logging * @retval 0 OK * @retval -1 Error * @@ -1044,7 +1045,8 @@ static yang_stmt * yang_parse_module(clicon_handle h, const char *module, const char *revision, - yang_stmt *yspec) + yang_stmt *yspec, + char *origname) { cbuf *fbuf = NULL; char *filename; @@ -1053,20 +1055,27 @@ yang_parse_module(clicon_handle h, yang_stmt *yrev; /* yang revision */ uint32_t revf = 0; /* revision in filename */ uint32_t revm = 0; /* revision in parsed new module (should be same as revf) */ + cbuf *cb = NULL; if ((fbuf = cbuf_new()) == NULL){ - clicon_err(OE_YANG, errno, "cbuf_new"); + clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } /* Match a yang file with or without revision in yang-dir list */ if ((nr = yang_parse_find_match(h, module, revision, &revf, fbuf)) < 0) goto done; if (nr == 0){ + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + cprintf(cb, "%s", module); if (revision) - clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s@%s\" in the list of CLICON_YANG_DIRs", - module, revision); + cprintf(cb, "@%s", revision); + if (origname) + clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs when loading %s.yang", cbuf_get(cb), origname); else - clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs", module); + clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs", cbuf_get(cb)); goto done; } filename = cbuf_get(fbuf); @@ -1099,6 +1108,8 @@ yang_parse_module(clicon_handle h, goto done; } done: + if (cb) + cbuf_free(cb); if (fbuf) cbuf_free(fbuf); return ymod; /* top-level (sub)module */ @@ -1149,7 +1160,7 @@ yang_parse_recurse(clicon_handle h, keyw==Y_IMPORT?Y_MODULE:Y_SUBMODULE, submodule) == NULL){ /* recursive call */ - if ((subymod = yang_parse_module(h, submodule, subrevision, ysp)) == NULL) + if ((subymod = yang_parse_module(h, submodule, subrevision, ysp, yang_argument_get(ymod))) == NULL) goto done; /* Sanity check: if submodule, its belongs-to statement shall point to the module */ if (keyw == Y_INCLUDE){ @@ -1581,7 +1592,7 @@ yang_spec_parse_module(clicon_handle h, if (yang_find_module_by_name_revision(yspec, name, revision) != NULL) goto ok; /* Find a yang module and parse it and all its submodules */ - if (yang_parse_module(h, name, revision, yspec) == NULL) + if (yang_parse_module(h, name, revision, yspec, NULL) == NULL) goto done; if (yang_parse_post(h, yspec, modmin) < 0) goto done; diff --git a/test/nacm.sh b/test/nacm.sh index 3952fba2..bb3c11f1 100755 --- a/test/nacm.sh +++ b/test/nacm.sh @@ -46,3 +46,4 @@ NADMIN=$(cat <]]>]]>" "^]]>]]>$" new "netconf get config" -expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "$XML]]>]]>" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "$XML]]>]]>" JSON='{"ietf-interfaces:interfaces":{"example-augment:ports":[{"id":22,"str":"foo"},{"id":44,"str":"bar"}]}}'