@@ -3391,293 +3391,6 @@ resolve_data(const struct lys_module *mod, const char *name, int nam_len, struct
33913391 return parents -> count ? EXIT_SUCCESS : EXIT_FAILURE ;
33923392}
33933393
3394- /**
3395- * @brief Resolve (find) a data node. Does not log.
3396- *
3397- * @param[in] mod_name Module name of the data node.
3398- * @param[in] mod_name_len Length of the module name.
3399- * @param[in] name Name of the data node.
3400- * @param[in] nam_len Length of the name.
3401- * @param[in] start Data node to start the search from.
3402- * @param[in,out] parents Resolved nodes. If there are some parents,
3403- * they are replaced (!!) with the resolvents.
3404- *
3405- * @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 otherwise.
3406- */
3407- static int
3408- resolve_data_node (const char * mod_name , int mod_name_len , const char * name , int name_len , struct lyd_node * start ,
3409- struct unres_data * parents )
3410- {
3411- const struct lys_module * mod ;
3412- char * str ;
3413-
3414- assert (start );
3415-
3416- if (mod_name ) {
3417- /* we have mod_name, find appropriate module */
3418- str = strndup (mod_name , mod_name_len );
3419- if (!str ) {
3420- LOGMEM ;
3421- return -1 ;
3422- }
3423- mod = ly_ctx_get_module (start -> schema -> module -> ctx , str , NULL );
3424- free (str );
3425- if (!mod ) {
3426- /* invalid prefix */
3427- return -1 ;
3428- }
3429- } else {
3430- /* no prefix, module is the same as of current node */
3431- mod = lyd_node_module (start );
3432- }
3433-
3434- return resolve_data (mod , name , name_len , start , parents );
3435- }
3436-
3437- /**
3438- * @brief Resolve a path predicate (leafref) in JSON data context. Logs directly
3439- * only specific errors, general no-resolvent error is left to the caller.
3440- *
3441- * @param[in] pred Predicate to use.
3442- * @param[in] node Node from which the predicate is being resolved
3443- * @param[in,out] node_match Nodes satisfying the restriction
3444- * without the predicate. Nodes not
3445- * satisfying the predicate are removed.
3446- * @param[out] parsed Number of characters parsed, negative on error.
3447- *
3448- * @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 on error.
3449- */
3450- static int
3451- resolve_path_predicate_data (const char * pred , struct lyd_node * node , struct unres_data * node_match ,
3452- int * parsed )
3453- {
3454- /* ... /node[source = destination] ... */
3455- struct unres_data source_match , dest_match ;
3456- const char * path_key_expr , * source , * sour_pref , * dest , * dest_pref ;
3457- int pke_len , sour_len , sour_pref_len , dest_len , dest_pref_len , parsed_loc = 0 , pke_parsed = 0 ;
3458- int has_predicate , dest_parent_times , i , rc ;
3459- uint32_t j ;
3460- struct lyd_node_leaf_list * leaf_dst , * leaf_src ;
3461-
3462- source_match .count = 1 ;
3463- source_match .node = malloc (sizeof * source_match .node );
3464- LY_CHECK_ERR_RETURN (!source_match .node , LOGMEM , -1 );
3465-
3466- dest_match .count = 1 ;
3467- dest_match .node = malloc (sizeof * dest_match .node );
3468- LY_CHECK_ERR_RETURN (!dest_match .node , LOGMEM , -1 );
3469-
3470- do {
3471- if ((i = parse_path_predicate (pred , & sour_pref , & sour_pref_len , & source , & sour_len , & path_key_expr ,
3472- & pke_len , & has_predicate )) < 1 ) {
3473- LOGVAL (LYE_INCHAR , LY_VLOG_LYD , node , pred [- i ], & pred [- i ]);
3474- rc = -1 ;
3475- goto error ;
3476- }
3477- parsed_loc += i ;
3478- pred += i ;
3479-
3480- for (j = 0 ; j < node_match -> count ;) {
3481- /* source */
3482- source_match .node [0 ] = node_match -> node [j ];
3483-
3484- /* must be leaf (key of a list) */
3485- if ((rc = resolve_data_node (sour_pref , sour_pref_len , source , sour_len , node_match -> node [j ],
3486- & source_match )) || (source_match .count != 1 ) || (source_match .node [0 ]-> schema -> nodetype != LYS_LEAF )) {
3487- i = 0 ;
3488- goto error ;
3489- }
3490-
3491- /* destination */
3492- dest_match .node [0 ] = node ;
3493- dest_parent_times = 0 ;
3494- if ((i = parse_path_key_expr (path_key_expr , & dest_pref , & dest_pref_len , & dest , & dest_len ,
3495- & dest_parent_times )) < 1 ) {
3496- LOGVAL (LYE_INCHAR , LY_VLOG_LYD , node , path_key_expr [- i ], & path_key_expr [- i ]);
3497- rc = -1 ;
3498- goto error ;
3499- }
3500- pke_parsed = i ;
3501- for (i = 0 ; i < dest_parent_times ; ++ i ) {
3502- dest_match .node [0 ] = dest_match .node [0 ]-> parent ;
3503- if (!dest_match .node [0 ]) {
3504- i = 0 ;
3505- rc = EXIT_FAILURE ;
3506- goto error ;
3507- }
3508- }
3509- while (1 ) {
3510- if ((rc = resolve_data_node (dest_pref , dest_pref_len , dest , dest_len , dest_match .node [0 ],
3511- & dest_match )) || (dest_match .count != 1 )) {
3512- i = 0 ;
3513- goto error ;
3514- }
3515-
3516- if (pke_len == pke_parsed ) {
3517- break ;
3518- }
3519- if ((i = parse_path_key_expr (path_key_expr + pke_parsed , & dest_pref , & dest_pref_len , & dest , & dest_len ,
3520- & dest_parent_times )) < 1 ) {
3521- LOGVAL (LYE_INCHAR , LY_VLOG_LYD , node , path_key_expr [- i ], & path_key_expr [- i ]);
3522- rc = -1 ;
3523- goto error ;
3524- }
3525- pke_parsed += i ;
3526- }
3527-
3528- /* check match between source and destination nodes */
3529- leaf_dst = (struct lyd_node_leaf_list * )dest_match .node [0 ];
3530- while (leaf_dst && leaf_dst -> value_type == LY_TYPE_LEAFREF ) {
3531- leaf_dst = (struct lyd_node_leaf_list * )leaf_dst -> value .leafref ;
3532- }
3533- leaf_src = (struct lyd_node_leaf_list * )source_match .node [0 ];
3534- while (leaf_src && leaf_src -> value_type == LY_TYPE_LEAFREF ) {
3535- leaf_src = (struct lyd_node_leaf_list * )leaf_src -> value .leafref ;
3536- }
3537- if (!leaf_src || !leaf_dst ) {
3538- /* not yet resolved leafrefs */
3539- return EXIT_FAILURE ;
3540- }
3541- if ((leaf_src -> value_type & LY_DATA_TYPE_MASK ) != (leaf_dst -> value_type & LY_DATA_TYPE_MASK )) {
3542- goto remove_leafref ;
3543- }
3544-
3545- if (!ly_strequal (leaf_src -> value_str , leaf_dst -> value_str , 1 )) {
3546- goto remove_leafref ;
3547- }
3548-
3549- /* leafref is ok, continue check with next leafref */
3550- ++ j ;
3551- continue ;
3552-
3553- remove_leafref :
3554- /* does not fulfill conditions, remove leafref record */
3555- unres_data_del (node_match , j );
3556- }
3557- } while (has_predicate );
3558-
3559- free (source_match .node );
3560- free (dest_match .node );
3561- if (parsed ) {
3562- * parsed = parsed_loc ;
3563- }
3564- return EXIT_SUCCESS ;
3565-
3566- error :
3567-
3568- if (source_match .count ) {
3569- free (source_match .node );
3570- }
3571- if (dest_match .count ) {
3572- free (dest_match .node );
3573- }
3574- if (parsed ) {
3575- * parsed = - parsed_loc + i ;
3576- }
3577- return rc ;
3578- }
3579-
3580- /**
3581- * @brief Resolve a path (leafref) in JSON data context. Logs directly.
3582- *
3583- * @param[in] node Leafref data node.
3584- * @param[in] path Path of the leafref.
3585- * @param[out] ret Matching nodes. Expects an empty, but allocated structure.
3586- *
3587- * @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 otherwise.
3588- */
3589- static int
3590- resolve_path_arg_data (struct lyd_node * node , const char * path , struct unres_data * ret )
3591- {
3592- struct lyd_node * data = NULL ;
3593- const char * prefix , * name ;
3594- int pref_len , nam_len , has_predicate , parent_times , i , parsed , rc ;
3595- uint32_t j ;
3596-
3597- assert (node && path && ret && !ret -> count );
3598-
3599- parent_times = 0 ;
3600- parsed = 0 ;
3601-
3602- /* searching for nodeset */
3603- do {
3604- if ((i = parse_path_arg (node -> schema -> module , path , & prefix , & pref_len , & name , & nam_len , & parent_times , & has_predicate )) < 1 ) {
3605- LOGVAL (LYE_INCHAR , LY_VLOG_LYD , node , path [- i ], & path [- i ]);
3606- rc = -1 ;
3607- goto error ;
3608- }
3609- path += i ;
3610- parsed += i ;
3611-
3612- if (!ret -> count ) {
3613- if (parent_times > 0 ) {
3614- data = node ;
3615- for (i = 1 ; i < parent_times ; ++ i ) {
3616- data = data -> parent ;
3617- }
3618- } else if (!parent_times ) {
3619- data = node -> child ;
3620- } else {
3621- /* absolute path */
3622- for (data = node ; data -> parent ; data = data -> parent );
3623- }
3624-
3625- /* we may still be parsing it and the pointer is not correct yet */
3626- if (data -> prev ) {
3627- while (data -> prev -> next ) {
3628- data = data -> prev ;
3629- }
3630- }
3631- }
3632-
3633- /* node identifier */
3634- if ((rc = resolve_data_node (prefix , pref_len , name , nam_len , data , ret ))) {
3635- if (rc == -1 ) {
3636- LOGVAL (LYE_INELEM_LEN , LY_VLOG_LYD , node , nam_len , name );
3637- }
3638- goto error ;
3639- }
3640-
3641- if (has_predicate ) {
3642- /* we have predicate, so the current results must be lists */
3643- for (j = 0 ; j < ret -> count ;) {
3644- if (ret -> node [j ]-> schema -> nodetype == LYS_LIST &&
3645- ((struct lys_node_list * )ret -> node [0 ]-> schema )-> keys ) {
3646- /* leafref is ok, continue check with next leafref */
3647- ++ j ;
3648- continue ;
3649- }
3650-
3651- /* does not fulfill conditions, remove leafref record */
3652- unres_data_del (ret , j );
3653- }
3654- if ((rc = resolve_path_predicate_data (path , node , ret , & i ))) {
3655- if (rc == -1 ) {
3656- LOGVAL (LYE_NORESOLV , LY_VLOG_LYD , node , "leafref" , path );
3657- }
3658- goto error ;
3659- }
3660- path += i ;
3661- parsed += i ;
3662-
3663- if (!ret -> count ) {
3664- rc = EXIT_FAILURE ;
3665- goto error ;
3666- }
3667- }
3668- } while (path [0 ] != '\0' );
3669-
3670- return EXIT_SUCCESS ;
3671-
3672- error :
3673-
3674- free (ret -> node );
3675- ret -> node = NULL ;
3676- ret -> count = 0 ;
3677-
3678- return rc ;
3679- }
3680-
36813394static int
36823395resolve_schema_leafref_valid_dep_flag (const struct lys_node * op_node , const struct lys_node * first_node , int abs_path )
36833396{
@@ -7410,30 +7123,32 @@ resolve_instid(struct lyd_node *data, const char *path, int req_inst, struct lyd
74107123static int
74117124resolve_leafref (struct lyd_node_leaf_list * leaf , const char * path , int req_inst , struct lyd_node * * ret )
74127125{
7413- struct unres_data matches ;
7126+ struct ly_set * set ;
74147127 uint32_t i ;
74157128
7416- /* init */
7417- memset (& matches , 0 , sizeof matches );
74187129 * ret = NULL ;
74197130
7420- /* EXIT_FAILURE return keeps leaf->value.lefref NULL, handled later */
7421- if (resolve_path_arg_data ((struct lyd_node * )leaf , path , & matches ) == -1 ) {
7131+ /* syntax was already checked, so just evaluate the path using standard XPath */
7132+ set = lyd_find_xpath ((struct lyd_node * )leaf , path );
7133+ if (!set ) {
74227134 return -1 ;
74237135 }
74247136
7425- /* check that value matches */
7426- for (i = 0 ; i < matches .count ; ++ i ) {
7137+ for (i = 0 ; i < set -> number ; ++ i ) {
7138+ if (!(set -> set .d [i ]-> schema -> nodetype & (LYS_LEAF | LYS_LEAFLIST ))) {
7139+ continue ;
7140+ }
7141+
74277142 /* not that the value is already in canonical form since the parsers does the conversion,
74287143 * so we can simply compare just the values */
7429- if (ly_strequal (leaf -> value_str , ((struct lyd_node_leaf_list * )matches . node [i ])-> value_str , 1 )) {
7144+ if (ly_strequal (leaf -> value_str , ((struct lyd_node_leaf_list * )set -> set . d [i ])-> value_str , 1 )) {
74307145 /* we have the match */
7431- * ret = matches . node [i ];
7146+ * ret = set -> set . d [i ];
74327147 break ;
74337148 }
74347149 }
74357150
7436- free ( matches . node );
7151+ ly_set_free ( set );
74377152
74387153 if (!* ret ) {
74397154 /* reference not found */
0 commit comments