Skip to content

Commit 13bdd03

Browse files
committed
xpath BUGFIX inheriting modules for unprefixed nodes
Reverts some previous changes and now JSON format is used for user XPaths when unprefixed nodes match every module and instance-ids when the moduloe should be inherited but is not (should not matter).
1 parent 08a2b06 commit 13bdd03

File tree

1 file changed

+52
-51
lines changed

1 file changed

+52
-51
lines changed

src/xpath.c

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static LY_ERR reparse_or_expr(const struct ly_ctx *ctx, struct lyxp_expr *exp, u
4848
static LY_ERR eval_expr_select(const struct lyxp_expr *exp, uint32_t *tok_idx, enum lyxp_expr_type etype,
4949
struct lyxp_set *set, uint32_t options);
5050
static LY_ERR moveto_resolve_model(const char **qname, uint32_t *qname_len, const struct lyxp_set *set,
51-
const struct lys_module **moveto_mod);
51+
const struct lysc_node *ctx_scnode, const struct lys_module **moveto_mod);
5252
static LY_ERR moveto_axis_node_next(const struct lyd_node **iter, enum lyxp_node_type *iter_type,
5353
const struct lyd_node *node, enum lyxp_node_type node_type, enum lyxp_axis axis, struct lyxp_set *set);
5454
static LY_ERR moveto_node(struct lyxp_set *set, const struct lys_module *moveto_mod, const char *ncname,
@@ -4112,33 +4112,11 @@ static LY_ERR
41124112
xpath_derived_ident_module(const char **qname, uint32_t *qname_len, const struct lyxp_set *set,
41134113
const struct lys_module **mod)
41144114
{
4115-
LY_CHECK_RET(moveto_resolve_model(qname, qname_len, set, mod));
4116-
if (*mod) {
4117-
/* prefixed identity */
4118-
return LY_SUCCESS;
4119-
}
4120-
4121-
switch (set->format) {
4122-
case LY_VALUE_SCHEMA:
4123-
case LY_VALUE_SCHEMA_RESOLVED:
4124-
/* current module */
4115+
LY_CHECK_RET(moveto_resolve_model(qname, qname_len, set, set->cur_node ? set->cur_node->schema : NULL, mod));
4116+
if (!*mod) {
4117+
/* unprefixed JSON identity */
4118+
assert(set->format == LY_VALUE_JSON);
41254119
*mod = set->cur_mod;
4126-
break;
4127-
case LY_VALUE_CANON:
4128-
case LY_VALUE_JSON:
4129-
case LY_VALUE_LYB:
4130-
case LY_VALUE_STR_NS:
4131-
/* inherit parent (context node) module */
4132-
if (set->cur_scnode) {
4133-
*mod = set->cur_scnode->module;
4134-
} else {
4135-
*mod = set->cur_mod;
4136-
}
4137-
break;
4138-
case LY_VALUE_XML:
4139-
/* all identifiers need to be prefixed */
4140-
LOGVAL(set->ctx, LYVE_DATA, "Non-prefixed identity \"%.*s\" in XML xpath found.", (int)*qname_len, *qname);
4141-
return LY_EVALID;
41424120
}
41434121

41444122
return LY_SUCCESS;
@@ -5673,47 +5651,69 @@ xpath_pi_text(struct lyxp_set *set, enum lyxp_axis axis, uint32_t options)
56735651
}
56745652

56755653
/**
5676-
* @brief Skip prefix and return corresponding model if there is a prefix. Logs directly.
5654+
* @brief Skip prefix and return corresponding model. Logs directly.
56775655
*
56785656
* XPath @p set is expected to be a (sc)node set!
56795657
*
56805658
* @param[in,out] qname Qualified node name. If includes prefix, it is skipped.
56815659
* @param[in,out] qname_len Length of @p qname, is updated accordingly.
56825660
* @param[in] set Set with general XPath context.
5661+
* @param[in] ctx_scnode Current context schema node (parent).
56835662
* @param[out] moveto_mod Expected module of a matching node.
56845663
* @return LY_ERR
56855664
*/
56865665
static LY_ERR
56875666
moveto_resolve_model(const char **qname, uint32_t *qname_len, const struct lyxp_set *set,
5688-
const struct lys_module **moveto_mod)
5667+
const struct lysc_node *ctx_scnode, const struct lys_module **moveto_mod)
56895668
{
56905669
const struct lys_module *mod = NULL;
56915670
const char *ptr;
56925671
size_t pref_len;
56935672

56945673
assert((set->type == LYXP_SET_NODE_SET) || (set->type == LYXP_SET_SCNODE_SET));
56955674

5696-
*moveto_mod = NULL;
5675+
if ((ptr = ly_strnchr(*qname, ':', *qname_len))) {
5676+
/* specific module */
5677+
pref_len = ptr - *qname;
5678+
mod = ly_resolve_prefix(set->ctx, *qname, pref_len, set->format, set->prefix_data);
56975679

5698-
ptr = ly_strnchr(*qname, ':', *qname_len);
5699-
if (!ptr) {
5700-
/* no prefix */
5701-
return LY_SUCCESS;
5702-
}
5703-
5704-
/* specific module */
5705-
pref_len = ptr - *qname;
5706-
mod = ly_resolve_prefix(set->ctx, *qname, pref_len, set->format, set->prefix_data);
5680+
/* check for errors and non-implemented modules, as they are not valid */
5681+
if (!mod || !mod->implemented) {
5682+
LOGVAL(set->ctx, LY_VCODE_XP_INMOD, (int)pref_len, *qname);
5683+
return LY_EVALID;
5684+
}
57075685

5708-
/* check for errors and non-implemented modules, as they are not valid */
5709-
if (!mod || !mod->implemented) {
5710-
LOGVAL(set->ctx, LY_VCODE_XP_INMOD, (int)pref_len, *qname);
5711-
return LY_EVALID;
5686+
*qname += pref_len + 1;
5687+
*qname_len -= pref_len + 1;
5688+
} else if (((*qname)[0] == '*') && (*qname_len == 1)) {
5689+
/* all modules - special case */
5690+
mod = NULL;
5691+
} else {
5692+
switch (set->format) {
5693+
case LY_VALUE_SCHEMA:
5694+
case LY_VALUE_SCHEMA_RESOLVED:
5695+
/* current module */
5696+
mod = set->cur_mod;
5697+
break;
5698+
case LY_VALUE_CANON:
5699+
case LY_VALUE_JSON:
5700+
case LY_VALUE_LYB:
5701+
case LY_VALUE_STR_NS:
5702+
/* inherit parent (context node) module */
5703+
if (ctx_scnode) {
5704+
mod = ctx_scnode->module;
5705+
} else {
5706+
/* JSON XPath is our own format (except for identityref), which supports node names matching all the modules */
5707+
mod = NULL;
5708+
}
5709+
break;
5710+
case LY_VALUE_XML:
5711+
/* all nodes need to be prefixed */
5712+
LOGVAL(set->ctx, LYVE_DATA, "Non-prefixed node \"%.*s\" in XML xpath found.", (int)*qname_len, *qname);
5713+
return LY_EVALID;
5714+
}
57125715
}
57135716

5714-
*qname += pref_len + 1;
5715-
*qname_len -= pref_len + 1;
5716-
57175717
*moveto_mod = mod;
57185718
return LY_SUCCESS;
57195719
}
@@ -7683,20 +7683,21 @@ eval_literal(const struct lyxp_expr *exp, uint32_t *tok_idx, struct lyxp_set *se
76837683
*
76847684
* @param[in] nametest Nametest to check.
76857685
* @param[in] len Length of @p nametest.
7686+
* @param[in] ctx_scnode Found schema node as the context for the predicate.
76867687
* @param[in] set Context set.
76877688
* @param[in] key Expected key node.
76887689
* @return LY_SUCCESS on success,
76897690
* @return LY_ENOT if a predicate could not be compiled.
76907691
* @return LY_ERR on any error.
76917692
*/
76927693
static LY_ERR
7693-
eval_name_test_try_compile_predicate_key(const char *nametest, uint32_t len, const struct lyxp_set *set,
7694-
const struct lysc_node *key)
7694+
eval_name_test_try_compile_predicate_key(const char *nametest, uint32_t len, const struct lysc_node *ctx_scnode,
7695+
const struct lyxp_set *set, const struct lysc_node *key)
76957696
{
76967697
const struct lys_module *mod;
76977698

76987699
/* prefix (module) */
7699-
LY_CHECK_RET(moveto_resolve_model(&nametest, &len, set, &mod));
7700+
LY_CHECK_RET(moveto_resolve_model(&nametest, &len, set, ctx_scnode, &mod));
77007701
if (mod && (mod != key->module)) {
77017702
return LY_ENOT;
77027703
}
@@ -7855,7 +7856,7 @@ eval_name_test_try_compile_predicates(const struct lyxp_expr *exp, uint32_t *tok
78557856

78567857
/* check key */
78577858
LY_CHECK_GOTO(rc = eval_name_test_try_compile_predicate_key(exp->expr + exp->tok_pos[e_idx],
7858-
exp->tok_len[e_idx], set, key), cleanup);
7859+
exp->tok_len[e_idx], ctx_scnode, set, key), cleanup);
78597860

78607861
++e_idx;
78617862

@@ -8155,7 +8156,7 @@ eval_name_test_with_predicate(const struct lyxp_expr *exp, uint32_t *tok_idx, en
81558156
}
81568157

81578158
/* parse (and skip) module name */
8158-
rc = moveto_resolve_model(&ncname, &ncname_len, set, &moveto_mod);
8159+
rc = moveto_resolve_model(&ncname, &ncname_len, set, NULL, &moveto_mod);
81598160
LY_CHECK_GOTO(rc, cleanup);
81608161

81618162
if ((ncname[0] == '*') && (ncname_len == 1)) {

0 commit comments

Comments
 (0)