1 /**
2  * @file parser_yang.c
3  * @author Pavol Vican
4  * @brief YANG parser for libyang
5  *
6  * Copyright (c) 2015 CESNET, z.s.p.o.
7  *
8  * This source code is licensed under BSD 3-Clause License (the "License").
9  * You may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     https://opensource.org/licenses/BSD-3-Clause
13  */
14 
15 #include <ctype.h>
16 #include <assert.h>
17 #include "parser_yang.h"
18 #include "parser_yang_lex.h"
19 #include "parser.h"
20 #include "xpath.h"
21 
22 static void yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size);
23 static int yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres);
24 static void yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size);
25 static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
26 static void free_yang_common(struct lys_module *module, struct lys_node *node);
27 static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
28                             int options, struct unres_schema *unres);
29 static int yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword);
30 static void yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node);
31 void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size, int shallow,
32                         void (*private_destructor)(const struct lys_node *node, void *priv));
33 
34 static int
yang_check_string(struct lys_module * module,const char ** target,char * what,char * where,char * value,struct lys_node * node)35 yang_check_string(struct lys_module *module, const char **target, char *what,
36                   char *where, char *value, struct lys_node *node)
37 {
38     if (*target) {
39         LOGVAL(module->ctx, LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
40         free(value);
41         return 1;
42     } else {
43         *target = lydict_insert_zc(module->ctx, value);
44         return 0;
45     }
46 }
47 
48 int
yang_read_common(struct lys_module * module,char * value,enum yytokentype type)49 yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
50 {
51     int ret = 0;
52     uint8_t i;
53 
54     switch (type) {
55     case MODULE_KEYWORD:
56         module->name = lydict_insert_zc(module->ctx, value);
57 
58         /* in some really invalid situations there can be a circular import and
59          * we can check it only after we have parsed the module name */
60         for (i = 0; i < module->ctx->models.parsing_sub_modules_count; ++i) {
61             if (module->ctx->models.parsing_sub_modules[i] == module) {
62                 /* skip our own module */
63                 continue;
64             }
65 
66             if (!strcmp(module->ctx->models.parsing_sub_modules[i]->name, module->name)) {
67                 LOGVAL(module->ctx, LYE_CIRC_IMPORTS, LY_VLOG_NONE, NULL, module->name);
68                 ret = EXIT_FAILURE;
69                 break;
70             }
71         }
72         break;
73     case NAMESPACE_KEYWORD:
74         ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
75         break;
76     case ORGANIZATION_KEYWORD:
77         ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
78         break;
79     case CONTACT_KEYWORD:
80         ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
81         break;
82     default:
83         free(value);
84         LOGINT(module->ctx);
85         ret = EXIT_FAILURE;
86         break;
87     }
88 
89     return ret;
90 }
91 
92 int
yang_check_version(struct lys_module * module,struct lys_submodule * submodule,char * value,int repeat)93 yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
94 {
95     int ret = EXIT_SUCCESS;
96 
97     if (repeat) {
98         LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
99         ret = EXIT_FAILURE;
100     } else {
101         if (!strcmp(value, "1")) {
102             if (submodule) {
103                 if (module->version > 1) {
104                     LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
105                     ret = EXIT_FAILURE;
106                  }
107                 submodule->version = 1;
108             } else {
109                 module->version = 1;
110             }
111         } else if (!strcmp(value, "1.1")) {
112             if (submodule) {
113                 if (module->version != 2) {
114                     LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
115                     ret = EXIT_FAILURE;
116                 }
117                 submodule->version = 2;
118             } else {
119                 module->version = 2;
120             }
121         } else {
122             LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
123             ret = EXIT_FAILURE;
124         }
125     }
126     free(value);
127     return ret;
128 }
129 
130 int
yang_read_prefix(struct lys_module * module,struct lys_import * imp,char * value)131 yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
132 {
133     int ret = 0;
134 
135     if (!imp && lyp_check_identifier(module->ctx, value, LY_IDENT_PREFIX, module, NULL)) {
136         free(value);
137         return EXIT_FAILURE;
138     }
139 
140     if (imp) {
141         ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
142     } else {
143         ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
144     }
145 
146     return ret;
147 }
148 
149 static int
yang_fill_import(struct lys_module * module,struct lys_import * imp_old,struct lys_import * imp_new,char * value,struct unres_schema * unres)150 yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
151                  char *value, struct unres_schema *unres)
152 {
153     const char *exp;
154     int rc;
155 
156     if (!imp_old->prefix) {
157         LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
158         goto error;
159     } else {
160         if (lyp_check_identifier(module->ctx, imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
161             goto error;
162         }
163     }
164     memcpy(imp_new, imp_old, sizeof *imp_old);
165     exp = lydict_insert_zc(module->ctx, value);
166     rc = lyp_check_import(module, exp, imp_new);
167     lydict_remove(module->ctx, exp);
168     module->imp_size++;
169     if (rc || yang_check_ext_instance(module, &imp_new->ext, &imp_new->ext_size, imp_new, unres)) {
170         return EXIT_FAILURE;
171     }
172 
173     return EXIT_SUCCESS;
174 
175 error:
176     free(value);
177     lydict_remove(module->ctx, imp_old->dsc);
178     lydict_remove(module->ctx, imp_old->ref);
179     lydict_remove(module->ctx, imp_old->prefix);
180     lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size, NULL);
181     return EXIT_FAILURE;
182 }
183 
184 int
yang_read_description(struct lys_module * module,void * node,char * value,char * where,enum yytokentype type)185 yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
186 {
187     int ret;
188     char *dsc = "description";
189 
190     switch (type) {
191     case MODULE_KEYWORD:
192         ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
193         break;
194     case REVISION_KEYWORD:
195         ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
196         break;
197     case IMPORT_KEYWORD:
198         ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
199         break;
200     case INCLUDE_KEYWORD:
201         ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
202         break;
203     case NODE_PRINT:
204         ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
205         break;
206     default:
207         ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
208         break;
209     }
210     return ret;
211 }
212 
213 int
yang_read_reference(struct lys_module * module,void * node,char * value,char * where,enum yytokentype type)214 yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
215 {
216     int ret;
217     char *ref = "reference";
218 
219     switch (type) {
220     case MODULE_KEYWORD:
221         ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
222         break;
223     case REVISION_KEYWORD:
224         ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
225         break;
226     case IMPORT_KEYWORD:
227         ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
228         break;
229     case INCLUDE_KEYWORD:
230         ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
231         break;
232     case NODE_PRINT:
233         ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
234         break;
235     default:
236         ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
237         break;
238     }
239     return ret;
240 }
241 
242 int
yang_fill_iffeature(struct lys_module * module,struct lys_iffeature * iffeature,void * parent,char * value,struct unres_schema * unres,int parent_is_feature)243 yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
244                     char *value, struct unres_schema *unres, int parent_is_feature)
245 {
246     const char *exp;
247     int ret;
248 
249     if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
250         LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
251         free(value);
252         return EXIT_FAILURE;
253     }
254 
255     if (!(exp = transform_iffeat_schema2json(module, value))) {
256         free(value);
257         return EXIT_FAILURE;
258     }
259     free(value);
260 
261     ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
262     lydict_remove(module->ctx, exp);
263 
264     return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
265 }
266 
267 int
yang_read_base(struct lys_module * module,struct lys_ident * ident,char * value,struct unres_schema * unres)268 yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
269 {
270     const char *exp;
271 
272     exp = transform_schema2json(module, value);
273     free(value);
274     if (!exp) {
275         return EXIT_FAILURE;
276     }
277 
278     if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
279         lydict_remove(module->ctx, exp);
280         return EXIT_FAILURE;
281     }
282 
283     lydict_remove(module->ctx, exp);
284     return EXIT_SUCCESS;
285 }
286 
287 int
yang_read_message(struct lys_module * module,struct lys_restr * save,char * value,char * what,int message)288 yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
289 {
290     int ret;
291 
292     if (message == ERROR_APP_TAG_KEYWORD) {
293         ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
294     } else {
295         ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
296     }
297     return ret;
298 }
299 
300 int
yang_read_presence(struct lys_module * module,struct lys_node_container * cont,char * value)301 yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
302 {
303     if (cont->presence) {
304         LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
305         free(value);
306         return EXIT_FAILURE;
307     } else {
308         cont->presence = lydict_insert_zc(module->ctx, value);
309         return EXIT_SUCCESS;
310     }
311 }
312 
313 void *
yang_read_when(struct lys_module * module,struct lys_node * node,enum yytokentype type,char * value)314 yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
315 {
316     struct lys_when *retval;
317 
318     retval = calloc(1, sizeof *retval);
319     LY_CHECK_ERR_RETURN(!retval, LOGMEM(module->ctx); free(value), NULL);
320     retval->cond = transform_schema2json(module, value);
321     if (!retval->cond) {
322         goto error;
323     }
324     switch (type) {
325     case CONTAINER_KEYWORD:
326         if (((struct lys_node_container *)node)->when) {
327             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
328             goto error;
329         }
330         ((struct lys_node_container *)node)->when = retval;
331         break;
332     case ANYDATA_KEYWORD:
333     case ANYXML_KEYWORD:
334         if (((struct lys_node_anydata *)node)->when) {
335             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
336             goto error;
337         }
338         ((struct lys_node_anydata *)node)->when = retval;
339         break;
340     case CHOICE_KEYWORD:
341         if (((struct lys_node_choice *)node)->when) {
342             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
343             goto error;
344         }
345         ((struct lys_node_choice *)node)->when = retval;
346         break;
347     case CASE_KEYWORD:
348         if (((struct lys_node_case *)node)->when) {
349             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
350             goto error;
351         }
352         ((struct lys_node_case *)node)->when = retval;
353         break;
354     case LEAF_KEYWORD:
355         if (((struct lys_node_leaf *)node)->when) {
356             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
357             goto error;
358         }
359         ((struct lys_node_leaf *)node)->when = retval;
360         break;
361     case LEAF_LIST_KEYWORD:
362         if (((struct lys_node_leaflist *)node)->when) {
363             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
364             goto error;
365         }
366         ((struct lys_node_leaflist *)node)->when = retval;
367         break;
368     case LIST_KEYWORD:
369         if (((struct lys_node_list *)node)->when) {
370             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
371             goto error;
372         }
373         ((struct lys_node_list *)node)->when = retval;
374         break;
375     case USES_KEYWORD:
376         if (((struct lys_node_uses *)node)->when) {
377             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
378             goto error;
379         }
380         ((struct lys_node_uses *)node)->when = retval;
381         break;
382     case AUGMENT_KEYWORD:
383         if (((struct lys_node_augment *)node)->when) {
384             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
385             goto error;
386         }
387         ((struct lys_node_augment *)node)->when = retval;
388         break;
389     case EXTENSION_INSTANCE:
390         *(struct lys_when **)node = retval;
391         break;
392     default:
393         goto error;
394         break;
395     }
396     free(value);
397     return retval;
398 
399 error:
400     free(value);
401     lydict_remove(module->ctx, retval->cond);
402     free(retval);
403     return NULL;
404 }
405 
406 void *
yang_read_node(struct lys_module * module,struct lys_node * parent,struct lys_node ** root,char * value,int nodetype,int sizeof_struct)407 yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
408                char *value, int nodetype, int sizeof_struct)
409 {
410     struct lys_node *node, **child;
411 
412     node = calloc(1, sizeof_struct);
413     LY_CHECK_ERR_RETURN(!node, LOGMEM(module->ctx); free(value), NULL);
414 
415     LOGDBG(LY_LDGYANG, "parsing %s statement \"%s\"", strnodetype(nodetype), value);
416     node->name = lydict_insert_zc(module->ctx, value);
417     node->module = module;
418     node->nodetype = nodetype;
419     node->parent = parent;
420 
421     /* insert the node into the schema tree */
422     child = (parent) ? &parent->child : root;
423     if (*child) {
424         (*child)->prev->next = node;
425         (*child)->prev = node;
426     } else {
427         *child = node;
428         node->prev = node;
429     }
430     return node;
431 }
432 
433 int
yang_read_default(struct lys_module * module,void * node,char * value,enum yytokentype type)434 yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
435 {
436     int ret;
437 
438     switch (type) {
439     case LEAF_KEYWORD:
440         ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
441         break;
442     case TYPEDEF_KEYWORD:
443         ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
444         break;
445     default:
446         free(value);
447         LOGINT(module->ctx);
448         ret = EXIT_FAILURE;
449         break;
450     }
451     return ret;
452 }
453 
454 int
yang_read_units(struct lys_module * module,void * node,char * value,enum yytokentype type)455 yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
456 {
457     int ret;
458 
459     switch (type) {
460     case LEAF_KEYWORD:
461         ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
462         break;
463     case LEAF_LIST_KEYWORD:
464         ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
465         break;
466     case TYPEDEF_KEYWORD:
467         ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
468         break;
469     case ADD_KEYWORD:
470     case REPLACE_KEYWORD:
471     case DELETE_KEYWORD:
472         ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
473         break;
474     default:
475         free(value);
476         LOGINT(module->ctx);
477         ret = EXIT_FAILURE;
478         break;
479     }
480     return ret;
481 }
482 
483 int
yang_read_key(struct lys_module * module,struct lys_node_list * list,struct unres_schema * unres)484 yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
485 {
486     char *exp, *value;
487 
488     exp = value = (char *) list->keys;
489     while ((value = strpbrk(value, " \t\n"))) {
490         list->keys_size++;
491         while (isspace(*value)) {
492             value++;
493         }
494     }
495     list->keys_size++;
496 
497     list->keys_str = lydict_insert_zc(module->ctx, exp);
498     list->keys = calloc(list->keys_size, sizeof *list->keys);
499     LY_CHECK_ERR_RETURN(!list->keys, LOGMEM(module->ctx), EXIT_FAILURE);
500 
501     if (unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
502         return EXIT_FAILURE;
503     }
504     return EXIT_SUCCESS;
505 }
506 
507 int
yang_fill_unique(struct lys_module * module,struct lys_node_list * list,struct lys_unique * unique,char * value,struct unres_schema * unres)508 yang_fill_unique(struct lys_module *module, struct lys_node_list *list, struct lys_unique *unique, char *value, struct unres_schema *unres)
509 {
510     int i, j;
511     char *vaux, c = 0;
512     struct unres_list_uniq *unique_info;
513 
514     /* count the number of unique leafs in the value */
515     vaux = value;
516     while ((vaux = strpbrk(vaux, " \t\n"))) {
517        unique->expr_size++;
518         while (isspace(*vaux)) {
519             vaux++;
520         }
521     }
522     unique->expr_size++;
523     unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
524     LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM(module->ctx), error);
525 
526     for (i = 0; i < unique->expr_size; i++) {
527         vaux = strpbrk(value, " \t\n");
528         if (vaux) {
529             c = *vaux;
530             *vaux = '\0';
531         }
532 
533         /* store token into unique structure (includes converting prefix to the module name) */
534         unique->expr[i] = transform_schema2json(module, value);
535         if (!unique->expr[i]) {
536             LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, list, value, "unique");
537             goto error;
538         }
539         if (vaux) {
540             *vaux = c;
541         }
542 
543         /* check that the expression does not repeat */
544         for (j = 0; j < i; j++) {
545             if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
546                 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
547                 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
548                 goto error;
549             }
550         }
551         /* try to resolve leaf */
552         if (unres) {
553             unique_info = malloc(sizeof *unique_info);
554             LY_CHECK_ERR_GOTO(!unique_info, LOGMEM(module->ctx), error);
555             unique_info->list = (struct lys_node *)list;
556             unique_info->expr = unique->expr[i];
557             unique_info->trg_type = &unique->trg_type;
558             if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
559                 goto error;
560             }
561         } else {
562             if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
563                 goto error;
564             }
565         }
566 
567         /* move to next token */
568         value = vaux;
569         while(value && isspace(*value)) {
570             value++;
571         }
572     }
573 
574     return EXIT_SUCCESS;
575 
576 error:
577     return EXIT_FAILURE;
578 }
579 
580 int
yang_read_unique(struct lys_module * module,struct lys_node_list * list,struct unres_schema * unres)581 yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
582 {
583     uint8_t k;
584     char *str;
585 
586     for (k = 0; k < list->unique_size; k++) {
587         str = (char *)list->unique[k].expr;
588         if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
589             goto error;
590         }
591         free(str);
592     }
593     return EXIT_SUCCESS;
594 
595 error:
596     free(str);
597     return EXIT_FAILURE;
598 }
599 
600 int
yang_read_leafref_path(struct lys_module * module,struct yang_type * stype,char * value)601 yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
602 {
603     if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
604         LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
605         goto error;
606     }
607     if (stype->type->info.lref.path) {
608         LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
609         goto error;
610     }
611     stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
612     stype->base = LY_TYPE_LEAFREF;
613     return EXIT_SUCCESS;
614 
615 error:
616     free(value);
617     return EXIT_FAILURE;
618 }
619 
620 int
yang_read_require_instance(struct ly_ctx * ctx,struct yang_type * stype,int req)621 yang_read_require_instance(struct ly_ctx *ctx, struct yang_type *stype, int req)
622 {
623     if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
624         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
625         return EXIT_FAILURE;
626     }
627     if (stype->type->info.lref.req) {
628         LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
629         return EXIT_FAILURE;
630     }
631     stype->type->info.lref.req = req;
632     stype->base = LY_TYPE_LEAFREF;
633     return EXIT_SUCCESS;
634 }
635 
636 int
yang_check_type(struct lys_module * module,struct lys_node * parent,struct yang_type * typ,struct lys_type * type,int tpdftype,struct unres_schema * unres)637 yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct lys_type *type, int tpdftype, struct unres_schema *unres)
638 {
639     struct ly_ctx *ctx = module->ctx;
640     int rc, ret = -1;
641     unsigned int i, j;
642     const char *name, *value, *module_name = NULL;
643     LY_DATA_TYPE base = 0, base_tmp;
644     struct lys_node *siter;
645     struct lys_type *dertype;
646     struct lys_type_enum *enms_sc = NULL;
647     struct lys_type_bit *bits_sc = NULL;
648     struct lys_type_bit bit_tmp;
649     struct yang_type *yang;
650 
651     value = transform_schema2json(module, typ->name);
652     if (!value) {
653         goto error;
654     }
655 
656     i = parse_identifier(value);
657     if (i < 1) {
658         LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
659         lydict_remove(ctx, value);
660         goto error;
661     }
662     /* module name */
663     name = value;
664     if (value[i]) {
665         module_name = lydict_insert(ctx, value, i);
666         name += i;
667         if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
668             LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
669             lydict_remove(ctx, module_name);
670             lydict_remove(ctx, value);
671             goto error;
672         }
673         ++name;
674     }
675 
676     rc = resolve_superior_type(name, module_name, module, parent, &type->der);
677     if (rc == -1) {
678         LOGVAL(ctx, LYE_INMOD, LY_VLOG_NONE, NULL, module_name);
679         lydict_remove(ctx, module_name);
680         lydict_remove(ctx, value);
681         goto error;
682 
683     /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
684     } else if (rc == EXIT_FAILURE) {
685         LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
686         lydict_remove(ctx, module_name);
687         lydict_remove(ctx, value);
688         ret = EXIT_FAILURE;
689         goto error;
690     }
691     lydict_remove(ctx, module_name);
692     lydict_remove(ctx, value);
693 
694     if (type->value_flags & LY_VALUE_UNRESGRP) {
695         /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
696          * unresolved item left inside the grouping, LYTYPE_GRP used as a flag for types inside a grouping.  */
697         for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
698         if (siter) {
699             assert(((struct lys_node_grp *)siter)->unres_count);
700             ((struct lys_node_grp *)siter)->unres_count--;
701         } else {
702             LOGINT(ctx);
703             goto error;
704         }
705         type->value_flags &= ~LY_VALUE_UNRESGRP;
706     }
707 
708     /* check status */
709     if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
710                          type->der->flags, type->der->module, type->der->name, parent)) {
711         goto error;
712     }
713 
714     base = typ->base;
715     base_tmp = type->base;
716     type->base = type->der->type.base;
717     if (base == 0) {
718         base = type->der->type.base;
719     }
720     switch (base) {
721     case LY_TYPE_STRING:
722         if (type->base == LY_TYPE_BINARY) {
723             if (type->info.str.pat_count) {
724                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
725                 goto error;
726             }
727             type->info.binary.length = type->info.str.length;
728             if (type->info.binary.length && lyp_check_length_range(ctx, type->info.binary.length->expr, type)) {
729                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
730                 goto error;
731             }
732         } else if (type->base == LY_TYPE_STRING) {
733             if (type->info.str.length && lyp_check_length_range(ctx, type->info.str.length->expr, type)) {
734                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
735                 goto error;
736             }
737         } else {
738             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
739             goto error;
740         }
741         break;
742     case LY_TYPE_DEC64:
743         if (type->base == LY_TYPE_DEC64) {
744             /* mandatory sub-statement(s) check */
745             if (!type->info.dec64.dig && !type->der->type.der) {
746                 /* decimal64 type directly derived from built-in type requires fraction-digits */
747                 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
748                 goto error;
749             }
750             if (type->info.dec64.dig && type->der->type.der) {
751                 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
752                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
753                 goto error;
754             }
755 
756             /* copy fraction-digits specification from parent type for easier internal use */
757             if (type->der->type.der) {
758                 type->info.dec64.dig = type->der->type.info.dec64.dig;
759                 type->info.dec64.div = type->der->type.info.dec64.div;
760             }
761             if (type->info.dec64.range && lyp_check_length_range(ctx, type->info.dec64.range->expr, type)) {
762                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
763                 goto error;
764             }
765         } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
766             if (type->info.dec64.dig) {
767                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
768                 goto error;
769             }
770             type->info.num.range = type->info.dec64.range;
771             if (type->info.num.range && lyp_check_length_range(ctx, type->info.num.range->expr, type)) {
772                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
773                 goto error;
774             }
775         } else {
776             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
777             goto error;
778         }
779         break;
780     case LY_TYPE_ENUM:
781         if (type->base != LY_TYPE_ENUM) {
782             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
783             goto error;
784         }
785         dertype = &type->der->type;
786 
787         if (!dertype->der) {
788             if (!type->info.enums.count) {
789                 /* type is derived directly from buit-in enumeartion type and enum statement is required */
790                 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
791                 goto error;
792             }
793         } else {
794             for (; !dertype->info.enums.count; dertype = &dertype->der->type);
795             if (module->version < 2 && type->info.enums.count) {
796                 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
797                  * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
798                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
799                 goto error;
800             }
801 
802             /* restricted enumeration type - the name MUST be used in the base type */
803             enms_sc = dertype->info.enums.enm;
804             for (i = 0; i < type->info.enums.count; i++) {
805                 for (j = 0; j < dertype->info.enums.count; j++) {
806                     if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
807                         break;
808                     }
809                 }
810                 if (j == dertype->info.enums.count) {
811                     LOGVAL(ctx, LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
812                     goto error;
813                 }
814 
815                 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
816                     /* automatically assign value from base type */
817                     type->info.enums.enm[i].value = enms_sc[j].value;
818                 } else {
819                     /* check that the assigned value corresponds to the original
820                      * value of the enum in the base type */
821                     if (type->info.enums.enm[i].value != enms_sc[j].value) {
822                         /* type->info.enums.enm[i].value - assigned value in restricted enum
823                          * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
824                         LOGVAL(ctx, LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
825                                type->info.enums.enm[i].name, enms_sc[j].value);
826                         goto error;
827                     }
828                 }
829             }
830         }
831         break;
832     case LY_TYPE_BITS:
833         if (type->base != LY_TYPE_BITS) {
834             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
835             goto error;
836         }
837         dertype = &type->der->type;
838 
839         if (!dertype->der) {
840             if (!type->info.bits.count) {
841                 /* type is derived directly from buit-in bits type and bit statement is required */
842                 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
843                 goto error;
844             }
845         } else {
846             for (; !dertype->info.enums.count; dertype = &dertype->der->type);
847             if (module->version < 2 && type->info.bits.count) {
848                 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
849                  * since YANG 1.1 the bit statements can be used to restrict the base bits type */
850                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
851                 goto error;
852             }
853 
854             bits_sc = dertype->info.bits.bit;
855             for (i = 0; i < type->info.bits.count; i++) {
856                 for (j = 0; j < dertype->info.bits.count; j++) {
857                     if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
858                         break;
859                     }
860                 }
861                 if (j == dertype->info.bits.count) {
862                     LOGVAL(ctx, LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
863                     goto error;
864                 }
865 
866                 /* restricted bits type */
867                 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
868                     /* automatically assign position from base type */
869                     type->info.bits.bit[i].pos = bits_sc[j].pos;
870                 } else {
871                     /* check that the assigned position corresponds to the original
872                      * position of the bit in the base type */
873                     if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
874                         /* type->info.bits.bit[i].pos - assigned position in restricted bits
875                          * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
876                         LOGVAL(ctx, LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
877                                type->info.bits.bit[i].name, bits_sc[j].pos);
878                         goto error;
879                     }
880                 }
881             }
882         }
883 
884         for (i = type->info.bits.count; i > 0; i--) {
885             j = i - 1;
886 
887             /* keep them ordered by position */
888             while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
889                 /* switch them */
890                 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
891                 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
892                 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
893                 j--;
894             }
895         }
896         break;
897     case LY_TYPE_LEAFREF:
898     case LY_TYPE_INST:
899         if (type->base == LY_TYPE_INST) {
900             if (type->info.lref.path) {
901                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
902                 goto error;
903             }
904             if (type->info.lref.req) {
905                 type->info.inst.req = type->info.lref.req;
906             } else if (type->der->type.der) {
907                 type->info.inst.req = type->der->type.info.inst.req;
908             }
909         } else if (type->base == LY_TYPE_LEAFREF) {
910             /* require-instance only YANG 1.1 */
911             if (type->info.lref.req && (module->version < 2)) {
912                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
913                 goto error;
914             }
915             /* flag resolving for later use */
916             if (!tpdftype && lys_ingrouping(parent)) {
917                 /* just a flag - do not resolve */
918                 tpdftype = 1;
919             }
920 
921             if (type->info.lref.path) {
922                 if (type->der->type.der) {
923                     LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
924                     goto error;
925                 }
926 
927                 value = type->info.lref.path;
928                 /* store in the JSON format */
929                 type->info.lref.path = transform_schema2json(module, value);
930                 lydict_remove(ctx, value);
931                 if (!type->info.lref.path) {
932                     goto error;
933                 }
934                 /* try to resolve leafref path only when this is instantiated
935                  * leaf, so it is not:
936                  * - typedef's type,
937                  * - in  grouping definition,
938                  * - just instantiated in a grouping definition,
939                  * because in those cases the nodes referenced in path might not be present
940                  * and it is not a bug.  */
941                 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
942                     goto error;
943                 }
944             } else if (!type->der->type.der) {
945                 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
946                 goto error;
947             } else {
948                 /* copy leafref definition into the derived type */
949                 type->info.lref.path = lydict_insert(ctx, type->der->type.info.lref.path, 0);
950                 if (!type->info.lref.req) {
951                     /* inherit require-instance only if not overwritten */
952                     type->info.lref.req = type->der->type.info.lref.req;
953                 }
954                 /* and resolve the path at the place we are (if not in grouping/typedef) */
955                 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
956                     goto error;
957                 }
958             }
959         } else {
960             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
961             goto error;
962         }
963         break;
964     case LY_TYPE_IDENT:
965         if (type->base != LY_TYPE_IDENT) {
966             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
967             goto error;
968         }
969         if (type->der->type.der) {
970             if (type->info.ident.ref) {
971                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
972                 goto error;
973             }
974         } else {
975             if (!type->info.ident.ref) {
976                 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
977                 goto error;
978             }
979         }
980         break;
981     case LY_TYPE_UNION:
982         if (type->base != LY_TYPE_UNION) {
983             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
984             goto error;
985         }
986         if (!type->info.uni.types) {
987             if (type->der->type.der) {
988                 /* this is just a derived type with no additional type specified/required */
989                 assert(type->der->type.base == LY_TYPE_UNION);
990                 type->info.uni.has_ptr_type = type->der->type.info.uni.has_ptr_type;
991                 break;
992             }
993             LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
994             goto error;
995         }
996         for (i = 0; i < type->info.uni.count; i++) {
997             dertype = &type->info.uni.types[i];
998             if (dertype->base == LY_TYPE_DER) {
999                 yang = (struct yang_type *)dertype->der;
1000                 dertype->der = NULL;
1001                 dertype->parent = type->parent;
1002                 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
1003                     dertype->der = (struct lys_tpdf *)yang;
1004                     ret = EXIT_FAILURE;
1005                     type->base = base_tmp;
1006                     base = 0;
1007                     goto error;
1008                 } else {
1009                     lydict_remove(ctx, yang->name);
1010                     free(yang);
1011                 }
1012             }
1013             if (module->version < 2) {
1014                 if (dertype->base == LY_TYPE_EMPTY) {
1015                     LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
1016                     goto error;
1017                 } else if (dertype->base == LY_TYPE_LEAFREF) {
1018                     LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
1019                     goto error;
1020                 }
1021             }
1022             if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
1023                     || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
1024                 type->info.uni.has_ptr_type = 1;
1025             }
1026         }
1027         break;
1028 
1029     default:
1030         if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
1031             if (type->base != base) {
1032                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
1033                 goto error;
1034             }
1035         } else {
1036             LOGINT(ctx);
1037             goto error;
1038         }
1039     }
1040 
1041     /* if derived type has extension, which need validate data */
1042     dertype = &type->der->type;
1043     while (dertype->der) {
1044         if (dertype->parent->flags & LYS_VALID_EXT) {
1045             type->parent->flags |= LYS_VALID_EXT;
1046         }
1047         dertype = &dertype->der->type;
1048     }
1049 
1050     return EXIT_SUCCESS;
1051 
1052 error:
1053     if (base) {
1054         type->base = base_tmp;
1055     }
1056     return ret;
1057 }
1058 
1059 void
yang_free_type_union(struct ly_ctx * ctx,struct lys_type * type)1060 yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1061 {
1062     struct lys_type *stype;
1063     struct yang_type *yang;
1064     unsigned int i;
1065 
1066     for (i = 0; i < type->info.uni.count; ++i) {
1067         stype = &type->info.uni.types[i];
1068         if (stype->base == LY_TYPE_DER) {
1069             yang = (struct yang_type *)stype->der;
1070             stype->base = yang->base;
1071             lydict_remove(ctx, yang->name);
1072             free(yang);
1073         } else if (stype->base == LY_TYPE_UNION) {
1074             yang_free_type_union(ctx, stype);
1075         }
1076     }
1077 }
1078 
1079 void *
yang_read_type(struct ly_ctx * ctx,void * parent,char * value,enum yytokentype type)1080 yang_read_type(struct ly_ctx *ctx, void *parent, char *value, enum yytokentype type)
1081 {
1082     struct yang_type *typ;
1083     struct lys_deviate *dev;
1084 
1085     typ = calloc(1, sizeof *typ);
1086     LY_CHECK_ERR_RETURN(!typ, LOGMEM(ctx), NULL);
1087 
1088     typ->flags = LY_YANG_STRUCTURE_FLAG;
1089     switch (type) {
1090     case LEAF_KEYWORD:
1091         if (((struct lys_node_leaf *)parent)->type.der) {
1092             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1093             goto error;
1094         }
1095         ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1096         ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1097         typ->type = &((struct lys_node_leaf *)parent)->type;
1098         break;
1099     case LEAF_LIST_KEYWORD:
1100         if (((struct lys_node_leaflist *)parent)->type.der) {
1101             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1102             goto error;
1103         }
1104         ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1105         ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1106         typ->type = &((struct lys_node_leaflist *)parent)->type;
1107         break;
1108     case UNION_KEYWORD:
1109         ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1110         typ->type = (struct lys_type *)parent;
1111         break;
1112     case TYPEDEF_KEYWORD:
1113         if (((struct lys_tpdf *)parent)->type.der) {
1114             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1115             goto error;
1116         }
1117         ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1118         typ->type = &((struct lys_tpdf *)parent)->type;
1119         break;
1120     case REPLACE_KEYWORD:
1121         /* deviation replace type*/
1122         dev = (struct lys_deviate *)parent;
1123         if (dev->type) {
1124             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
1125             goto error;
1126         }
1127         dev->type = calloc(1, sizeof *dev->type);
1128         LY_CHECK_ERR_GOTO(!dev->type, LOGMEM(ctx), error);
1129         dev->type->der = (struct lys_tpdf *)typ;
1130         typ->type = dev->type;
1131         break;
1132     case EXTENSION_INSTANCE:
1133         ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1134         typ->type = parent;
1135         break;
1136     default:
1137         goto error;
1138         break;
1139     }
1140     typ->name = lydict_insert_zc(ctx, value);
1141     return typ;
1142 
1143 error:
1144     free(value);
1145     free(typ);
1146     return NULL;
1147 }
1148 
1149 void *
yang_read_length(struct ly_ctx * ctx,struct yang_type * stype,char * value,int is_ext_instance)1150 yang_read_length(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
1151 {
1152     struct lys_restr *length;
1153 
1154     if (is_ext_instance) {
1155         length = (struct lys_restr *)stype;
1156     } else {
1157         if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1158             stype->base = LY_TYPE_STRING;
1159         } else {
1160             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
1161             goto error;
1162         }
1163 
1164         if (stype->type->info.str.length) {
1165             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
1166             goto error;
1167         }
1168         length = calloc(1, sizeof *length);
1169         LY_CHECK_ERR_GOTO(!length, LOGMEM(ctx), error);
1170         stype->type->info.str.length = length;
1171     }
1172     length->expr = lydict_insert_zc(ctx, value);
1173     return length;
1174 
1175 error:
1176     free(value);
1177     return NULL;
1178 }
1179 
1180 int
yang_read_pattern(struct ly_ctx * ctx,struct lys_restr * pattern,void ** precomp,char * value,char modifier)1181 yang_read_pattern(struct ly_ctx *ctx, struct lys_restr *pattern, void **precomp, char *value, char modifier)
1182 {
1183     char *buf;
1184     size_t len;
1185 
1186     if (precomp && lyp_precompile_pattern(ctx, value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
1187         free(value);
1188         return EXIT_FAILURE;
1189     }
1190 
1191     len = strlen(value);
1192     buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
1193     LY_CHECK_ERR_RETURN(!buf, LOGMEM(ctx); free(value), EXIT_FAILURE);
1194 
1195     buf[0] = modifier;
1196     strcpy(&buf[1], value);
1197     free(value);
1198 
1199     pattern->expr = lydict_insert_zc(ctx, buf);
1200     return EXIT_SUCCESS;
1201 }
1202 
1203 void *
yang_read_range(struct ly_ctx * ctx,struct yang_type * stype,char * value,int is_ext_instance)1204 yang_read_range(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
1205 {
1206     struct lys_restr * range;
1207 
1208     if (is_ext_instance) {
1209         range = (struct lys_restr *)stype;
1210     } else {
1211         if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
1212             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
1213             goto error;
1214         }
1215         stype->base = LY_TYPE_DEC64;
1216         if (stype->type->info.dec64.range) {
1217             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
1218             goto error;
1219         }
1220         range = calloc(1, sizeof *range);
1221         LY_CHECK_ERR_GOTO(!range, LOGMEM(ctx), error);
1222         stype->type->info.dec64.range = range;
1223     }
1224     range->expr = lydict_insert_zc(ctx, value);
1225     return range;
1226 
1227 error:
1228     free(value);
1229     return NULL;
1230 }
1231 
1232 int
yang_read_fraction(struct ly_ctx * ctx,struct yang_type * typ,uint32_t value)1233 yang_read_fraction(struct ly_ctx *ctx, struct yang_type *typ, uint32_t value)
1234 {
1235     uint32_t i;
1236 
1237     if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1238         typ->base = LY_TYPE_DEC64;
1239     } else {
1240         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
1241         goto error;
1242     }
1243     if (typ->type->info.dec64.dig) {
1244         LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
1245         goto error;
1246     }
1247     /* range check */
1248     if (value < 1 || value > 18) {
1249         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
1250         goto error;
1251     }
1252     typ->type->info.dec64.dig = value;
1253     typ->type->info.dec64.div = 10;
1254     for (i = 1; i < value; i++) {
1255         typ->type->info.dec64.div *= 10;
1256     }
1257     return EXIT_SUCCESS;
1258 
1259 error:
1260     return EXIT_FAILURE;
1261 }
1262 
1263 int
yang_read_enum(struct ly_ctx * ctx,struct yang_type * typ,struct lys_type_enum * enm,char * value)1264 yang_read_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, char *value)
1265 {
1266     int i, j;
1267 
1268     typ->base = LY_TYPE_ENUM;
1269     if (!value[0]) {
1270         LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1271         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1272         free(value);
1273         goto error;
1274     }
1275 
1276     enm->name = lydict_insert_zc(ctx, value);
1277 
1278     /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1279     if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
1280         LOGVAL(ctx, LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
1281         goto error;
1282     }
1283 
1284     j = typ->type->info.enums.count - 1;
1285     /* check the name uniqueness */
1286     for (i = 0; i < j; i++) {
1287         if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
1288             LOGVAL(ctx, LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
1289             goto error;
1290         }
1291     }
1292 
1293     return EXIT_SUCCESS;
1294 
1295 error:
1296     return EXIT_FAILURE;
1297 }
1298 
1299 int
yang_check_enum(struct ly_ctx * ctx,struct yang_type * typ,struct lys_type_enum * enm,int64_t * value,int assign)1300 yang_check_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
1301 {
1302     int i, j;
1303 
1304     if (!assign) {
1305         /* assign value automatically */
1306         if (*value > INT32_MAX) {
1307             LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
1308             goto error;
1309         }
1310         enm->value = *value;
1311         enm->flags |= LYS_AUTOASSIGNED;
1312         (*value)++;
1313     } else if (typ->type->info.enums.enm == enm) {
1314         /* change value, which is assigned automatically, if first enum has value. */
1315         *value = typ->type->info.enums.enm[0].value;
1316         (*value)++;
1317     }
1318 
1319     /* check that the value is unique */
1320     j = typ->type->info.enums.count-1;
1321     for (i = 0; i < j; i++) {
1322         if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
1323             LOGVAL(ctx, LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
1324                    typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1325                    typ->type->info.enums.enm[i].name);
1326             goto error;
1327         }
1328     }
1329 
1330     return EXIT_SUCCESS;
1331 
1332 error:
1333     return EXIT_FAILURE;
1334 }
1335 
1336 int
yang_read_bit(struct ly_ctx * ctx,struct yang_type * typ,struct lys_type_bit * bit,char * value)1337 yang_read_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, char *value)
1338 {
1339     int i, j;
1340 
1341     typ->base = LY_TYPE_BITS;
1342     bit->name = lydict_insert_zc(ctx, value);
1343     if (lyp_check_identifier(ctx, bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
1344         goto error;
1345     }
1346 
1347     j = typ->type->info.bits.count - 1;
1348     /* check the name uniqueness */
1349     for (i = 0; i < j; i++) {
1350         if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
1351             LOGVAL(ctx, LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
1352             goto error;
1353         }
1354     }
1355     return EXIT_SUCCESS;
1356 
1357 error:
1358     return EXIT_FAILURE;
1359 }
1360 
1361 int
yang_check_bit(struct ly_ctx * ctx,struct yang_type * typ,struct lys_type_bit * bit,int64_t * value,int assign)1362 yang_check_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
1363 {
1364     int i,j;
1365 
1366     if (!assign) {
1367         /* assign value automatically */
1368         if (*value > UINT32_MAX) {
1369             LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
1370             goto error;
1371         }
1372         bit->pos = (uint32_t)*value;
1373         bit->flags |= LYS_AUTOASSIGNED;
1374         (*value)++;
1375     }
1376 
1377     j = typ->type->info.bits.count - 1;
1378     /* check that the value is unique */
1379     for (i = 0; i < j; i++) {
1380         if (typ->type->info.bits.bit[i].pos == bit->pos) {
1381             LOGVAL(ctx, LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
1382             goto error;
1383         }
1384     }
1385 
1386     return EXIT_SUCCESS;
1387 
1388 error:
1389     return EXIT_FAILURE;
1390 }
1391 
1392 int
yang_read_augment(struct lys_module * module,struct lys_node * parent,struct lys_node_augment * aug,char * value)1393 yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
1394 {
1395     aug->nodetype = LYS_AUGMENT;
1396     aug->target_name = transform_schema2json(module, value);
1397     free(value);
1398     if (!aug->target_name) {
1399         return EXIT_FAILURE;
1400     }
1401     aug->parent = parent;
1402     aug->module = module;
1403     return EXIT_SUCCESS;
1404 }
1405 
1406 void *
yang_read_deviate_unsupported(struct ly_ctx * ctx,struct lys_deviation * dev)1407 yang_read_deviate_unsupported(struct ly_ctx *ctx, struct lys_deviation *dev)
1408 {
1409     if (dev->deviate_size) {
1410         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
1411         return NULL;
1412     }
1413     dev->deviate = calloc(1, sizeof *dev->deviate);
1414     LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM(ctx), NULL);
1415     dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1416     dev->deviate_size = 1;
1417     return dev->deviate;
1418 }
1419 
1420 void *
yang_read_deviate(struct ly_ctx * ctx,struct lys_deviation * dev,LYS_DEVIATE_TYPE mod)1421 yang_read_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
1422 {
1423     struct lys_deviate *deviate;
1424 
1425     if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
1426         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1427         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
1428         return NULL;
1429     }
1430     if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1431         deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
1432         LY_CHECK_ERR_RETURN(!deviate, LOGMEM(ctx), NULL);
1433         memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1434         dev->deviate = deviate;
1435     }
1436     dev->deviate[dev->deviate_size].mod = mod;
1437     return &dev->deviate[dev->deviate_size++];
1438 }
1439 
1440 int
yang_read_deviate_units(struct ly_ctx * ctx,struct lys_deviate * deviate,struct lys_node * dev_target)1441 yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
1442 {
1443     const char **stritem;
1444     int j;
1445 
1446     /* check target node type */
1447     if (dev_target->nodetype == LYS_LEAFLIST) {
1448         stritem = &((struct lys_node_leaflist *)dev_target)->units;
1449     } else if (dev_target->nodetype == LYS_LEAF) {
1450         stritem = &((struct lys_node_leaf *)dev_target)->units;
1451     } else {
1452         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1453         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
1454         goto error;
1455     }
1456 
1457     if (deviate->mod == LY_DEVIATE_DEL) {
1458         /* check values */
1459         if (!ly_strequal(*stritem, deviate->units, 1)) {
1460             LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
1461             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1462             goto error;
1463         }
1464         /* remove current units value of the target */
1465         lydict_remove(ctx, *stritem);
1466         *stritem = NULL;
1467         /* remove its extensions */
1468         j = -1;
1469         while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1470             lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1471             --j;
1472         }
1473     } else {
1474         if (deviate->mod == LY_DEVIATE_ADD) {
1475             /* check that there is no current value */
1476             if (*stritem) {
1477                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1478                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1479                 goto error;
1480             }
1481         } else { /* replace */
1482             if (!*stritem) {
1483                 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1484                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1485                 goto error;
1486             }
1487         }
1488         /* remove current units value of the target ... */
1489         lydict_remove(ctx, *stritem);
1490 
1491         /* ... and replace it with the value specified in deviation */
1492         *stritem = lydict_insert(ctx, deviate->units, 0);
1493     }
1494 
1495     return EXIT_SUCCESS;
1496 
1497 error:
1498     return EXIT_FAILURE;
1499 }
1500 
1501 int
yang_read_deviate_unique(struct lys_deviate * deviate,struct lys_node * dev_target)1502 yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
1503 {
1504     struct ly_ctx *ctx = dev_target->module->ctx;
1505     struct lys_node_list *list;
1506     struct lys_unique *unique;
1507 
1508     /* check target node type */
1509     if (dev_target->nodetype != LYS_LIST) {
1510         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1511         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
1512         goto error;
1513     }
1514 
1515     list = (struct lys_node_list *)dev_target;
1516     if (deviate->mod == LY_DEVIATE_ADD) {
1517         /* reallocate the unique array of the target */
1518         unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
1519         LY_CHECK_ERR_GOTO(!unique, LOGMEM(ctx), error);
1520         list->unique = unique;
1521         memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
1522     }
1523 
1524     return EXIT_SUCCESS;
1525 
1526 error:
1527     return EXIT_FAILURE;
1528 }
1529 
1530 int
yang_fill_deviate_default(struct ly_ctx * ctx,struct lys_deviate * deviate,struct lys_node * dev_target,struct ly_set * dflt_check,const char * value)1531 yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1532                           struct ly_set *dflt_check, const char *value)
1533 {
1534     struct lys_node *node;
1535     struct lys_node_choice *choice;
1536     struct lys_node_leaf *leaf;
1537     struct lys_node_leaflist *llist;
1538     enum int_log_opts prev_ilo;
1539     int rc, i, j;
1540     unsigned int u;
1541     const char *orig_dflt, *ptr;
1542 
1543     u = strlen(value);
1544     if (dev_target->nodetype == LYS_CHOICE) {
1545         choice = (struct lys_node_choice *)dev_target;
1546         rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1547         if (rc || !node) {
1548             LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1549             goto error;
1550         }
1551         if (deviate->mod == LY_DEVIATE_DEL) {
1552             if (!choice->dflt || (choice->dflt != node)) {
1553                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1554                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1555                 goto error;
1556             }
1557             choice->dflt = NULL;
1558             /* remove extensions of this default instance from the target node */
1559             j = -1;
1560             while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1561                 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1562                 --j;
1563             }
1564         } else { /* add or replace */
1565             choice->dflt = node;
1566             if (!choice->dflt) {
1567                 /* default branch not found */
1568                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1569                 goto error;
1570             }
1571         }
1572     } else if (dev_target->nodetype == LYS_LEAF) {
1573         leaf = (struct lys_node_leaf *)dev_target;
1574         if (deviate->mod == LY_DEVIATE_DEL) {
1575             orig_dflt = NULL;
1576             if (leaf->dflt) {
1577                 if (leaf->type.base == LY_TYPE_IDENT) {
1578                     /* skip prefixes, cannot be compared reliably */
1579                     if ((ptr = strchr(leaf->dflt, ':'))) {
1580                         orig_dflt = ptr + 1;
1581                     } else {
1582                         orig_dflt = leaf->dflt;
1583                     }
1584                     if ((ptr = strchr(value, ':'))) {
1585                         value = ptr + 1;
1586                     }
1587                 } else {
1588                     orig_dflt = leaf->dflt;
1589                 }
1590             }
1591             if (!orig_dflt || !ly_strequal(orig_dflt, value, 0)) {
1592                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1593                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1594                 goto error;
1595             }
1596 
1597             /* remove value */
1598             lydict_remove(ctx, leaf->dflt);
1599             leaf->dflt = NULL;
1600             leaf->flags &= ~LYS_DFLTJSON;
1601             /* remove extensions of this default instance from the target node */
1602             j = -1;
1603             while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1604                 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1605                 --j;
1606             }
1607         } else { /* add (already checked) and replace */
1608             /* remove value */
1609             lydict_remove(ctx, leaf->dflt);
1610             leaf->flags &= ~LYS_DFLTJSON;
1611 
1612             /* set new value */
1613             leaf->dflt = lydict_insert(ctx, value, u);
1614 
1615             /* remember to check it later (it may not fit now, but the type can be deviated too) */
1616             ly_set_add(dflt_check, dev_target, 0);
1617         }
1618     } else { /* LYS_LEAFLIST */
1619         llist = (struct lys_node_leaflist *)dev_target;
1620         if (deviate->mod == LY_DEVIATE_DEL) {
1621             /* find and remove the value in target list */
1622             for (i = 0; i < llist->dflt_size; i++) {
1623                 orig_dflt = NULL;
1624                 if (llist->dflt[i]) {
1625                     /* transform back into the original value */
1626                     ly_ilo_change(NULL, ILO_IGNORE, &prev_ilo, NULL);
1627                     orig_dflt = transform_json2schema(llist->module, llist->dflt[i]);
1628                     ly_ilo_restore(NULL, prev_ilo, NULL, 0);
1629                     if (!orig_dflt) {
1630                         orig_dflt = lydict_insert(ctx, llist->dflt[i], 0);
1631                     }
1632                 }
1633 
1634                 if (orig_dflt && ly_strequal(orig_dflt, value, 1)) {
1635                     lydict_remove(ctx, orig_dflt);
1636 
1637                     /* match, remove the value */
1638                     lydict_remove(llist->module->ctx, llist->dflt[i]);
1639                     llist->dflt[i] = NULL;
1640                     /* remove extensions of this default instance from the target node */
1641                     j = -1;
1642                     while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1643                         if (dev_target->ext[j]->insubstmt_index == i) {
1644                             lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1645                             --j;
1646                         } else if (dev_target->ext[j]->insubstmt_index > i) {
1647                             /* decrease the substatement index of the extension because of the changed array of defaults */
1648                             dev_target->ext[j]->insubstmt_index--;
1649                         }
1650                     }
1651                     break;
1652                 }
1653                 lydict_remove(ctx, orig_dflt);
1654             }
1655             if (i == llist->dflt_size) {
1656                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1657                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1658                 goto error;
1659             }
1660         } else {
1661             /* add or replace, anyway we place items into the deviate's list
1662                which propagates to the target */
1663             /* we just want to check that the value isn't already in the list */
1664             for (i = 0; i < llist->dflt_size; i++) {
1665                 if (ly_strequal(llist->dflt[i], value, 1)) {
1666                     LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1667                     LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1668                     goto error;
1669                 }
1670             }
1671             /* store it in target node */
1672             llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1673 
1674             /* remember to check it later (it may not fit now, but the type can be deviated too) */
1675             ly_set_add(dflt_check, dev_target, 0);
1676             llist->flags &= ~LYS_DFLTJSON;
1677         }
1678     }
1679 
1680     return EXIT_SUCCESS;
1681 
1682 error:
1683     return EXIT_FAILURE;
1684 }
1685 
1686 int
yang_read_deviate_default(struct lys_module * module,struct lys_deviate * deviate,struct lys_node * dev_target,struct ly_set * dflt_check)1687 yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1688                           struct lys_node *dev_target, struct ly_set * dflt_check)
1689 {
1690     struct ly_ctx *ctx = module->ctx;
1691     int i;
1692     struct lys_node_leaflist *llist;
1693     const char **dflt;
1694 
1695     /* check target node type */
1696     if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1697         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1698         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1699         goto error;
1700     } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1701         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1702         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1703         goto error;
1704     } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1705         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1706         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1707         goto error;
1708     }
1709 
1710     if (deviate->mod == LY_DEVIATE_ADD) {
1711         /* check that there is no current value */
1712         if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1713                 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1714             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1715             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1716             goto error;
1717         }
1718 
1719         /* check collision with mandatory/min-elements */
1720         if ((dev_target->flags & LYS_MAND_TRUE) ||
1721                 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1722             LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1723             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
1724                    "Adding the \"default\" statement is forbidden on %s statement.",
1725                    (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1726             goto error;
1727         }
1728     } else if (deviate->mod == LY_DEVIATE_RPL) {
1729         /* check that there was a value before */
1730         if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1731                 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1732             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1733             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1734             goto error;
1735         }
1736     }
1737 
1738     if (dev_target->nodetype == LYS_LEAFLIST) {
1739         /* reallocate default list in the target */
1740         llist = (struct lys_node_leaflist *)dev_target;
1741         if (deviate->mod == LY_DEVIATE_ADD) {
1742             /* reallocate (enlarge) the unique array of the target */
1743             dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
1744             LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
1745             llist->dflt = dflt;
1746         } else if (deviate->mod == LY_DEVIATE_RPL) {
1747             /* reallocate (replace) the unique array of the target */
1748             for (i = 0; i < llist->dflt_size; i++) {
1749                 lydict_remove(ctx, llist->dflt[i]);
1750             }
1751             dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
1752             LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
1753             llist->dflt = dflt;
1754             llist->dflt_size = 0;
1755         }
1756     }
1757 
1758     for (i = 0; i < deviate->dflt_size; ++i) {
1759         if (yang_fill_deviate_default(ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1760             goto error;
1761         }
1762     }
1763 
1764     return EXIT_SUCCESS;
1765 
1766 error:
1767     return EXIT_FAILURE;
1768 }
1769 
1770 int
yang_check_deviate_mandatory(struct lys_deviate * deviate,struct lys_node * dev_target)1771 yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
1772 {
1773     struct ly_ctx *ctx = dev_target->module->ctx;
1774     struct lys_node *parent;
1775 
1776     /* check target node type */
1777     if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
1778         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1779         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
1780         goto error;
1781     }
1782 
1783     if (deviate->mod == LY_DEVIATE_ADD) {
1784         /* check that there is no current value */
1785         if (dev_target->flags & LYS_MAND_MASK) {
1786             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1787             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1788             goto error;
1789         } else {
1790             if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
1791                 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1792                 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1793                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1794                 goto error;
1795             } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
1796                 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1797                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1798                 goto error;
1799             }
1800         }
1801     } else { /* replace */
1802         if (!(dev_target->flags & LYS_MAND_MASK)) {
1803             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1804             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1805             goto error;
1806         }
1807     }
1808 
1809     /* remove current mandatory value of the target ... */
1810     dev_target->flags &= ~LYS_MAND_MASK;
1811 
1812     /* ... and replace it with the value specified in deviation */
1813     dev_target->flags |= deviate->flags & LYS_MAND_MASK;
1814 
1815     /* check for mandatory node in default case, first find the closest parent choice to the changed node */
1816     for (parent = dev_target->parent;
1817          parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1818          parent = parent->parent) {
1819         if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1820             /* stop also on presence containers */
1821             break;
1822         }
1823     }
1824     /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1825     if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1826         if (lyp_check_mandatory_choice(parent)) {
1827             goto error;
1828         }
1829     }
1830 
1831     return EXIT_SUCCESS;
1832 
1833 error:
1834     return EXIT_FAILURE;
1835 }
1836 
1837 int
yang_read_deviate_minmax(struct lys_deviate * deviate,struct lys_node * dev_target,uint32_t value,int type)1838 yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
1839 {
1840     struct ly_ctx *ctx = dev_target->module->ctx;
1841     uint32_t *ui32val, *min, *max;
1842 
1843     /* check target node type */
1844     if (dev_target->nodetype == LYS_LEAFLIST) {
1845         max = &((struct lys_node_leaflist *)dev_target)->max;
1846         min = &((struct lys_node_leaflist *)dev_target)->min;
1847     } else if (dev_target->nodetype == LYS_LIST) {
1848         max = &((struct lys_node_list *)dev_target)->max;
1849         min = &((struct lys_node_list *)dev_target)->min;
1850     } else {
1851         LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1852         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"%s\" property.", (type) ? "max-elements" : "min-elements");
1853         goto error;
1854     }
1855 
1856     ui32val = (type) ? max : min;
1857     if (deviate->mod == LY_DEVIATE_ADD) {
1858         /* check that there is no current value */
1859         if (*ui32val) {
1860             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1861             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1862             goto error;
1863         }
1864     } else if (deviate->mod == LY_DEVIATE_RPL) {
1865         /* unfortunately, there is no way to check reliably that there
1866          * was a value before, it could have been the default */
1867     }
1868 
1869     /* add (already checked) and replace */
1870     /* set new value specified in deviation */
1871     *ui32val = value;
1872 
1873     /* check min-elements is smaller than max-elements */
1874     if (*max && *min > *max) {
1875         if (type) {
1876             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1877             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1878         } else {
1879             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1880             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1881         }
1882         goto error;
1883     }
1884 
1885     return EXIT_SUCCESS;
1886 
1887 error:
1888     return EXIT_FAILURE;
1889 }
1890 
1891 int
yang_check_deviate_must(struct lys_module * module,struct unres_schema * unres,struct lys_deviate * deviate,struct lys_node * dev_target)1892 yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1893                         struct lys_deviate *deviate, struct lys_node *dev_target)
1894 {
1895     struct ly_ctx *ctx = module->ctx;
1896     int i, j, erase_must = 1;
1897     struct lys_restr **trg_must, *must;
1898     uint8_t *trg_must_size;
1899 
1900     /* check target node type */
1901     switch (dev_target->nodetype) {
1902         case LYS_LEAF:
1903             trg_must = &((struct lys_node_leaf *)dev_target)->must;
1904             trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
1905             break;
1906         case LYS_CONTAINER:
1907             trg_must = &((struct lys_node_container *)dev_target)->must;
1908             trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1909             break;
1910         case LYS_LEAFLIST:
1911             trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1912             trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1913             break;
1914         case LYS_LIST:
1915             trg_must = &((struct lys_node_list *)dev_target)->must;
1916             trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1917             break;
1918         case LYS_ANYXML:
1919         case LYS_ANYDATA:
1920             trg_must = &((struct lys_node_anydata *)dev_target)->must;
1921             trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1922             break;
1923         default:
1924             LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1925             LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1926             goto error;
1927     }
1928 
1929     /* flag will be checked again, clear it for now */
1930     dev_target->flags &= ~(LYS_XPCONF_DEP | LYS_XPSTATE_DEP);
1931 
1932     if (deviate->mod == LY_DEVIATE_ADD) {
1933         /* reallocate the must array of the target */
1934         must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
1935         LY_CHECK_ERR_GOTO(!must, LOGMEM(ctx), error);
1936         *trg_must = must;
1937         memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
1938         *trg_must_size = *trg_must_size + deviate->must_size;
1939         erase_must = 0;
1940     } else if (deviate->mod == LY_DEVIATE_DEL) {
1941         /* find must to delete, we are ok with just matching conditions */
1942         for (j = 0; j < deviate->must_size; ++j) {
1943             for (i = 0; i < *trg_must_size; i++) {
1944                 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1945                     /* we have a match, free the must structure ... */
1946                     lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
1947                     /* ... and maintain the array */
1948                     (*trg_must_size)--;
1949                     if (i != *trg_must_size) {
1950                         memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
1951                     }
1952                     if (!(*trg_must_size)) {
1953                         free(*trg_must);
1954                         *trg_must = NULL;
1955                     } else {
1956                         memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
1957                     }
1958 
1959                     i = -1; /* set match flag */
1960                     break;
1961                 }
1962             }
1963             if (i != -1) {
1964                 /* no match found */
1965                 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1966                 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1967                 goto error;
1968             }
1969         }
1970     }
1971 
1972     if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1973         goto error;
1974     }
1975     /* check XPath dependencies */
1976     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1977             && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
1978         goto error;
1979     }
1980 
1981     return EXIT_SUCCESS;
1982 
1983 error:
1984     if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1985         for (i = 0; i < deviate->must_size; ++i) {
1986             lys_restr_free(module->ctx, &deviate->must[i], NULL);
1987         }
1988         free(deviate->must);
1989     }
1990     return EXIT_FAILURE;
1991 }
1992 
1993 int
yang_deviate_delete_unique(struct lys_module * module,struct lys_deviate * deviate,struct lys_node_list * list,int index,char * value)1994 yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1995                            struct lys_node_list *list, int index, char * value)
1996 {
1997     struct ly_ctx *ctx = module->ctx;
1998     int i, j, k = 0;
1999 
2000     /* find unique structures to delete */
2001     for (i = 0; i < list->unique_size; i++) {
2002         if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
2003             continue;
2004         }
2005 
2006         for (j = 0; j < deviate->unique[index].expr_size; j++) {
2007             if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
2008                 break;
2009             }
2010         }
2011 
2012         if (j == deviate->unique[index].expr_size) {
2013             /* we have a match, free the unique structure ... */
2014             for (j = 0; j < list->unique[i].expr_size; j++) {
2015                 lydict_remove(ctx, list->unique[i].expr[j]);
2016             }
2017             free(list->unique[i].expr);
2018             /* ... and maintain the array */
2019             list->unique_size--;
2020             if (i != list->unique_size) {
2021                 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
2022                 list->unique[i].expr = list->unique[list->unique_size].expr;
2023             }
2024 
2025             if (!list->unique_size) {
2026                 free(list->unique);
2027                 list->unique = NULL;
2028             } else {
2029                 list->unique[list->unique_size].expr_size = 0;
2030                 list->unique[list->unique_size].expr = NULL;
2031             }
2032 
2033             k = i; /* remember index for removing extensions */
2034             i = -1; /* set match flag */
2035             break;
2036         }
2037     }
2038 
2039     if (i != -1) {
2040         /* no match found */
2041         LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
2042         LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
2043         return EXIT_FAILURE;
2044     }
2045 
2046     /* remove extensions of this unique instance from the target node */
2047     j = -1;
2048     while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
2049         if (list->ext[j]->insubstmt_index == k) {
2050             lyp_ext_instance_rm(ctx, &list->ext, &list->ext_size, j);
2051             --j;
2052         } else if (list->ext[j]->insubstmt_index > k) {
2053             /* decrease the substatement index of the extension because of the changed array of uniques */
2054             list->ext[j]->insubstmt_index--;
2055         }
2056     }
2057     return EXIT_SUCCESS;
2058 }
2059 
yang_check_deviate_unique(struct lys_module * module,struct lys_deviate * deviate,struct lys_node * dev_target)2060 int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
2061 {
2062     struct lys_node_list *list;
2063     char *str;
2064     uint i = 0;
2065     struct lys_unique *last_unique = NULL;
2066 
2067     if (yang_read_deviate_unique(deviate, dev_target)) {
2068         goto error;
2069     }
2070     list = (struct lys_node_list *)dev_target;
2071     last_unique = &list->unique[list->unique_size];
2072     for (i = 0; i < deviate->unique_size; ++i) {
2073         str = (char *) deviate->unique[i].expr;
2074         if (deviate->mod == LY_DEVIATE_ADD) {
2075             if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2076                 free(str);
2077                 goto error;
2078             }
2079             list->unique_size++;
2080         } else if (deviate->mod == LY_DEVIATE_DEL) {
2081             if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2082                 free(str);
2083                 goto error;
2084             }
2085             if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2086                 free(str);
2087                 goto error;
2088             }
2089         }
2090         free(str);
2091     }
2092     if (deviate->mod == LY_DEVIATE_ADD) {
2093         free(deviate->unique);
2094         deviate->unique = last_unique;
2095     }
2096 
2097     return EXIT_SUCCESS;
2098 
2099 error:
2100     if (deviate->mod == LY_DEVIATE_ADD) {
2101         for (i = i + 1; i < deviate->unique_size; ++i) {
2102             free(deviate->unique[i].expr);
2103         }
2104         free(deviate->unique);
2105         deviate->unique = last_unique;
2106 
2107     }
2108     return EXIT_FAILURE;
2109 }
2110 
2111 static int
yang_fill_include(struct lys_module * trg,char * value,struct lys_include * inc,struct unres_schema * unres)2112 yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2113                   struct unres_schema *unres)
2114 {
2115     const char *str;
2116     int rc;
2117     int ret = 0;
2118 
2119     str = lydict_insert_zc(trg->ctx, value);
2120     rc = lyp_check_include(trg, str, inc, unres);
2121     if (!rc) {
2122         /* success, copy the filled data into the final array */
2123         memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
2124         if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, &trg->inc[trg->inc_size].ext_size,
2125                                     &trg->inc[trg->inc_size], unres)) {
2126             ret = -1;
2127         }
2128         trg->inc_size++;
2129     } else if (rc == -1) {
2130         lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
2131         ret = -1;
2132     }
2133 
2134     lydict_remove(trg->ctx, str);
2135     return ret;
2136 }
2137 
2138 struct lys_ext_instance *
yang_ext_instance(void * node,enum yytokentype type,int is_ext_instance)2139 yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
2140 {
2141     struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2142     LYEXT_PAR parent_type;
2143     uint8_t *size;
2144 
2145     switch (type) {
2146     case MODULE_KEYWORD:
2147     case SUBMODULE_KEYWORD:
2148         ext = &((struct lys_module *)node)->ext;
2149         size = &((struct lys_module *)node)->ext_size;
2150         parent_type = LYEXT_PAR_MODULE;
2151         break;
2152     case BELONGS_TO_KEYWORD:
2153         if (is_ext_instance) {
2154             ext = &((struct lys_ext_instance *)node)->ext;
2155             size = &((struct lys_ext_instance *)node)->ext_size;
2156             parent_type = LYEXT_PAR_EXTINST;
2157         } else {
2158             ext = &((struct lys_module *)node)->ext;
2159             size = &((struct lys_module *)node)->ext_size;
2160             parent_type = LYEXT_PAR_MODULE;
2161         }
2162         break;
2163     case IMPORT_KEYWORD:
2164         ext = &((struct lys_import *)node)->ext;
2165         size = &((struct lys_import *)node)->ext_size;
2166         parent_type = LYEXT_PAR_IMPORT;
2167         break;
2168     case INCLUDE_KEYWORD:
2169         ext = &((struct lys_include *)node)->ext;
2170         size = &((struct lys_include *)node)->ext_size;
2171         parent_type = LYEXT_PAR_INCLUDE;
2172         break;
2173     case REVISION_KEYWORD:
2174         ext = &((struct lys_revision *)node)->ext;
2175         size = &((struct lys_revision *)node)->ext_size;
2176         parent_type = LYEXT_PAR_REVISION;
2177         break;
2178     case GROUPING_KEYWORD:
2179     case CONTAINER_KEYWORD:
2180     case LEAF_KEYWORD:
2181     case LEAF_LIST_KEYWORD:
2182     case LIST_KEYWORD:
2183     case CHOICE_KEYWORD:
2184     case CASE_KEYWORD:
2185     case ANYXML_KEYWORD:
2186     case ANYDATA_KEYWORD:
2187     case USES_KEYWORD:
2188     case AUGMENT_KEYWORD:
2189     case ACTION_KEYWORD:
2190     case RPC_KEYWORD:
2191     case INPUT_KEYWORD:
2192     case OUTPUT_KEYWORD:
2193     case NOTIFICATION_KEYWORD:
2194         ext = &((struct lys_node *)node)->ext;
2195         size = &((struct lys_node *)node)->ext_size;
2196         parent_type = LYEXT_PAR_NODE;
2197         break;
2198     case ARGUMENT_KEYWORD:
2199         if (is_ext_instance) {
2200             ext = &((struct lys_ext_instance *)node)->ext;
2201             size = &((struct lys_ext_instance *)node)->ext_size;
2202             parent_type = LYEXT_PAR_EXTINST;
2203         } else {
2204             ext = &((struct lys_ext *)node)->ext;
2205             size = &((struct lys_ext *)node)->ext_size;
2206             parent_type = LYEXT_PAR_EXT;
2207         }
2208         break;
2209     case EXTENSION_KEYWORD:
2210         ext = &((struct lys_ext *)node)->ext;
2211         size = &((struct lys_ext *)node)->ext_size;
2212         parent_type = LYEXT_PAR_EXT;
2213         break;
2214     case FEATURE_KEYWORD:
2215         ext = &((struct lys_feature *)node)->ext;
2216         size = &((struct lys_feature *)node)->ext_size;
2217         parent_type = LYEXT_PAR_FEATURE;
2218         break;
2219     case IDENTITY_KEYWORD:
2220         ext = &((struct lys_ident *)node)->ext;
2221         size = &((struct lys_ident *)node)->ext_size;
2222         parent_type = LYEXT_PAR_IDENT;
2223         break;
2224     case IF_FEATURE_KEYWORD:
2225         ext = &((struct lys_iffeature *)node)->ext;
2226         size = &((struct lys_iffeature *)node)->ext_size;
2227         parent_type = LYEXT_PAR_IFFEATURE;
2228         break;
2229     case TYPEDEF_KEYWORD:
2230         ext = &((struct lys_tpdf *)node)->ext;
2231         size = &((struct lys_tpdf *)node)->ext_size;
2232         parent_type = LYEXT_PAR_TPDF;
2233         break;
2234     case TYPE_KEYWORD:
2235         ext = &((struct yang_type *)node)->type->ext;
2236         size = &((struct yang_type *)node)->type->ext_size;
2237         parent_type = LYEXT_PAR_TYPE;
2238         break;
2239     case LENGTH_KEYWORD:
2240     case PATTERN_KEYWORD:
2241     case RANGE_KEYWORD:
2242     case MUST_KEYWORD:
2243         ext = &((struct lys_restr *)node)->ext;
2244         size = &((struct lys_restr *)node)->ext_size;
2245         parent_type = LYEXT_PAR_RESTR;
2246         break;
2247     case WHEN_KEYWORD:
2248         ext = &((struct lys_when *)node)->ext;
2249         size = &((struct lys_when *)node)->ext_size;
2250         parent_type = LYEXT_PAR_RESTR;
2251         break;
2252     case ENUM_KEYWORD:
2253         ext = &((struct lys_type_enum *)node)->ext;
2254         size = &((struct lys_type_enum *)node)->ext_size;
2255         parent_type = LYEXT_PAR_TYPE_ENUM;
2256         break;
2257     case BIT_KEYWORD:
2258         ext = &((struct lys_type_bit *)node)->ext;
2259         size = &((struct lys_type_bit *)node)->ext_size;
2260         parent_type = LYEXT_PAR_TYPE_BIT;
2261         break;
2262     case REFINE_KEYWORD:
2263         ext = &((struct lys_type_bit *)node)->ext;
2264         size = &((struct lys_type_bit *)node)->ext_size;
2265         parent_type = LYEXT_PAR_REFINE;
2266         break;
2267     case DEVIATION_KEYWORD:
2268         ext = &((struct lys_deviation *)node)->ext;
2269         size = &((struct lys_deviation *)node)->ext_size;
2270         parent_type = LYEXT_PAR_DEVIATION;
2271         break;
2272     case NOT_SUPPORTED_KEYWORD:
2273     case ADD_KEYWORD:
2274     case DELETE_KEYWORD:
2275     case REPLACE_KEYWORD:
2276         ext = &((struct lys_deviate *)node)->ext;
2277         size = &((struct lys_deviate *)node)->ext_size;
2278         parent_type = LYEXT_PAR_DEVIATE;
2279         break;
2280     case EXTENSION_INSTANCE:
2281         ext = &((struct lys_ext_instance *)node)->ext;
2282         size = &((struct lys_ext_instance *)node)->ext_size;
2283         parent_type = LYEXT_PAR_EXTINST;
2284         break;
2285     default:
2286         LOGINT(NULL);
2287         return NULL;
2288     }
2289 
2290     instance = calloc(1, sizeof *instance);
2291     if (!instance) {
2292         goto error;
2293     }
2294     instance->parent_type = parent_type;
2295     tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2296     if (!tmp) {
2297         goto error;
2298     }
2299     tmp[*size] = instance;
2300     *ext = tmp;
2301     (*size)++;
2302     return instance;
2303 
2304 error:
2305     LOGMEM(NULL);
2306     free(instance);
2307     return NULL;
2308 }
2309 
2310 void *
yang_read_ext(struct lys_module * module,void * actual,char * ext_name,char * ext_arg,enum yytokentype actual_type,enum yytokentype backup_type,int is_ext_instance)2311 yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
2312               enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
2313 {
2314     struct lys_ext_instance *instance;
2315     LY_STMT stmt = LY_STMT_UNKNOWN;
2316     LYEXT_SUBSTMT insubstmt;
2317     uint8_t insubstmt_index = 0;
2318 
2319     if (backup_type != NODE) {
2320         switch (actual_type) {
2321         case YANG_VERSION_KEYWORD:
2322             insubstmt = LYEXT_SUBSTMT_VERSION;
2323             stmt = LY_STMT_VERSION;
2324             break;
2325         case NAMESPACE_KEYWORD:
2326             insubstmt = LYEXT_SUBSTMT_NAMESPACE;
2327             stmt = LY_STMT_NAMESPACE;
2328             break;
2329         case PREFIX_KEYWORD:
2330             insubstmt = LYEXT_SUBSTMT_PREFIX;
2331             stmt = LY_STMT_PREFIX;
2332             break;
2333         case REVISION_DATE_KEYWORD:
2334             insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
2335             stmt = LY_STMT_REVISIONDATE;
2336             break;
2337         case DESCRIPTION_KEYWORD:
2338             insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
2339             stmt = LY_STMT_DESCRIPTION;
2340             break;
2341         case REFERENCE_KEYWORD:
2342             insubstmt = LYEXT_SUBSTMT_REFERENCE;
2343             stmt = LY_STMT_REFERENCE;
2344             break;
2345         case CONTACT_KEYWORD:
2346             insubstmt = LYEXT_SUBSTMT_CONTACT;
2347             stmt = LY_STMT_CONTACT;
2348             break;
2349         case ORGANIZATION_KEYWORD:
2350             insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
2351             stmt = LY_STMT_ORGANIZATION;
2352             break;
2353         case YIN_ELEMENT_KEYWORD:
2354             insubstmt = LYEXT_SUBSTMT_YINELEM;
2355             stmt = LY_STMT_YINELEM;
2356             break;
2357         case STATUS_KEYWORD:
2358             insubstmt = LYEXT_SUBSTMT_STATUS;
2359             stmt = LY_STMT_STATUS;
2360             break;
2361         case BASE_KEYWORD:
2362             insubstmt = LYEXT_SUBSTMT_BASE;
2363             stmt = LY_STMT_BASE;
2364             if (backup_type == IDENTITY_KEYWORD) {
2365                 insubstmt_index = ((struct lys_ident *)actual)->base_size;
2366             } else if (backup_type == TYPE_KEYWORD) {
2367                 insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2368             }
2369             break;
2370         case DEFAULT_KEYWORD:
2371             insubstmt = LYEXT_SUBSTMT_DEFAULT;
2372             stmt = LY_STMT_DEFAULT;
2373             switch (backup_type) {
2374             case LEAF_LIST_KEYWORD:
2375                 insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
2376                 break;
2377             case REFINE_KEYWORD:
2378                 insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
2379                 break;
2380             case ADD_KEYWORD:
2381                 insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2382                 break;
2383             default:
2384                 /* nothing changes */
2385                 break;
2386             }
2387             break;
2388         case UNITS_KEYWORD:
2389             insubstmt = LYEXT_SUBSTMT_UNITS;
2390             stmt = LY_STMT_UNITS;
2391             break;
2392         case REQUIRE_INSTANCE_KEYWORD:
2393             insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
2394             stmt = LY_STMT_REQINSTANCE;
2395             break;
2396         case PATH_KEYWORD:
2397             insubstmt = LYEXT_SUBSTMT_PATH;
2398             stmt = LY_STMT_PATH;
2399             break;
2400         case ERROR_MESSAGE_KEYWORD:
2401             insubstmt = LYEXT_SUBSTMT_ERRMSG;
2402             stmt = LY_STMT_ERRMSG;
2403             break;
2404         case ERROR_APP_TAG_KEYWORD:
2405             insubstmt = LYEXT_SUBSTMT_ERRTAG;
2406             stmt = LY_STMT_ERRTAG;
2407             break;
2408         case MODIFIER_KEYWORD:
2409             insubstmt = LYEXT_SUBSTMT_MODIFIER;
2410             stmt = LY_STMT_MODIFIER;
2411             break;
2412         case FRACTION_DIGITS_KEYWORD:
2413             insubstmt = LYEXT_SUBSTMT_DIGITS;
2414             stmt = LY_STMT_DIGITS;
2415             break;
2416         case VALUE_KEYWORD:
2417             insubstmt = LYEXT_SUBSTMT_VALUE;
2418             stmt = LY_STMT_VALUE;
2419             break;
2420         case POSITION_KEYWORD:
2421             insubstmt = LYEXT_SUBSTMT_POSITION;
2422             stmt = LY_STMT_POSITION;
2423             break;
2424         case PRESENCE_KEYWORD:
2425             insubstmt = LYEXT_SUBSTMT_PRESENCE;
2426             stmt = LY_STMT_PRESENCE;
2427             break;
2428         case CONFIG_KEYWORD:
2429             insubstmt = LYEXT_SUBSTMT_CONFIG;
2430             stmt = LY_STMT_CONFIG;
2431             break;
2432         case MANDATORY_KEYWORD:
2433             insubstmt = LYEXT_SUBSTMT_MANDATORY;
2434             stmt = LY_STMT_MANDATORY;
2435             break;
2436         case MIN_ELEMENTS_KEYWORD:
2437             insubstmt = LYEXT_SUBSTMT_MIN;
2438             stmt = LY_STMT_MIN;
2439             break;
2440         case MAX_ELEMENTS_KEYWORD:
2441             insubstmt = LYEXT_SUBSTMT_MAX;
2442             stmt = LY_STMT_MAX;
2443             break;
2444         case ORDERED_BY_KEYWORD:
2445             insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
2446             stmt = LY_STMT_ORDEREDBY;
2447             break;
2448         case KEY_KEYWORD:
2449             insubstmt = LYEXT_SUBSTMT_KEY;
2450             stmt = LY_STMT_KEY;
2451             break;
2452         case UNIQUE_KEYWORD:
2453             insubstmt = LYEXT_SUBSTMT_UNIQUE;
2454             stmt = LY_STMT_UNIQUE;
2455             switch (backup_type) {
2456             case LIST_KEYWORD:
2457                 insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
2458                 break;
2459             case ADD_KEYWORD:
2460             case DELETE_KEYWORD:
2461             case REPLACE_KEYWORD:
2462                 insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
2463                 break;
2464             default:
2465                 /* nothing changes */
2466                 break;
2467             }
2468             break;
2469         default:
2470             LOGINT(module->ctx);
2471             return NULL;
2472         }
2473 
2474         instance = yang_ext_instance(actual, backup_type, is_ext_instance);
2475     } else {
2476         switch (actual_type) {
2477         case ARGUMENT_KEYWORD:
2478             insubstmt = LYEXT_SUBSTMT_ARGUMENT;
2479             stmt = LY_STMT_ARGUMENT;
2480             break;
2481         case BELONGS_TO_KEYWORD:
2482             insubstmt = LYEXT_SUBSTMT_BELONGSTO;
2483             stmt = LY_STMT_BELONGSTO;
2484             break;
2485         default:
2486             insubstmt = LYEXT_SUBSTMT_SELF;
2487             break;
2488         }
2489 
2490         instance = yang_ext_instance(actual, actual_type, is_ext_instance);
2491     }
2492 
2493     if (!instance) {
2494         return NULL;
2495     }
2496     instance->insubstmt = insubstmt;
2497     instance->insubstmt_index = insubstmt_index;
2498     instance->flags |= LYEXT_OPT_YANG;
2499     instance->def = (struct lys_ext *)ext_name;    /* hack for UNRES */
2500     instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
2501     if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2502         instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2503     }
2504     return instance;
2505 }
2506 
2507 static int
check_status_flag(struct lys_node * node,struct lys_node * parent)2508 check_status_flag(struct lys_node *node, struct lys_node *parent)
2509 {
2510     struct ly_ctx *ctx = node->module->ctx;
2511     char *str;
2512 
2513     if (node->nodetype & (LYS_OUTPUT | LYS_INPUT)) {
2514         return EXIT_SUCCESS;
2515     }
2516 
2517     if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2518         /* status is not inherited by specification, but it not make sense to have
2519          * current in deprecated or deprecated in obsolete, so we print warning
2520          * and fix the schema by inheriting */
2521         if (!(node->flags & (LYS_STATUS_MASK))) {
2522             /* status not explicitely specified on the current node -> inherit */
2523             str = lys_path(node, LYS_PATH_FIRST_PREFIX);
2524             LOGWRN(ctx, "Missing status in %s subtree (%s), inheriting.",
2525                    parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2526             free(str);
2527             node->flags |= parent->flags & LYS_STATUS_MASK;
2528         } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2529             /* invalid combination of statuses */
2530             switch (node->flags & LYS_STATUS_MASK) {
2531                 case 0:
2532                 case LYS_STATUS_CURR:
2533                     LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
2534                            parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2535                     break;
2536                 case LYS_STATUS_DEPRC:
2537                     LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
2538                            "obsolete", parent->name);
2539                     break;
2540             }
2541             return EXIT_FAILURE;
2542         }
2543     }
2544 
2545     return EXIT_SUCCESS;
2546 }
2547 
2548 int
store_config_flag(struct lys_node * node,int options)2549 store_config_flag(struct lys_node *node, int options)
2550 {
2551     switch (node->nodetype) {
2552     case LYS_CONTAINER:
2553     case LYS_LEAF:
2554     case LYS_LEAFLIST:
2555     case LYS_LIST:
2556     case LYS_CHOICE:
2557     case LYS_ANYDATA:
2558     case LYS_ANYXML:
2559         if (options & LYS_PARSE_OPT_CFG_IGNORE) {
2560             node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
2561         } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
2562             if (!(node->flags & LYS_CONFIG_MASK)) {
2563                 /* get config flag from parent */
2564                 if (node->parent) {
2565                     node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2566                 } else {
2567                     /* default config is true */
2568                     node->flags |= LYS_CONFIG_W;
2569                 }
2570             }
2571         }
2572         break;
2573     case LYS_CASE:
2574         if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
2575             if (!(node->flags & LYS_CONFIG_MASK)) {
2576                 /* get config flag from parent */
2577                 if (node->parent) {
2578                     node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2579                 } else {
2580                     /* default config is true */
2581                     node->flags |= LYS_CONFIG_W;
2582                 }
2583             }
2584         }
2585         break;
2586     default:
2587         break;
2588     }
2589 
2590     return EXIT_SUCCESS;
2591 }
2592 
2593 int
yang_parse_mem(struct lys_module * module,struct lys_submodule * submodule,struct unres_schema * unres,const char * data,unsigned int size_data,struct lys_node ** node)2594 yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2595                const char *data, unsigned int size_data, struct lys_node **node)
2596 {
2597     unsigned int size;
2598     YY_BUFFER_STATE bp;
2599     yyscan_t scanner = NULL;
2600     int ret = 0;
2601     struct lys_module *trg;
2602     struct yang_parameter param;
2603 
2604     size = (size_data) ? size_data : strlen(data) + 2;
2605     yylex_init(&scanner);
2606     yyset_extra(module->ctx, scanner);
2607     bp = yy_scan_buffer((char *)data, size, scanner);
2608     yy_switch_to_buffer(bp, scanner);
2609     memset(&param, 0, sizeof param);
2610     param.module = module;
2611     param.submodule = submodule;
2612     param.unres = unres;
2613     param.node = node;
2614     param.flags |= YANG_REMOVE_IMPORT;
2615     if (yyparse(scanner, &param)) {
2616         if (param.flags & YANG_REMOVE_IMPORT) {
2617             trg = (submodule) ? (struct lys_module *)submodule : module;
2618             yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2619             yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2620             trg->inc_size = 0;
2621             trg->imp_size = 0;
2622         }
2623         ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2624     }
2625     yy_delete_buffer(bp, scanner);
2626     yylex_destroy(scanner);
2627     return ret;
2628 }
2629 
2630 int
yang_parse_ext_substatement(struct lys_module * module,struct unres_schema * unres,const char * data,char * ext_name,struct lys_ext_instance_complex * ext)2631 yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2632                             char *ext_name, struct lys_ext_instance_complex *ext)
2633 {
2634     unsigned int size;
2635     YY_BUFFER_STATE bp;
2636     yyscan_t scanner = NULL;
2637     int ret = 0;
2638     struct yang_parameter param;
2639     struct lys_node *node = NULL;
2640 
2641     if (!data) {
2642         return EXIT_SUCCESS;
2643     }
2644     size = strlen(data) + 2;
2645     yylex_init(&scanner);
2646     bp = yy_scan_buffer((char *)data, size, scanner);
2647     yy_switch_to_buffer(bp, scanner);
2648     memset(&param, 0, sizeof param);
2649     param.module = module;
2650     param.unres = unres;
2651     param.node = &node;
2652     param.actual_node = (void **)ext;
2653     param.data_node = (void **)ext_name;
2654     param.flags |= EXT_INSTANCE_SUBSTMT;
2655     if (yyparse(scanner, &param)) {
2656         yang_free_nodes(module->ctx, node);
2657         ret = -1;
2658     } else {
2659         /* success parse, but it needs some sematic controls */
2660         if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
2661             ret = -1;
2662         }
2663     }
2664     yy_delete_buffer(bp, scanner);
2665     yylex_destroy(scanner);
2666     return ret;
2667 }
2668 
2669 struct lys_module *
yang_read_module(struct ly_ctx * ctx,const char * data,unsigned int size,const char * revision,int implement)2670 yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
2671 {
2672     struct lys_module *module = NULL, *tmp_mod;
2673     struct unres_schema *unres = NULL;
2674     struct lys_node *node = NULL;
2675     int ret;
2676 
2677     unres = calloc(1, sizeof *unres);
2678     LY_CHECK_ERR_GOTO(!unres, LOGMEM(ctx), error);
2679 
2680     module = calloc(1, sizeof *module);
2681     LY_CHECK_ERR_GOTO(!module, LOGMEM(ctx), error);
2682 
2683     /* initiale module */
2684     module->ctx = ctx;
2685     module->type = 0;
2686     module->implemented = (implement ? 1 : 0);
2687 
2688     /* add into the list of processed modules */
2689     if (lyp_check_circmod_add(module)) {
2690         goto error;
2691     }
2692 
2693     ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2694     if (ret == -1) {
2695         if (ly_vecode(ctx) == LYVE_SUBMODULE && !module->name) {
2696             /* Remove this module from the list of processed modules,
2697                as we're about to free it */
2698             lyp_check_circmod_pop(ctx);
2699 
2700             free(module);
2701             module = NULL;
2702         } else {
2703             free_yang_common(module, node);
2704         }
2705         goto error;
2706     } else if (ret == 1) {
2707         assert(!unres->count);
2708     } else {
2709         if (yang_check_sub_module(module, unres, node)) {
2710             goto error;
2711         }
2712 
2713         if (!implement && module->implemented && lys_make_implemented_r(module, unres)) {
2714             goto error;
2715         }
2716 
2717         if (unres->count && resolve_unres_schema(module, unres)) {
2718             goto error;
2719         }
2720 
2721         /* check correctness of includes */
2722         if (lyp_check_include_missing(module)) {
2723             goto error;
2724         }
2725     }
2726 
2727     lyp_sort_revisions(module);
2728 
2729     if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
2730         goto error;
2731     }
2732 
2733     if (revision) {
2734         /* check revision of the parsed model */
2735         if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2736             LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2737                    module->name, module->rev[0].date, revision);
2738             goto error;
2739         }
2740     }
2741 
2742     /* add into context if not already there */
2743     if (!ret) {
2744         if (lyp_ctx_add_module(module)) {
2745             goto error;
2746         }
2747 
2748         /* remove our submodules from the parsed submodules list */
2749         lyp_del_includedup(module, 0);
2750     } else {
2751         tmp_mod = module;
2752 
2753         /* get the model from the context */
2754         module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
2755         assert(module);
2756 
2757         /* free what was parsed */
2758         lys_free(tmp_mod, NULL, 0, 0);
2759     }
2760 
2761     unres_schema_free(NULL, &unres, 0);
2762     lyp_check_circmod_pop(ctx);
2763     LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2764            (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
2765     return module;
2766 
2767 error:
2768     /* cleanup */
2769     unres_schema_free(module, &unres, 1);
2770 
2771     if (!module) {
2772         if (ly_vecode(ctx) != LYVE_SUBMODULE) {
2773             LOGERR(ctx, ly_errno, "Module parsing failed.");
2774         }
2775         return NULL;
2776     }
2777 
2778     if (module->name) {
2779         LOGERR(ctx, ly_errno, "Module \"%s\" parsing failed.", module->name);
2780     } else {
2781         LOGERR(ctx, ly_errno, "Module parsing failed.");
2782     }
2783 
2784     lyp_check_circmod_pop(ctx);
2785     lys_sub_module_remove_devs_augs(module);
2786     lyp_del_includedup(module, 1);
2787     lys_free(module, NULL, 0, 1);
2788     return NULL;
2789 }
2790 
2791 struct lys_submodule *
yang_read_submodule(struct lys_module * module,const char * data,unsigned int size,struct unres_schema * unres)2792 yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
2793 {
2794     struct lys_submodule *submodule;
2795     struct lys_node *node = NULL;
2796 
2797     submodule = calloc(1, sizeof *submodule);
2798     LY_CHECK_ERR_GOTO(!submodule, LOGMEM(module->ctx), error);
2799 
2800     submodule->ctx = module->ctx;
2801     submodule->type = 1;
2802     submodule->implemented = module->implemented;
2803     submodule->belongsto = module;
2804 
2805     /* add into the list of processed modules */
2806     if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2807         goto error;
2808     }
2809 
2810     /* module cannot be changed in this case and 1 cannot be returned */
2811     if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
2812         free_yang_common((struct lys_module *)submodule, node);
2813         goto error;
2814     }
2815 
2816     lyp_sort_revisions((struct lys_module *)submodule);
2817 
2818     if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
2819         goto error;
2820     }
2821 
2822     lyp_check_circmod_pop(module->ctx);
2823 
2824     LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
2825     return submodule;
2826 
2827 error:
2828     /* cleanup */
2829     if (!submodule || !submodule->name) {
2830         free(submodule);
2831         LOGERR(module->ctx, ly_errno, "Submodule parsing failed.");
2832         return NULL;
2833     }
2834 
2835     LOGERR(module->ctx, ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2836 
2837     unres_schema_free((struct lys_module *)submodule, &unres, 0);
2838     lyp_check_circmod_pop(module->ctx);
2839     lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2840     lys_submodule_module_data_free(submodule);
2841     lys_submodule_free(submodule, NULL);
2842     return NULL;
2843 }
2844 
2845 static int
read_indent(const char * input,int indent,int size,int in_index,int * out_index,char * output)2846 read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2847 {
2848     int k = 0, j;
2849 
2850     while (in_index < size) {
2851         if (input[in_index] == ' ') {
2852             k++;
2853         } else if (input[in_index] == '\t') {
2854             /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2855             k += 8;
2856         } else {
2857             break;
2858         }
2859         ++in_index;
2860         if (k >= indent) {
2861             for (j = k - indent; j > 0; --j) {
2862                 ++(*out_index);
2863                 output[*out_index] = ' ';
2864             }
2865             break;
2866         }
2867     }
2868     return in_index - 1;
2869 }
2870 
2871 char *
yang_read_string(struct ly_ctx * ctx,const char * input,char * output,int size,int offset,int indent)2872 yang_read_string(struct ly_ctx *ctx, const char *input, char *output, int size, int offset, int indent)
2873 {
2874     int i = 0, out_index = offset, space = 0;
2875 
2876     while (i < size) {
2877         switch (input[i]) {
2878         case '\n':
2879             out_index -= space;
2880             output[out_index] = '\n';
2881             space = 0;
2882             i = read_indent(input, indent, size, i + 1, &out_index, output);
2883             break;
2884         case ' ':
2885         case '\t':
2886             output[out_index] = input[i];
2887             ++space;
2888             break;
2889         case '\\':
2890             space = 0;
2891             if (input[i + 1] == 'n') {
2892                 output[out_index] = '\n';
2893             } else if (input[i + 1] == 't') {
2894                 output[out_index] = '\t';
2895             } else if (input[i + 1] == '\\') {
2896                 output[out_index] = '\\';
2897             } else if ((i + 1) != size && input[i + 1] == '"') {
2898                 output[out_index] = '"';
2899             } else {
2900                 /* backslash must not be followed by any other character */
2901                 LOGVAL(ctx, LYE_XML_INCHAR, LY_VLOG_NONE, NULL, input + i);
2902                 return NULL;
2903             }
2904             ++i;
2905             break;
2906         default:
2907             output[out_index] = input[i];
2908             space = 0;
2909             break;
2910         }
2911         ++i;
2912         ++out_index;
2913     }
2914     output[out_index] = '\0';
2915     if (size != out_index) {
2916         output = realloc(output, out_index + 1);
2917         LY_CHECK_ERR_RETURN(!output, LOGMEM(ctx), NULL);
2918     }
2919     return output;
2920 }
2921 
2922 /* free function */
2923 
2924 void
yang_type_free(struct ly_ctx * ctx,struct lys_type * type)2925 yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
2926 {
2927     struct yang_type *stype = (struct yang_type *)type->der;
2928     unsigned int i;
2929 
2930     if (!stype) {
2931         return ;
2932     }
2933     if (type->base == LY_TYPE_DER || type->base == LY_TYPE_UNION) {
2934         lydict_remove(ctx, stype->name);
2935         if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2936             for (i = 0; i < type->info.ident.count; ++i) {
2937                 free(type->info.ident.ref[i]);
2938             }
2939         }
2940         if (stype->base == LY_TYPE_UNION) {
2941             for (i = 0; i < type->info.uni.count; ++i) {
2942                 yang_type_free(ctx, &type->info.uni.types[i]);
2943             }
2944             free(type->info.uni.types);
2945             type->base = LY_TYPE_DER;
2946         } else {
2947             type->base = stype->base;
2948         }
2949         free(stype);
2950         type->der = NULL;
2951     }
2952     lys_type_free(ctx, type, NULL);
2953     memset(type, 0, sizeof (struct lys_type));
2954 }
2955 
2956 static void
yang_tpdf_free(struct ly_ctx * ctx,struct lys_tpdf * tpdf,uint16_t start,uint16_t size)2957 yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint16_t start, uint16_t size)
2958 {
2959     uint16_t i;
2960 
2961     assert(ctx);
2962     if (!tpdf) {
2963         return;
2964     }
2965 
2966     for (i = start; i < size; ++i) {
2967         lydict_remove(ctx, tpdf[i].name);
2968         lydict_remove(ctx, tpdf[i].dsc);
2969         lydict_remove(ctx, tpdf[i].ref);
2970 
2971         yang_type_free(ctx, &tpdf[i].type);
2972 
2973         lydict_remove(ctx, tpdf[i].units);
2974         lydict_remove(ctx, tpdf[i].dflt);
2975         lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
2976     }
2977 }
2978 
2979 static void
yang_free_import(struct ly_ctx * ctx,struct lys_import * imp,uint8_t start,uint8_t size)2980 yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2981 {
2982     uint8_t i;
2983 
2984     for (i = start; i < size; ++i){
2985         free((char *)imp[i].module);
2986         lydict_remove(ctx, imp[i].prefix);
2987         lydict_remove(ctx, imp[i].dsc);
2988         lydict_remove(ctx, imp[i].ref);
2989         lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
2990     }
2991 }
2992 
2993 static void
yang_free_include(struct ly_ctx * ctx,struct lys_include * inc,uint8_t start,uint8_t size)2994 yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2995 {
2996     uint8_t i;
2997 
2998     for (i = start; i < size; ++i){
2999         free((char *)inc[i].submodule);
3000         lydict_remove(ctx, inc[i].dsc);
3001         lydict_remove(ctx, inc[i].ref);
3002         lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
3003     }
3004 }
3005 
3006 static void
yang_free_ident_base(struct lys_ident * ident,uint32_t start,uint32_t size)3007 yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
3008 {
3009     uint32_t i;
3010     uint8_t j;
3011 
3012     /* free base name */
3013     for (i = start; i < size; ++i) {
3014         for (j = 0; j < ident[i].base_size; ++j) {
3015             free(ident[i].base[j]);
3016         }
3017     }
3018 }
3019 
3020 static void
yang_free_grouping(struct ly_ctx * ctx,struct lys_node_grp * grp)3021 yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
3022 {
3023     yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
3024     free(grp->tpdf);
3025 }
3026 
3027 static void
yang_free_container(struct ly_ctx * ctx,struct lys_node_container * cont)3028 yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
3029 {
3030     uint8_t i;
3031 
3032     yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
3033     free(cont->tpdf);
3034     lydict_remove(ctx, cont->presence);
3035 
3036     for (i = 0; i < cont->must_size; ++i) {
3037         lys_restr_free(ctx, &cont->must[i], NULL);
3038     }
3039     free(cont->must);
3040 
3041     lys_when_free(ctx, cont->when, NULL);
3042 }
3043 
3044 static void
yang_free_leaf(struct ly_ctx * ctx,struct lys_node_leaf * leaf)3045 yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
3046 {
3047     uint8_t i;
3048 
3049     for (i = 0; i < leaf->must_size; i++) {
3050         lys_restr_free(ctx, &leaf->must[i], NULL);
3051     }
3052     free(leaf->must);
3053 
3054     lys_when_free(ctx, leaf->when, NULL);
3055 
3056     yang_type_free(ctx, &leaf->type);
3057     lydict_remove(ctx, leaf->units);
3058     lydict_remove(ctx, leaf->dflt);
3059 }
3060 
3061 static void
yang_free_leaflist(struct ly_ctx * ctx,struct lys_node_leaflist * leaflist)3062 yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
3063 {
3064     uint8_t i;
3065 
3066     for (i = 0; i < leaflist->must_size; i++) {
3067         lys_restr_free(ctx, &leaflist->must[i], NULL);
3068     }
3069     free(leaflist->must);
3070 
3071     for (i = 0; i < leaflist->dflt_size; i++) {
3072         lydict_remove(ctx, leaflist->dflt[i]);
3073     }
3074     free(leaflist->dflt);
3075 
3076     lys_when_free(ctx, leaflist->when, NULL);
3077 
3078     yang_type_free(ctx, &leaflist->type);
3079     lydict_remove(ctx, leaflist->units);
3080 }
3081 
3082 static void
yang_free_list(struct ly_ctx * ctx,struct lys_node_list * list)3083 yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3084 {
3085     uint8_t i;
3086 
3087     yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3088     free(list->tpdf);
3089 
3090     for (i = 0; i < list->must_size; ++i) {
3091         lys_restr_free(ctx, &list->must[i], NULL);
3092     }
3093     free(list->must);
3094 
3095     lys_when_free(ctx, list->when, NULL);
3096 
3097     for (i = 0; i < list->unique_size; ++i) {
3098         free(list->unique[i].expr);
3099     }
3100     free(list->unique);
3101 
3102     free(list->keys);
3103 }
3104 
3105 static void
yang_free_choice(struct ly_ctx * ctx,struct lys_node_choice * choice)3106 yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3107 {
3108     free(choice->dflt);
3109     lys_when_free(ctx, choice->when, NULL);
3110 }
3111 
3112 static void
yang_free_anydata(struct ly_ctx * ctx,struct lys_node_anydata * anydata)3113 yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3114 {
3115     uint8_t i;
3116 
3117     for (i = 0; i < anydata->must_size; ++i) {
3118         lys_restr_free(ctx, &anydata->must[i], NULL);
3119     }
3120     free(anydata->must);
3121 
3122     lys_when_free(ctx, anydata->when, NULL);
3123 }
3124 
3125 static void
yang_free_inout(struct ly_ctx * ctx,struct lys_node_inout * inout)3126 yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3127 {
3128     uint8_t i;
3129 
3130     yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3131     free(inout->tpdf);
3132 
3133     for (i = 0; i < inout->must_size; ++i) {
3134         lys_restr_free(ctx, &inout->must[i], NULL);
3135     }
3136     free(inout->must);
3137 }
3138 
3139 static void
yang_free_notif(struct ly_ctx * ctx,struct lys_node_notif * notif)3140 yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3141 {
3142     uint8_t i;
3143 
3144     yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3145     free(notif->tpdf);
3146 
3147     for (i = 0; i < notif->must_size; ++i) {
3148         lys_restr_free(ctx, &notif->must[i], NULL);
3149     }
3150     free(notif->must);
3151 }
3152 
3153 static void
yang_free_uses(struct ly_ctx * ctx,struct lys_node_uses * uses)3154 yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3155 {
3156     int i, j;
3157 
3158     for (i = 0; i < uses->refine_size; i++) {
3159         lydict_remove(ctx, uses->refine[i].target_name);
3160         lydict_remove(ctx, uses->refine[i].dsc);
3161         lydict_remove(ctx, uses->refine[i].ref);
3162 
3163         for (j = 0; j < uses->refine[i].must_size; j++) {
3164             lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
3165         }
3166         free(uses->refine[i].must);
3167 
3168         for (j = 0; j < uses->refine[i].dflt_size; j++) {
3169             lydict_remove(ctx, uses->refine[i].dflt[j]);
3170         }
3171         free(uses->refine[i].dflt);
3172 
3173         if (uses->refine[i].target_type & LYS_CONTAINER) {
3174             lydict_remove(ctx, uses->refine[i].mod.presence);
3175         }
3176         lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
3177     }
3178     free(uses->refine);
3179 
3180     lys_when_free(ctx, uses->when, NULL);
3181 }
3182 
3183 static void
yang_free_nodes(struct ly_ctx * ctx,struct lys_node * node)3184 yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3185 {
3186     struct lys_node *tmp, *child, *sibling;
3187 
3188     if (!node) {
3189         return;
3190     }
3191     tmp = node;
3192 
3193     while (tmp) {
3194         child = tmp->child;
3195         sibling = tmp->next;
3196         /* common part */
3197         lydict_remove(ctx, tmp->name);
3198         if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
3199             lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
3200             lydict_remove(ctx, tmp->dsc);
3201             lydict_remove(ctx, tmp->ref);
3202         }
3203 
3204         switch (tmp->nodetype) {
3205         case LYS_GROUPING:
3206         case LYS_RPC:
3207         case LYS_ACTION:
3208             yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3209             break;
3210         case LYS_CONTAINER:
3211             yang_free_container(ctx, (struct lys_node_container *)tmp);
3212             break;
3213         case LYS_LEAF:
3214             yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3215             break;
3216         case LYS_LEAFLIST:
3217             yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3218             break;
3219         case LYS_LIST:
3220             yang_free_list(ctx, (struct lys_node_list *)tmp);
3221             break;
3222         case LYS_CHOICE:
3223             yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3224             break;
3225         case LYS_CASE:
3226             lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
3227             break;
3228         case LYS_ANYXML:
3229         case LYS_ANYDATA:
3230             yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3231             break;
3232         case LYS_INPUT:
3233         case LYS_OUTPUT:
3234             yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3235             break;
3236         case LYS_NOTIF:
3237             yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3238             break;
3239         case LYS_USES:
3240             yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3241             break;
3242         default:
3243             break;
3244         }
3245         lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
3246         yang_free_nodes(ctx, child);
3247         free(tmp);
3248         tmp = sibling;
3249     }
3250 }
3251 
3252 static void
yang_free_augment(struct ly_ctx * ctx,struct lys_node_augment * aug)3253 yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3254 {
3255     lydict_remove(ctx, aug->target_name);
3256     lydict_remove(ctx, aug->dsc);
3257     lydict_remove(ctx, aug->ref);
3258 
3259     lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
3260     lys_when_free(ctx, aug->when, NULL);
3261     yang_free_nodes(ctx, aug->child);
3262     lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
3263 }
3264 
3265 static void
yang_free_deviate(struct ly_ctx * ctx,struct lys_deviation * dev,uint index)3266 yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3267 {
3268     uint i, j;
3269 
3270     for (i = index; i < dev->deviate_size; ++i) {
3271         lydict_remove(ctx, dev->deviate[i].units);
3272 
3273         if (dev->deviate[i].type) {
3274             yang_type_free(ctx, dev->deviate[i].type);
3275             free(dev->deviate[i].type);
3276         }
3277 
3278         for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3279             lydict_remove(ctx, dev->deviate[i].dflt[j]);
3280         }
3281         free(dev->deviate[i].dflt);
3282 
3283         for (j = 0; j < dev->deviate[i].must_size; ++j) {
3284             lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
3285         }
3286         free(dev->deviate[i].must);
3287 
3288         for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3289             free(dev->deviate[i].unique[j].expr);
3290         }
3291         free(dev->deviate[i].unique);
3292         lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
3293     }
3294 }
3295 
3296 void
yang_free_ext_data(struct yang_ext_substmt * substmt)3297 yang_free_ext_data(struct yang_ext_substmt *substmt)
3298 {
3299     int i;
3300 
3301     if (!substmt) {
3302         return;
3303     }
3304 
3305     free(substmt->ext_substmt);
3306     if (substmt->ext_modules) {
3307         for (i = 0; substmt->ext_modules[i]; ++i) {
3308             free(substmt->ext_modules[i]);
3309         }
3310         free(substmt->ext_modules);
3311     }
3312     free(substmt);
3313 }
3314 
3315 /* free common item from module and submodule */
3316 static void
free_yang_common(struct lys_module * module,struct lys_node * node)3317 free_yang_common(struct lys_module *module, struct lys_node *node)
3318 {
3319     uint i;
3320     yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3321     module->tpdf_size = 0;
3322     yang_free_ident_base(module->ident, 0, module->ident_size);
3323     yang_free_nodes(module->ctx, node);
3324     for (i = 0; i < module->augment_size; ++i) {
3325         yang_free_augment(module->ctx, &module->augment[i]);
3326     }
3327     module->augment_size = 0;
3328     for (i = 0; i < module->deviation_size; ++i) {
3329         yang_free_deviate(module->ctx, &module->deviation[i], 0);
3330         free(module->deviation[i].deviate);
3331         lydict_remove(module->ctx, module->deviation[i].target_name);
3332         lydict_remove(module->ctx, module->deviation[i].dsc);
3333         lydict_remove(module->ctx, module->deviation[i].ref);
3334     }
3335     module->deviation_size = 0;
3336 }
3337 
3338 /* check function*/
3339 
3340 int
yang_check_ext_instance(struct lys_module * module,struct lys_ext_instance *** ext,uint8_t * size,void * parent,struct unres_schema * unres)3341 yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint8_t *size,
3342                         void *parent, struct unres_schema *unres)
3343 {
3344     struct unres_ext *info;
3345     struct lys_ext_instance **ext_list = *ext;
3346     uint8_t i = 0, orig_size = *size;
3347     int rc;
3348 
3349     while (i < *size) {
3350         info = malloc(sizeof *info);
3351         LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
3352         info->data.yang = ext_list[i]->parent;
3353         info->datatype = LYS_IN_YANG;
3354         info->parent = parent;
3355         info->mod = module;
3356         info->parent_type = ext_list[i]->parent_type;
3357         info->substmt = ext_list[i]->insubstmt;
3358         info->substmt_index = ext_list[i]->insubstmt_index;
3359         info->ext_index = i;
3360 
3361         rc = unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info);
3362         if (rc == -1) {
3363             return EXIT_FAILURE;
3364         }
3365         if (!rc && !ext_list[i]) {
3366             /* this extension is skipped, move all extensions after it */
3367             memmove(ext_list + i, ext_list + i + 1, (*size - i - 1) * sizeof(*ext_list));
3368             --(*size);
3369         } else {
3370             ++i;
3371         }
3372     }
3373 
3374     lyp_reduce_ext_list(ext, *size, orig_size);
3375 
3376     return EXIT_SUCCESS;
3377 }
3378 
3379 int
yang_check_imports(struct lys_module * module,struct unres_schema * unres)3380 yang_check_imports(struct lys_module *module, struct unres_schema *unres)
3381 {
3382     struct lys_import *imp;
3383     struct lys_include *inc;
3384     uint8_t imp_size, inc_size, j = 0, i = 0;
3385     char *s;
3386 
3387     imp = module->imp;
3388     imp_size = module->imp_size;
3389     inc = module->inc;
3390     inc_size = module->inc_size;
3391 
3392     if (imp_size) {
3393         module->imp = calloc(imp_size, sizeof *module->imp);
3394         module->imp_size = 0;
3395         LY_CHECK_ERR_GOTO(!module->imp, LOGMEM(module->ctx), error);
3396     }
3397 
3398     if (inc_size) {
3399         module->inc = calloc(inc_size, sizeof *module->inc);
3400         module->inc_size = 0;
3401         LY_CHECK_ERR_GOTO(!module->inc, LOGMEM(module->ctx), error);
3402     }
3403 
3404     for (i = 0; i < imp_size; ++i) {
3405         s = (char *) imp[i].module;
3406         imp[i].module = NULL;
3407         if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
3408             ++i;
3409             goto error;
3410         }
3411     }
3412     for (j = 0; j < inc_size; ++j) {
3413         s = (char *) inc[j].submodule;
3414         inc[j].submodule = NULL;
3415         if (yang_fill_include(module, s, &inc[j], unres)) {
3416             ++j;
3417             goto error;
3418         }
3419     }
3420     free(inc);
3421     free(imp);
3422 
3423     return EXIT_SUCCESS;
3424 
3425 error:
3426     yang_free_import(module->ctx, imp, i, imp_size);
3427     yang_free_include(module->ctx, inc, j, inc_size);
3428     free(imp);
3429     free(inc);
3430     return EXIT_FAILURE;
3431 }
3432 
3433 static int
yang_check_iffeatures(struct lys_module * module,void * ptr,void * parent,enum yytokentype type,struct unres_schema * unres)3434 yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
3435 {
3436     struct lys_iffeature *iffeature;
3437     uint8_t *ptr_size, size, i;
3438     char *s;
3439     int parent_is_feature = 0;
3440 
3441     switch (type) {
3442     case FEATURE_KEYWORD:
3443         iffeature = ((struct lys_feature *)parent)->iffeature;
3444         size = ((struct lys_feature *)parent)->iffeature_size;
3445         ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3446         parent_is_feature = 1;
3447         break;
3448     case IDENTITY_KEYWORD:
3449         iffeature = ((struct lys_ident *)parent)->iffeature;
3450         size = ((struct lys_ident *)parent)->iffeature_size;
3451         ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3452         break;
3453     case ENUM_KEYWORD:
3454         iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3455         size = ((struct lys_type_enum *)ptr)->iffeature_size;
3456         ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3457         break;
3458     case BIT_KEYWORD:
3459         iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3460         size = ((struct lys_type_bit *)ptr)->iffeature_size;
3461         ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3462         break;
3463     case REFINE_KEYWORD:
3464         iffeature = ((struct lys_refine *)ptr)->iffeature;
3465         size = ((struct lys_refine *)ptr)->iffeature_size;
3466         ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3467         break;
3468     default:
3469         iffeature = ((struct lys_node *)parent)->iffeature;
3470         size = ((struct lys_node *)parent)->iffeature_size;
3471         ptr_size = &((struct lys_node *)parent)->iffeature_size;
3472         break;
3473     }
3474 
3475     *ptr_size = 0;
3476     for (i = 0; i < size; ++i) {
3477         s = (char *)iffeature[i].features;
3478         iffeature[i].features = NULL;
3479         if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3480             *ptr_size = size;
3481             return EXIT_FAILURE;
3482         }
3483         if (yang_check_ext_instance(module, &iffeature[i].ext, &iffeature[i].ext_size, &iffeature[i], unres)) {
3484             *ptr_size = size;
3485             return EXIT_FAILURE;
3486         }
3487         (*ptr_size)++;
3488     }
3489 
3490     return EXIT_SUCCESS;
3491 }
3492 
3493 static int
yang_check_identityref(struct lys_module * module,struct lys_type * type,struct unres_schema * unres)3494 yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3495 {
3496     uint size, i;
3497     int rc;
3498     struct lys_ident **ref;
3499     const char *value;
3500     char *expr;
3501 
3502     ref = type->info.ident.ref;
3503     size = type->info.ident.count;
3504     type->info.ident.count = 0;
3505     type->info.ident.ref = NULL;
3506     ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3507 
3508     for (i = 0; i < size; ++i) {
3509         expr = (char *)ref[i];
3510         /* store in the JSON format */
3511         value = transform_schema2json(module, expr);
3512         free(expr);
3513 
3514         if (!value) {
3515             goto error;
3516         }
3517         rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3518         lydict_remove(module->ctx, value);
3519 
3520         if (rc == -1) {
3521             goto error;
3522         }
3523     }
3524     free(ref);
3525 
3526     return EXIT_SUCCESS;
3527 error:
3528     for (i = i+1; i < size; ++i) {
3529         free(ref[i]);
3530     }
3531     free(ref);
3532     return EXIT_FAILURE;
3533 }
3534 
3535 int
yang_fill_type(struct lys_module * module,struct lys_type * type,struct yang_type * stype,void * parent,struct unres_schema * unres)3536 yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3537                void *parent, struct unres_schema *unres)
3538 {
3539     unsigned int i, j;
3540 
3541     type->parent = parent;
3542     if (yang_check_ext_instance(module, &type->ext, &type->ext_size, type, unres)) {
3543         return EXIT_FAILURE;
3544     }
3545     for (j = 0; j < type->ext_size; ++j) {
3546         if (type->ext[j]->flags & LYEXT_OPT_VALID) {
3547             type->parent->flags |= LYS_VALID_EXT;
3548             break;
3549         }
3550     }
3551 
3552     switch (stype->base) {
3553     case LY_TYPE_ENUM:
3554         for (i = 0; i < type->info.enums.count; ++i) {
3555             if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3556                 return EXIT_FAILURE;
3557             }
3558             if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, &type->info.enums.enm[i].ext_size,
3559                                         &type->info.enums.enm[i], unres)) {
3560                 return EXIT_FAILURE;
3561             }
3562             for (j = 0; j < type->info.enums.enm[i].ext_size; ++j) {
3563                 if (type->info.enums.enm[i].ext[j]->flags & LYEXT_OPT_VALID) {
3564                     type->parent->flags |= LYS_VALID_EXT;
3565                     break;
3566                 }
3567             }
3568         }
3569         break;
3570     case LY_TYPE_BITS:
3571         for (i = 0; i < type->info.bits.count; ++i) {
3572             if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3573                 return EXIT_FAILURE;
3574             }
3575             if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, &type->info.bits.bit[i].ext_size,
3576                                         &type->info.bits.bit[i], unres)) {
3577                 return EXIT_FAILURE;
3578             }
3579             for (j = 0; j < type->info.bits.bit[i].ext_size; ++j) {
3580                 if (type->info.bits.bit[i].ext[j]->flags & LYEXT_OPT_VALID) {
3581                     type->parent->flags |= LYS_VALID_EXT;
3582                     break;
3583                 }
3584             }
3585         }
3586         break;
3587     case LY_TYPE_IDENT:
3588         if (yang_check_identityref(module, type, unres)) {
3589             return EXIT_FAILURE;
3590         }
3591         break;
3592     case LY_TYPE_STRING:
3593         if (type->info.str.length) {
3594             if (yang_check_ext_instance(module, &type->info.str.length->ext,
3595                                         &type->info.str.length->ext_size, type->info.str.length, unres)) {
3596                 return EXIT_FAILURE;
3597             }
3598             for (j = 0; j < type->info.str.length->ext_size; ++j) {
3599                 if (type->info.str.length->ext[j]->flags & LYEXT_OPT_VALID) {
3600                     type->parent->flags |= LYS_VALID_EXT;
3601                     break;
3602                 }
3603             }
3604         }
3605 
3606         for (i = 0; i < type->info.str.pat_count; ++i) {
3607             if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, &type->info.str.patterns[i].ext_size,
3608                                         &type->info.str.patterns[i], unres)) {
3609                 return EXIT_FAILURE;
3610             }
3611             for (j = 0; j < type->info.str.patterns[i].ext_size; ++j) {
3612                 if (type->info.str.patterns[i].ext[j]->flags & LYEXT_OPT_VALID) {
3613                     type->parent->flags |= LYS_VALID_EXT;
3614                     break;
3615                 }
3616             }
3617         }
3618         break;
3619     case LY_TYPE_DEC64:
3620         if (type->info.dec64.range) {
3621             if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
3622                                         &type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3623                 return EXIT_FAILURE;
3624             }
3625             for (j = 0; j < type->info.dec64.range->ext_size; ++j) {
3626                 if (type->info.dec64.range->ext[j]->flags & LYEXT_OPT_VALID) {
3627                     type->parent->flags |= LYS_VALID_EXT;
3628                     break;
3629                 }
3630             }
3631         }
3632         break;
3633     case LY_TYPE_UNION:
3634         for (i = 0; i < type->info.uni.count; ++i) {
3635             if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3636                                parent, unres)) {
3637                 return EXIT_FAILURE;
3638             }
3639         }
3640         break;
3641     default:
3642         /* nothing checks */
3643         break;
3644     }
3645     return EXIT_SUCCESS;
3646 }
3647 
3648 int
yang_check_typedef(struct lys_module * module,struct lys_node * parent,struct unres_schema * unres)3649 yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3650 {
3651     struct lys_tpdf *tpdf;
3652     uint8_t *ptr_tpdf_size = NULL;
3653     uint16_t j, i, tpdf_size, *ptr_tpdf_size16 = NULL;
3654 
3655     if (!parent) {
3656         tpdf = module->tpdf;
3657         //ptr_tpdf_size = &module->tpdf_size;
3658         ptr_tpdf_size16 = &module->tpdf_size;
3659     } else {
3660         switch (parent->nodetype) {
3661         case LYS_GROUPING:
3662             tpdf = ((struct lys_node_grp *)parent)->tpdf;
3663             ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
3664             break;
3665         case LYS_CONTAINER:
3666             tpdf = ((struct lys_node_container *)parent)->tpdf;
3667             ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
3668             break;
3669         case LYS_LIST:
3670             tpdf = ((struct lys_node_list *)parent)->tpdf;
3671             ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3672             break;
3673         case LYS_RPC:
3674         case LYS_ACTION:
3675             tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3676             ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3677             break;
3678         case LYS_INPUT:
3679         case LYS_OUTPUT:
3680             tpdf = ((struct lys_node_inout *)parent)->tpdf;
3681             ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
3682             break;
3683         case LYS_NOTIF:
3684             tpdf = ((struct lys_node_notif *)parent)->tpdf;
3685             ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
3686             break;
3687         default:
3688             LOGINT(module->ctx);
3689             return EXIT_FAILURE;
3690         }
3691     }
3692 
3693     if (ptr_tpdf_size16) {
3694         tpdf_size = *ptr_tpdf_size16;
3695         *ptr_tpdf_size16 = 0;
3696     } else {
3697         tpdf_size = *ptr_tpdf_size;
3698         *ptr_tpdf_size = 0;
3699     }
3700 
3701     for (i = 0; i < tpdf_size; ++i) {
3702         if (lyp_check_identifier(module->ctx, tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3703             goto error;
3704         }
3705 
3706         if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3707             goto error;
3708         }
3709         if (yang_check_ext_instance(module, &tpdf[i].ext, &tpdf[i].ext_size, &tpdf[i], unres)) {
3710             goto error;
3711         }
3712         for (j = 0; j < tpdf[i].ext_size; ++j) {
3713             if (tpdf[i].ext[j]->flags & LYEXT_OPT_VALID) {
3714                 tpdf[i].flags |= LYS_VALID_EXT;
3715                 break;
3716             }
3717         }
3718         if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
3719             goto error;
3720         }
3721 
3722         if (ptr_tpdf_size16) {
3723             (*ptr_tpdf_size16)++;
3724         } else {
3725             (*ptr_tpdf_size)++;
3726         }
3727         /* check default value*/
3728         if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3729                 && unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPEDEF_DFLT, (struct lys_node *)(&tpdf[i].dflt)) == -1)  {
3730             ++i;
3731             goto error;
3732         }
3733     }
3734 
3735     return EXIT_SUCCESS;
3736 
3737 error:
3738     yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3739     return EXIT_FAILURE;
3740 }
3741 
3742 static int
yang_check_identities(struct lys_module * module,struct unres_schema * unres)3743 yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3744 {
3745     uint32_t i, size, base_size;
3746     uint8_t j;
3747 
3748     size = module->ident_size;
3749     module->ident_size = 0;
3750     for (i = 0; i < size; ++i) {
3751         base_size = module->ident[i].base_size;
3752         module->ident[i].base_size = 0;
3753         for (j = 0; j < base_size; ++j) {
3754             if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3755                 ++j;
3756                 module->ident_size = size;
3757                 goto error;
3758             }
3759         }
3760         module->ident_size++;
3761         if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3762             goto error;
3763         }
3764         if (yang_check_ext_instance(module, &module->ident[i].ext, &module->ident[i].ext_size, &module->ident[i], unres)) {
3765             goto error;
3766         }
3767     }
3768 
3769     return EXIT_SUCCESS;
3770 
3771 error:
3772     for (; j< module->ident[i].base_size; ++j) {
3773         free(module->ident[i].base[j]);
3774     }
3775     yang_free_ident_base(module->ident, i + 1, size);
3776     return EXIT_FAILURE;
3777 }
3778 
3779 static int
yang_check_must(struct lys_module * module,struct lys_restr * must,uint size,struct unres_schema * unres)3780 yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3781 {
3782     uint i;
3783 
3784     for (i = 0; i < size; ++i) {
3785         if (yang_check_ext_instance(module, &must[i].ext, &must[i].ext_size, &must[i], unres)) {
3786             return EXIT_FAILURE;
3787         }
3788     }
3789     return EXIT_SUCCESS;
3790 }
3791 
3792 static int
yang_check_container(struct lys_module * module,struct lys_node_container * cont,struct lys_node ** child,int options,struct unres_schema * unres)3793 yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
3794                      int options, struct unres_schema *unres)
3795 {
3796     if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
3797         goto error;
3798     }
3799 
3800     if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
3801         goto error;
3802     }
3803 
3804     if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
3805         *child = NULL;
3806         goto error;
3807     }
3808     *child = NULL;
3809 
3810     if (cont->when && yang_check_ext_instance(module, &cont->when->ext, &cont->when->ext_size, cont->when, unres)) {
3811         goto error;
3812     }
3813     if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3814         goto error;
3815     }
3816 
3817     /* check XPath dependencies */
3818     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
3819         if (options & LYS_PARSE_OPT_INGRP) {
3820             if (lyxp_node_check_syntax((struct lys_node *)cont)) {
3821                 goto error;
3822             }
3823         } else {
3824             if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3825                 goto error;
3826             }
3827         }
3828     }
3829 
3830     return EXIT_SUCCESS;
3831 error:
3832 
3833     return EXIT_FAILURE;
3834 }
3835 
3836 static int
yang_check_leaf(struct lys_module * module,struct lys_node_leaf * leaf,int options,struct unres_schema * unres)3837 yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
3838 {
3839     if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
3840         yang_type_free(module->ctx, &leaf->type);
3841         goto error;
3842     }
3843     if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3844         yang_type_free(module->ctx, &leaf->type);
3845         goto error;
3846     }
3847 
3848     if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
3849         yang_type_free(module->ctx, &leaf->type);
3850         goto error;
3851     }
3852 
3853     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
3854             (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
3855         goto error;
3856     }
3857 
3858     if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, &leaf->when->ext_size, leaf->when, unres)) {
3859         goto error;
3860     }
3861     if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3862         goto error;
3863     }
3864 
3865     /* check XPath dependencies */
3866     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
3867         if (options & LYS_PARSE_OPT_INGRP) {
3868             if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
3869                 goto error;
3870             }
3871         } else {
3872             if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3873                 goto error;
3874             }
3875         }
3876     }
3877 
3878     return EXIT_SUCCESS;
3879 
3880 error:
3881     return EXIT_FAILURE;
3882 }
3883 
3884 static int
yang_check_leaflist(struct lys_module * module,struct lys_node_leaflist * leaflist,int options,struct unres_schema * unres)3885 yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3886                     struct unres_schema *unres)
3887 {
3888     int i, j;
3889 
3890     if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
3891         yang_type_free(module->ctx, &leaflist->type);
3892         goto error;
3893     }
3894     if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3895         yang_type_free(module->ctx, &leaflist->type);
3896         goto error;
3897     }
3898 
3899     if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
3900         yang_type_free(module->ctx, &leaflist->type);
3901         goto error;
3902     }
3903 
3904     for (i = 0; i < leaflist->dflt_size; ++i) {
3905         /* check for duplicity in case of configuration data,
3906          * in case of status data duplicities are allowed */
3907         if (leaflist->flags & LYS_CONFIG_W) {
3908             for (j = i +1; j < leaflist->dflt_size; ++j) {
3909                 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
3910                     LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3911                     LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
3912                     goto error;
3913                 }
3914             }
3915         }
3916         /* check default value (if not defined, there still could be some restrictions
3917          * that need to be checked against a default value from a derived type) */
3918         if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
3919                 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3920                                        (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
3921             goto error;
3922         }
3923     }
3924 
3925     if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, &leaflist->when->ext_size, leaflist->when, unres)) {
3926         goto error;
3927     }
3928     if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3929         goto error;
3930     }
3931 
3932     /* check XPath dependencies */
3933     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
3934         if (options & LYS_PARSE_OPT_INGRP) {
3935             if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
3936                 goto error;
3937             }
3938         } else {
3939             if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3940                 goto error;
3941             }
3942         }
3943     }
3944 
3945     return EXIT_SUCCESS;
3946 
3947 error:
3948     return EXIT_FAILURE;
3949 }
3950 
3951 static int
yang_check_list(struct lys_module * module,struct lys_node_list * list,struct lys_node ** child,int options,struct unres_schema * unres)3952 yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
3953                 int options, struct unres_schema *unres)
3954 {
3955     struct lys_node *node;
3956 
3957     if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3958         goto error;
3959     }
3960 
3961     if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3962         goto error;
3963     }
3964 
3965     if (list->flags & LYS_CONFIG_R) {
3966         /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3967          * ignore oredering MASK - 0x7F
3968          */
3969         list->flags &= 0x7F;
3970     }
3971     /* check - if list is configuration, key statement is mandatory
3972      * (but only if we are not in a grouping or augment, then the check is deferred) */
3973     for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT | LYS_EXT)); node = node->parent);
3974     if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3975         LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3976         goto error;
3977     }
3978 
3979     if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
3980         *child = NULL;
3981         goto error;
3982     }
3983     *child = NULL;
3984 
3985     if (list->keys && yang_read_key(module, list, unres)) {
3986         goto error;
3987     }
3988 
3989     if (yang_read_unique(module, list, unres)) {
3990         goto error;
3991     }
3992 
3993     if (list->when && yang_check_ext_instance(module, &list->when->ext, &list->when->ext_size, list->when, unres)) {
3994         goto error;
3995     }
3996     if (yang_check_must(module, list->must, list->must_size, unres)) {
3997         goto error;
3998     }
3999 
4000     /* check XPath dependencies */
4001     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
4002         if (options & LYS_PARSE_OPT_INGRP) {
4003             if (lyxp_node_check_syntax((struct lys_node *)list)) {
4004                 goto error;
4005             }
4006         } else {
4007             if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
4008                 goto error;
4009             }
4010         }
4011     }
4012 
4013     return EXIT_SUCCESS;
4014 
4015 error:
4016     return EXIT_FAILURE;
4017 }
4018 
4019 static int
yang_check_choice(struct lys_module * module,struct lys_node_choice * choice,struct lys_node ** child,int options,struct unres_schema * unres)4020 yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
4021                   int options, struct unres_schema *unres)
4022 {
4023     char *value;
4024 
4025     if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
4026         free(choice->dflt);
4027         choice->dflt = NULL;
4028         goto error;
4029     }
4030 
4031     if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
4032         *child = NULL;
4033         free(choice->dflt);
4034         choice->dflt = NULL;
4035         goto error;
4036     }
4037     *child = NULL;
4038 
4039     if (choice->dflt) {
4040         value = (char *)choice->dflt;
4041         choice->dflt = NULL;
4042         if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
4043             free(value);
4044             goto error;
4045         }
4046         free(value);
4047     }
4048 
4049     if (choice->when && yang_check_ext_instance(module, &choice->when->ext, &choice->when->ext_size, choice->when, unres)) {
4050         goto error;
4051     }
4052 
4053     /* check XPath dependencies */
4054     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
4055         if (options & LYS_PARSE_OPT_INGRP) {
4056             if (lyxp_node_check_syntax((struct lys_node *)choice)) {
4057                 goto error;
4058             }
4059         } else {
4060             if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
4061                 goto error;
4062             }
4063         }
4064     }
4065 
4066     return EXIT_SUCCESS;
4067 
4068 error:
4069     return EXIT_FAILURE;
4070 }
4071 
4072 static int
yang_check_rpc_action(struct lys_module * module,struct lys_node_rpc_action * rpc,struct lys_node ** child,int options,struct unres_schema * unres)4073 yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
4074                       int options, struct unres_schema *unres)
4075 {
4076     if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
4077         goto error;
4078     }
4079 
4080     if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
4081         goto error;
4082     }
4083 
4084     if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
4085         *child = NULL;
4086         goto error;
4087     }
4088     *child = NULL;
4089 
4090     if (!(rpc->child->flags & LYS_IMPLICIT) && !rpc->child->child) {
4091         LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, rpc->child, "schema-node", strnodetype(rpc->child->nodetype));
4092         goto error;
4093     } else if (!(rpc->child->next->flags & LYS_IMPLICIT) && !rpc->child->next->child) {
4094         LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, rpc->child->next, "schema-node", strnodetype(rpc->child->next->nodetype));
4095         goto error;
4096     }
4097 
4098     return EXIT_SUCCESS;
4099 
4100 error:
4101     return EXIT_FAILURE;
4102 }
4103 
4104 static int
yang_check_notif(struct lys_module * module,struct lys_node_notif * notif,struct lys_node ** child,int options,struct unres_schema * unres)4105 yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
4106                  int options, struct unres_schema *unres)
4107 {
4108     if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
4109         goto error;
4110     }
4111 
4112     if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
4113         goto error;
4114     }
4115 
4116     if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
4117         *child = NULL;
4118         goto error;
4119     }
4120     *child = NULL;
4121 
4122     if (yang_check_must(module, notif->must, notif->must_size, unres)) {
4123         goto error;
4124     }
4125 
4126     /* check XPath dependencies */
4127     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
4128         if (options & LYS_PARSE_OPT_INGRP) {
4129             if (lyxp_node_check_syntax((struct lys_node *)notif)) {
4130                 goto error;
4131             }
4132         } else {
4133             if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
4134                 goto error;
4135             }
4136         }
4137     }
4138 
4139     return EXIT_SUCCESS;
4140 
4141 error:
4142     return EXIT_FAILURE;
4143 }
4144 
4145 static int
yang_check_augment(struct lys_module * module,struct lys_node_augment * augment,int options,struct unres_schema * unres)4146 yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
4147 {
4148     struct lys_node *child;
4149 
4150     child = augment->child;
4151     augment->child = NULL;
4152 
4153     if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4154         yang_free_nodes(module->ctx, child);
4155         goto error;
4156     }
4157 
4158     if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
4159         goto error;
4160     }
4161 
4162     if (yang_check_ext_instance(module, &augment->ext, &augment->ext_size, augment, unres)) {
4163         goto error;
4164     }
4165 
4166     if (augment->when && yang_check_ext_instance(module, &augment->when->ext, &augment->when->ext_size, augment->when, unres)) {
4167         goto error;
4168     }
4169 
4170     /* check XPath dependencies */
4171     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
4172         if (options & LYS_PARSE_OPT_INGRP) {
4173             if (lyxp_node_check_syntax((struct lys_node *)augment)) {
4174                 goto error;
4175             }
4176         } else {
4177             if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4178                 goto error;
4179             }
4180         }
4181     }
4182 
4183     return EXIT_SUCCESS;
4184 
4185 error:
4186     return EXIT_FAILURE;
4187 }
4188 
4189 static int
yang_check_uses(struct lys_module * module,struct lys_node_uses * uses,int options,struct unres_schema * unres)4190 yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
4191 {
4192     uint i, size;
4193 
4194     size = uses->augment_size;
4195     uses->augment_size = 0;
4196 
4197     if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
4198         goto error;
4199     }
4200 
4201     for (i = 0; i < uses->refine_size; ++i) {
4202         if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4203             goto error;
4204         }
4205         if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4206             goto error;
4207         }
4208         if (yang_check_ext_instance(module, &uses->refine[i].ext, &uses->refine[i].ext_size, &uses->refine[i], unres)) {
4209             goto error;
4210         }
4211     }
4212 
4213     for (i = 0; i < size; ++i) {
4214         uses->augment_size++;
4215         if (yang_check_augment(module, &uses->augment[i], options, unres)) {
4216             goto error;
4217         }
4218     }
4219 
4220     if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4221         goto error;
4222     }
4223 
4224     if (uses->when && yang_check_ext_instance(module, &uses->when->ext, &uses->when->ext_size, uses->when, unres)) {
4225         goto error;
4226     }
4227 
4228     /* check XPath dependencies */
4229     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
4230         if (options & LYS_PARSE_OPT_INGRP) {
4231             if (lyxp_node_check_syntax((struct lys_node *)uses)) {
4232                 goto error;
4233             }
4234         } else {
4235             if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4236                 goto error;
4237             }
4238         }
4239     }
4240 
4241     return EXIT_SUCCESS;
4242 
4243 error:
4244     for (i = uses->augment_size; i < size; ++i) {
4245         yang_free_augment(module->ctx, &uses->augment[i]);
4246     }
4247     return EXIT_FAILURE;
4248 }
4249 
4250 static int
yang_check_anydata(struct lys_module * module,struct lys_node_anydata * anydata,struct lys_node ** child,int options,struct unres_schema * unres)4251 yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
4252                    int options, struct unres_schema *unres)
4253 {
4254     if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4255         goto error;
4256     }
4257 
4258     if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
4259         *child = NULL;
4260         goto error;
4261     }
4262     *child = NULL;
4263 
4264     if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, &anydata->when->ext_size, anydata->when, unres)) {
4265         goto error;
4266     }
4267     if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4268         goto error;
4269     }
4270 
4271     /* check XPath dependencies */
4272     if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
4273         if (options & LYS_PARSE_OPT_INGRP) {
4274             if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
4275                 goto error;
4276             }
4277         } else {
4278             if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4279                 goto error;
4280             }
4281         }
4282     }
4283 
4284     return EXIT_SUCCESS;
4285 
4286 error:
4287     return EXIT_FAILURE;
4288 }
4289 
4290 static int
yang_check_nodes(struct lys_module * module,struct lys_node * parent,struct lys_node * nodes,int options,struct unres_schema * unres)4291 yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
4292                  int options, struct unres_schema *unres)
4293 {
4294     struct lys_node *node = nodes, *sibling, *child;
4295     int i;
4296 
4297     while (node) {
4298         sibling = node->next;
4299         child = node->child;
4300         node->next = NULL;
4301         node->child = NULL;
4302         node->parent = NULL;
4303         node->prev = node;
4304 
4305         if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node, 0) ||
4306             check_status_flag(node, parent)) {
4307             lys_node_unlink(node);
4308             yang_free_nodes(module->ctx, node);
4309             goto error;
4310         }
4311         if (node->parent != parent) {
4312             assert(node->parent->parent == parent);
4313             assert((node->parent->nodetype == LYS_CASE) && (node->parent->flags & LYS_IMPLICIT));
4314             store_config_flag(node->parent, options);
4315         }
4316         store_config_flag(node, options);
4317         if (yang_check_ext_instance(module, &node->ext, &node->ext_size, node, unres)) {
4318             goto error;
4319         }
4320         for (i = 0; i < node->ext_size; ++i) {
4321             if (node->ext[i]->flags & LYEXT_OPT_VALID) {
4322                 node->flags |= LYS_VALID_EXT;
4323                 if (node->ext[i]->flags & LYEXT_OPT_VALID_SUBTREE) {
4324                     node->flags |= LYS_VALID_EXT_SUBTREE;
4325                     break;
4326                 }
4327             }
4328         }
4329 
4330         switch (node->nodetype) {
4331         case LYS_GROUPING:
4332             if (yang_check_typedef(module, node, unres)) {
4333                 goto error;
4334             }
4335             if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
4336                 goto error;
4337             }
4338             if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
4339                 child = NULL;
4340                 goto error;
4341             }
4342             break;
4343         case LYS_CONTAINER:
4344             if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
4345                 goto error;
4346             }
4347             break;
4348         case LYS_LEAF:
4349             if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
4350                 child = NULL;
4351                 goto error;
4352             }
4353             break;
4354         case LYS_LEAFLIST:
4355             if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
4356                 child = NULL;
4357                 goto error;
4358             }
4359             break;
4360         case LYS_LIST:
4361             if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
4362                 goto error;
4363             }
4364             break;
4365         case LYS_CHOICE:
4366             if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
4367                 goto error;
4368             }
4369             break;
4370         case LYS_CASE:
4371             if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
4372                 goto error;
4373             }
4374             if (yang_check_nodes(module, node, child, options, unres)) {
4375                 child = NULL;
4376                 goto error;
4377             }
4378             if (((struct lys_node_case *)node)->when) {
4379                 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4380                         &((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4381                     goto error;
4382                 }
4383                 /* check XPath dependencies */
4384                 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
4385                     if (lyxp_node_check_syntax(node)) {
4386                         goto error;
4387                     }
4388                 } else {
4389                     if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4390                         goto error;
4391                     }
4392                 }
4393             }
4394             break;
4395         case LYS_ANYDATA:
4396         case LYS_ANYXML:
4397             if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
4398                 goto error;
4399             }
4400             break;
4401         case LYS_RPC:
4402         case LYS_ACTION:
4403             if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
4404                 goto error;
4405             }
4406             break;
4407         case LYS_INPUT:
4408         case LYS_OUTPUT:
4409             if (yang_check_typedef(module, node, unres)) {
4410                 goto error;
4411             }
4412             if (yang_check_nodes(module, node, child, options, unres)) {
4413                 child = NULL;
4414                 goto error;
4415             }
4416             if (((struct lys_node_inout *)node)->must_size) {
4417                 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4418                     goto error;
4419                 }
4420                 /* check XPath dependencies */
4421                 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
4422                     if (lyxp_node_check_syntax(node)) {
4423                         goto error;
4424                     }
4425                 } else {
4426                     if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4427                         goto error;
4428                     }
4429                 }
4430             }
4431             break;
4432         case LYS_NOTIF:
4433             if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
4434                 goto error;
4435             }
4436             break;
4437         case LYS_USES:
4438             if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
4439                 child = NULL;
4440                 goto error;
4441             }
4442             break;
4443         default:
4444             LOGINT(module->ctx);
4445             goto error;
4446         }
4447         node = sibling;
4448     }
4449 
4450     return EXIT_SUCCESS;
4451 
4452 error:
4453     yang_free_nodes(module->ctx, sibling);
4454     yang_free_nodes(module->ctx, child);
4455     return EXIT_FAILURE;
4456 }
4457 
4458 static int
yang_check_deviate(struct lys_module * module,struct unres_schema * unres,struct lys_deviate * deviate,struct lys_node * dev_target,struct ly_set * dflt_check)4459 yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4460                    struct lys_node *dev_target, struct ly_set *dflt_check)
4461 {
4462     struct lys_node_leaflist *llist;
4463     struct lys_type *type;
4464     struct lys_tpdf *tmp_parent;
4465     int i, j;
4466 
4467     if (yang_check_ext_instance(module, &deviate->ext, &deviate->ext_size, deviate, unres)) {
4468         goto error;
4469     }
4470     if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4471         goto error;
4472     }
4473     if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4474         goto error;
4475     }
4476     if (deviate->dflt_size) {
4477         if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4478             goto error;
4479         }
4480         if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4481             /* consolidate the final list in the target after removing items from it */
4482             llist = (struct lys_node_leaflist *)dev_target;
4483             for (i = j = 0; j < llist->dflt_size; j++) {
4484                 llist->dflt[i] = llist->dflt[j];
4485                 if (llist->dflt[i]) {
4486                     i++;
4487                 }
4488             }
4489             llist->dflt_size = i + 1;
4490         }
4491     }
4492 
4493     if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4494         goto error;
4495     }
4496 
4497     if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4498         goto error;
4499     }
4500 
4501     if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4502         goto error;
4503     }
4504 
4505     if ((deviate->flags & LYS_CONFIG_MASK)) {
4506         /* cannot add if it was explicitly set */
4507         if ((deviate->mod == LY_DEVIATE_ADD) && (dev_target->flags & LYS_CONFIG_SET)) {
4508             LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "config");
4509             LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
4510             goto error;
4511         } else if ((deviate->mod == LY_DEVIATE_RPL) && !(dev_target->flags & LYS_CONFIG_SET)) {
4512             LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "config");
4513             LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
4514             goto error;
4515         }
4516 
4517         /* add and replace are the same in this case */
4518         /* remove current config value of the target ... */
4519         dev_target->flags &= ~LYS_CONFIG_MASK;
4520 
4521         /* ... and replace it with the value specified in deviation */
4522         dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4523 
4524         /* "config" is explicitely set in the node */
4525         dev_target->flags |= LYS_CONFIG_SET;
4526 
4527         /* "config" must be set to either "yes" or "no" */
4528         assert(dev_target->flags ^ LYS_CONFIG_MASK);
4529 
4530         /* check and inherit new config to all the children */
4531         if (lyp_deviate_inherit_config_r(dev_target)) {
4532             goto error;
4533         }
4534     }
4535 
4536     if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4537         goto error;
4538     }
4539 
4540     if (deviate->type) {
4541         /* check target node type */
4542         if (dev_target->nodetype == LYS_LEAF) {
4543             type = &((struct lys_node_leaf *)dev_target)->type;
4544         } else if (dev_target->nodetype == LYS_LEAFLIST) {
4545             type = &((struct lys_node_leaflist *)dev_target)->type;
4546         } else {
4547             LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4548             LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
4549             goto error;
4550         }
4551         /* remove type and initialize it */
4552         tmp_parent = type->parent;
4553         lys_type_free(module->ctx, type, NULL);
4554         memcpy(type, deviate->type, sizeof *deviate->type);
4555         free(deviate->type);
4556         deviate->type = type;
4557         deviate->type->parent = tmp_parent;
4558         if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4559             goto error;
4560         }
4561 
4562         if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4563             goto error;
4564         }
4565     }
4566 
4567     return EXIT_SUCCESS;
4568 
4569 error:
4570     if (deviate->type) {
4571         yang_type_free(module->ctx, deviate->type);
4572         deviate->type = NULL;
4573     }
4574     return EXIT_FAILURE;
4575 }
4576 
4577 static int
yang_check_deviation(struct lys_module * module,struct unres_schema * unres,struct lys_deviation * dev)4578 yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4579 {
4580     int rc;
4581     uint i;
4582     struct lys_node *dev_target = NULL, *parent;
4583     struct ly_set *dflt_check = ly_set_new(), *set;
4584     unsigned int u;
4585     const char *value, *target_name;
4586     struct lys_node_leaflist *llist;
4587     struct lys_node_leaf *leaf;
4588     struct lys_node_inout *inout;
4589     struct unres_schema *tmp_unres;
4590     struct lys_module *mod;
4591 
4592     /* resolve target node */
4593     rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4594     if (rc == -1) {
4595         LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4596         ly_set_free(set);
4597         i = 0;
4598         goto free_type_error;
4599     }
4600     dev_target = set->set.s[0];
4601     ly_set_free(set);
4602 
4603     if (dev_target->module == lys_main_module(module)) {
4604         LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4605         LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4606         i = 0;
4607         goto free_type_error;
4608     }
4609 
4610     if (!dflt_check) {
4611         LOGMEM(module->ctx);
4612         i = 0;
4613         goto free_type_error;
4614     }
4615 
4616     if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4617         /* you cannot remove a key leaf */
4618         if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4619             for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4620                 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4621                     LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4622                     LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
4623                     i = 0;
4624                     goto free_type_error;
4625                 }
4626             }
4627         }
4628         /* unlink and store the original node */
4629         parent = dev_target->parent;
4630         lys_node_unlink(dev_target);
4631         if (parent) {
4632             if (parent->nodetype & (LYS_AUGMENT | LYS_USES)) {
4633                 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4634                  * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4635                  * path), so we need to remember the augment as an addition */
4636                 /* remember uses parent so we can reconnect to it */
4637                 dev_target->parent = parent;
4638             } else if (parent->nodetype & (LYS_RPC | LYS_ACTION)) {
4639                 /* re-create implicit node */
4640                 inout = calloc(1, sizeof *inout);
4641                 LY_CHECK_ERR_GOTO(!inout, LOGMEM(module->ctx), error);
4642 
4643                 inout->nodetype = dev_target->nodetype;
4644                 inout->name = lydict_insert(module->ctx, (inout->nodetype == LYS_INPUT) ? "input" : "output", 0);
4645                 inout->module = dev_target->module;
4646                 inout->flags = LYS_IMPLICIT;
4647 
4648                 /* insert it manually */
4649                 assert(parent->child && !parent->child->next
4650                     && (parent->child->nodetype == (inout->nodetype == LYS_INPUT ? LYS_OUTPUT : LYS_INPUT)));
4651                 parent->child->next = (struct lys_node *)inout;
4652                 inout->prev = parent->child;
4653                 parent->child->prev = (struct lys_node *)inout;
4654                 inout->parent = parent;
4655             }
4656         }
4657         dev->orig_node = dev_target;
4658     } else {
4659         /* store a shallow copy of the original node */
4660         tmp_unres = calloc(1, sizeof *tmp_unres);
4661         dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, tmp_unres, 1);
4662         /* such a case is not really supported but whatever */
4663         unres_schema_free(dev_target->module, &tmp_unres, 1);
4664     }
4665 
4666     if (yang_check_ext_instance(module, &dev->ext, &dev->ext_size, dev, unres)) {
4667         i = 0;
4668         goto free_type_error;
4669     }
4670 
4671     for (i = 0; i < dev->deviate_size; ++i) {
4672         if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4673             yang_free_deviate(module->ctx, dev, i + 1);
4674             dev->deviate_size = i + 1;
4675             goto free_type_error;
4676         }
4677     }
4678     /* now check whether default value, if any, matches the type */
4679     for (u = 0; u < dflt_check->number; ++u) {
4680         value = NULL;
4681         rc = EXIT_SUCCESS;
4682         if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4683             leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4684             target_name = leaf->name;
4685             value = leaf->dflt;
4686             rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4687         } else { /* LYS_LEAFLIST */
4688             llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4689             target_name = llist->name;
4690             for (i = 0; i < llist->dflt_size; i++) {
4691                 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4692                                            (struct lys_node *)(&llist->dflt[i]));
4693                 if (rc == -1) {
4694                     value = llist->dflt[i];
4695                     break;
4696                 }
4697             }
4698         }
4699         if (rc == -1) {
4700             LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4701             LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
4702                 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4703                 target_name);
4704             goto error;
4705         }
4706     }
4707     ly_set_free(dflt_check);
4708     dflt_check = NULL;
4709 
4710     /* mark all the affected modules as deviated and implemented */
4711     for (parent = dev_target; parent; parent = lys_parent(parent)) {
4712         mod = lys_node_module(parent);
4713         if (module != mod) {
4714             mod->deviated = 1;            /* main module */
4715             parent->module->deviated = 1; /* possible submodule */
4716             if (!mod->implemented) {
4717                 mod->implemented = 1;
4718                 if (unres_schema_add_node(mod, unres, NULL, UNRES_MOD_IMPLEMENT, NULL) == -1) {
4719                     goto error;
4720                 }
4721             }
4722         }
4723     }
4724 
4725     return EXIT_SUCCESS;
4726 
4727 free_type_error:
4728     /* we need to free types because they are for now allocated dynamically (use i as it is now, is set correctly) */
4729     for (; i < dev->deviate_size; ++i) {
4730         if (dev->deviate[i].type) {
4731             yang_type_free(module->ctx, dev->deviate[i].type);
4732             free(dev->deviate[i].type);
4733             dev->deviate[i].type = NULL;
4734         }
4735     }
4736 error:
4737     ly_set_free(dflt_check);
4738     return EXIT_FAILURE;
4739 }
4740 
4741 static int
yang_check_sub_module(struct lys_module * module,struct unres_schema * unres,struct lys_node * node)4742 yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4743 {
4744     uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
4745 
4746     aug_size = module->augment_size;
4747     module->augment_size = 0;
4748     dev_size = module->deviation_size;
4749     module->deviation_size = 0;
4750 
4751     if (yang_check_typedef(module, NULL, unres)) {
4752         goto error;
4753     }
4754 
4755     if (yang_check_ext_instance(module, &module->ext, &module->ext_size, module, unres)) {
4756         goto error;
4757     }
4758 
4759     /* check extension in revision */
4760     for (i = 0; i < module->rev_size; ++i) {
4761         if (yang_check_ext_instance(module, &module->rev[i].ext, &module->rev[i].ext_size, &module->rev[i], unres)) {
4762             goto error;
4763         }
4764     }
4765 
4766     /* check extension in definition of extension */
4767     for (i = 0; i < module->extensions_size; ++i) {
4768         if (yang_check_ext_instance(module, &module->extensions[i].ext, &module->extensions[i].ext_size, &module->extensions[i], unres)) {
4769             goto error;
4770         }
4771     }
4772 
4773     /* check features */
4774     for (i = 0; i < module->features_size; ++i) {
4775         if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4776             goto error;
4777         }
4778         if (yang_check_ext_instance(module, &module->features[i].ext, &module->features[i].ext_size, &module->features[i], unres)) {
4779             goto error;
4780         }
4781 
4782         /* check for circular dependencies */
4783         if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4784             goto error;
4785         }
4786     }
4787     erase_identities = 0;
4788     if (yang_check_identities(module, unres)) {
4789         goto error;
4790     }
4791     erase_nodes = 0;
4792     if (yang_check_nodes(module, NULL, node, 0, unres)) {
4793         goto error;
4794     }
4795 
4796     /* check deviation */
4797     for (i = 0; i < dev_size; ++i) {
4798         module->deviation_size++;
4799         if (yang_check_deviation(module, unres, &module->deviation[i])) {
4800             goto error;
4801         }
4802     }
4803 
4804     /* check augments */
4805     for (i = 0; i < aug_size; ++i) {
4806         module->augment_size++;
4807         if (yang_check_augment(module, &module->augment[i], 0, unres)) {
4808             goto error;
4809         }
4810         if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4811             goto error;
4812         }
4813     }
4814 
4815     return EXIT_SUCCESS;
4816 
4817 error:
4818     if (erase_identities) {
4819         yang_free_ident_base(module->ident, 0, module->ident_size);
4820     }
4821     if (erase_nodes) {
4822         yang_free_nodes(module->ctx, node);
4823     }
4824     for (i = module->augment_size; i < aug_size; ++i) {
4825         yang_free_augment(module->ctx, &module->augment[i]);
4826     }
4827     for (i = module->deviation_size; i < dev_size; ++i) {
4828         yang_free_deviate(module->ctx, &module->deviation[i], 0);
4829         free(module->deviation[i].deviate);
4830         lydict_remove(module->ctx, module->deviation[i].target_name);
4831         lydict_remove(module->ctx, module->deviation[i].dsc);
4832         lydict_remove(module->ctx, module->deviation[i].ref);
4833     }
4834     return EXIT_FAILURE;
4835 }
4836 
4837 int
yang_read_extcomplex_str(struct lys_module * module,struct lys_ext_instance_complex * ext,const char * arg_name,const char * parent_name,char ** value,int parent_stmt,LY_STMT stmt)4838 yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
4839                          const char *parent_name, char **value, int parent_stmt, LY_STMT stmt)
4840 {
4841     int c;
4842     const char **str, ***p = NULL;
4843     void *reallocated;
4844     struct lyext_substmt *info;
4845 
4846     c = 0;
4847     if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
4848         /* str contains no NULL value */
4849         str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4850         if (info->cardinality < LY_STMT_CARD_SOME) {
4851             str++;
4852         } else {
4853            /* get the index in the array to add new item */
4854             p = (const char ***)str;
4855             for (c = 0; p[0][c + 1]; c++);
4856             str = p[1];
4857         }
4858         str[c] = lydict_insert_zc(module->ctx, *value);
4859         *value = NULL;
4860     }  else {
4861         str = lys_ext_complex_get_substmt(stmt, ext, &info);
4862         if (!str) {
4863             LOGVAL(module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
4864             goto error;
4865         }
4866         if (info->cardinality < LY_STMT_CARD_SOME && *str) {
4867             LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
4868             goto error;
4869         }
4870 
4871         if (info->cardinality >= LY_STMT_CARD_SOME) {
4872             /* there can be multiple instances, str is actually const char *** */
4873             p = (const char ***)str;
4874             if (!p[0]) {
4875                 /* allocate initial array */
4876                 p[0] = calloc(2, sizeof(const char *));
4877                 LY_CHECK_ERR_GOTO(!p[0], LOGMEM(module->ctx), error);
4878                 if (stmt == LY_STMT_BELONGSTO) {
4879                     /* allocate another array for the belongs-to's prefixes */
4880                     p[1] = calloc(2, sizeof(const char *));
4881                     LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
4882                 } else if (stmt == LY_STMT_ARGUMENT) {
4883                     /* allocate another array for the yin element */
4884                     ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
4885                     LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
4886                     /* default value of yin element */
4887                     ((uint8_t *)p[1])[0] = 2;
4888                 }
4889             } else {
4890                 /* get the index in the array to add new item */
4891                 for (c = 0; p[0][c]; c++);
4892             }
4893             str = p[0];
4894         }
4895 
4896         str[c] = lydict_insert_zc(module->ctx, *value);
4897         *value = NULL;
4898 
4899         if (c) {
4900             /* enlarge the array(s) */
4901             reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4902             if (!reallocated) {
4903                 LOGMEM(module->ctx);
4904                 lydict_remove(module->ctx, p[0][c]);
4905                 p[0][c] = NULL;
4906                 return EXIT_FAILURE;
4907             }
4908             p[0] = reallocated;
4909             p[0][c + 1] = NULL;
4910 
4911             if (stmt == LY_STMT_BELONGSTO) {
4912                 /* enlarge the second belongs-to's array with prefixes */
4913                 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4914                 if (!reallocated) {
4915                     LOGMEM(module->ctx);
4916                     lydict_remove(module->ctx, p[1][c]);
4917                     p[1][c] = NULL;
4918                     return EXIT_FAILURE;
4919                 }
4920                 p[1] = reallocated;
4921                 p[1][c + 1] = NULL;
4922             } else if (stmt == LY_STMT_ARGUMENT) {
4923                 /* enlarge the second argument's array with yin element */
4924                 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4925                 if (!reallocated) {
4926                     LOGMEM(module->ctx);
4927                     ((uint8_t *)p[1])[c] = 0;
4928                     return EXIT_FAILURE;
4929                 }
4930                 p[1] = reallocated;
4931                 ((uint8_t *)p[1])[c + 1] = 0;
4932             }
4933         }
4934     }
4935 
4936     return EXIT_SUCCESS;
4937 
4938 error:
4939     free(*value);
4940     *value = NULL;
4941     return EXIT_FAILURE;
4942 }
4943 
4944 static int
yang_fill_ext_substm_index(struct lys_ext_instance_complex * ext,LY_STMT stmt,enum yytokentype keyword)4945 yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4946 {
4947     int c = 0, decrement = 0;
4948     const char **str, ***p = NULL;
4949     struct lyext_substmt *info;
4950 
4951 
4952     if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4953         stmt = LY_STMT_BELONGSTO;
4954         decrement = -1;
4955     } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4956         stmt = LY_STMT_ARGUMENT;
4957         decrement = -1;
4958     }
4959 
4960     str = lys_ext_complex_get_substmt(stmt, ext, &info);
4961     if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4962         return 0;
4963     } else {
4964         p = (const char ***)str;
4965         /* get the index in the array */
4966         for (c = 0; p[0][c]; c++);
4967         return c + decrement;
4968     }
4969 }
4970 
4971 void **
yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex * ext,int * index,char * parent_name,char * node_name,LY_STMT stmt)4972 yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4973                                     char *parent_name, char *node_name, LY_STMT stmt)
4974 {
4975     struct ly_ctx *ctx = ext->module->ctx;
4976     int c;
4977     void **data, ***p = NULL;
4978     void *reallocated;
4979     struct lyext_substmt *info;
4980 
4981     data = lys_ext_complex_get_substmt(stmt, ext, &info);
4982     if (!data) {
4983         LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4984         return NULL;
4985     }
4986     if (info->cardinality < LY_STMT_CARD_SOME && *data) {
4987         LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4988         return NULL;
4989     }
4990 
4991     c = 0;
4992     if (info->cardinality >= LY_STMT_CARD_SOME) {
4993         /* there can be multiple instances, so instead of pointer to array,
4994          * we have in data pointer to pointer to array */
4995         p = (void ***)data;
4996         data = *p;
4997         if (!data) {
4998             /* allocate initial array */
4999             *p = data = calloc(2, sizeof(void *));
5000             LY_CHECK_ERR_RETURN(!data, LOGMEM(ctx), NULL);
5001         } else {
5002             for (c = 0; *data; data++, c++);
5003         }
5004     }
5005 
5006     if (c) {
5007         /* enlarge the array */
5008         reallocated = realloc(*p, (c + 2) * sizeof(void *));
5009         LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), NULL);
5010         *p = reallocated;
5011         data = *p;
5012         data[c + 1] = NULL;
5013     }
5014 
5015     if (index) {
5016         *index = c;
5017         return data;
5018     } else {
5019         return &data[c];
5020     }
5021 }
5022 
5023 int
yang_fill_extcomplex_flags(struct lys_ext_instance_complex * ext,char * parent_name,char * node_name,LY_STMT stmt,uint16_t value,uint16_t mask)5024 yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
5025                            LY_STMT stmt, uint16_t value, uint16_t mask)
5026 {
5027     uint16_t *data;
5028     struct lyext_substmt *info;
5029 
5030     data = lys_ext_complex_get_substmt(stmt, ext, &info);
5031     if (!data) {
5032         LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
5033         return EXIT_FAILURE;
5034     }
5035     if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
5036         LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
5037         return EXIT_FAILURE;
5038     }
5039 
5040     *data |= value;
5041     return EXIT_SUCCESS;
5042 }
5043 
5044 int
yang_fill_extcomplex_uint8(struct lys_ext_instance_complex * ext,char * parent_name,char * node_name,LY_STMT stmt,uint8_t value)5045 yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
5046                            LY_STMT stmt, uint8_t value)
5047 {
5048     struct ly_ctx *ctx = ext->module->ctx;
5049     uint8_t *val, **pp = NULL, *reallocated;
5050     struct lyext_substmt *info;
5051     int i = 0;
5052 
5053     val = lys_ext_complex_get_substmt(stmt, ext, &info);
5054     if (!val) {
5055         LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
5056         return EXIT_FAILURE;
5057     }
5058     if (stmt == LY_STMT_DIGITS) {
5059         if (info->cardinality < LY_STMT_CARD_SOME && *val) {
5060             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
5061             return EXIT_FAILURE;
5062         }
5063 
5064         if (info->cardinality >= LY_STMT_CARD_SOME) {
5065             /* there can be multiple instances */
5066             pp = (uint8_t**)val;
5067             if (!(*pp)) {
5068                 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
5069                 LY_CHECK_ERR_RETURN(!*pp, LOGMEM(ctx), EXIT_FAILURE);
5070             } else {
5071                 for (i = 0; (*pp)[i]; i++);
5072             }
5073             val = &(*pp)[i];
5074         }
5075 
5076         /* stored value */
5077         *val = value;
5078 
5079         if (i) {
5080             /* enlarge the array */
5081             reallocated = realloc(*pp, (i + 2) * sizeof *val);
5082             LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
5083             *pp = reallocated;
5084             (*pp)[i + 1] = 0;
5085         }
5086     } else {
5087         if (*val) {
5088             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
5089             return EXIT_FAILURE;
5090         }
5091 
5092         if (stmt == LY_STMT_REQINSTANCE) {
5093             *val = (value == 1) ? 1 : 2;
5094         } else if (stmt == LY_STMT_MODIFIER) {
5095             *val =  1;
5096         } else {
5097             LOGINT(ctx);
5098             return EXIT_FAILURE;
5099         }
5100     }
5101 
5102     return EXIT_SUCCESS;
5103 }
5104 
5105 int
yang_extcomplex_node(struct lys_ext_instance_complex * ext,char * parent_name,char * node_name,struct lys_node * node,LY_STMT stmt)5106 yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
5107                      struct lys_node *node, LY_STMT stmt)
5108 {
5109     struct lyext_substmt *info;
5110     struct lys_node **snode, *siter;
5111 
5112     snode = lys_ext_complex_get_substmt(stmt, ext, &info);
5113     if (!snode) {
5114         LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
5115         return EXIT_FAILURE;
5116     }
5117     if (info->cardinality < LY_STMT_CARD_SOME) {
5118         LY_TREE_FOR(node, siter) {
5119             if (stmt == lys_snode2stmt(siter->nodetype)) {
5120                 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
5121                 return EXIT_FAILURE;
5122             }
5123         }
5124     }
5125 
5126     return EXIT_SUCCESS;
5127 }
5128 
5129 int
yang_fill_extcomplex_module(struct ly_ctx * ctx,struct lys_ext_instance_complex * ext,char * parent_name,char ** values,int implemented)5130 yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
5131                             char *parent_name, char **values, int implemented)
5132 {
5133     int c, i;
5134     struct lys_module **modules, ***p, *reallocated, **pp;
5135     struct lyext_substmt *info;
5136 
5137     if (!values) {
5138         return EXIT_SUCCESS;
5139     }
5140     pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
5141     if (!modules) {
5142         LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
5143         return EXIT_FAILURE;
5144     }
5145 
5146     for (i = 0; values[i]; ++i) {
5147         c = 0;
5148         if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
5149             LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
5150             return EXIT_FAILURE;
5151         }
5152         if (info->cardinality >= LY_STMT_CARD_SOME) {
5153             /* there can be multiple instances, so instead of pointer to array,
5154              * we have in modules pointer to pointer to array */
5155             p = (struct lys_module ***)pp;
5156             modules = *p;
5157             if (!modules) {
5158                 /* allocate initial array */
5159                 *p = modules = calloc(2, sizeof(struct lys_module *));
5160                 LY_CHECK_ERR_RETURN(!*p, LOGMEM(ctx), EXIT_FAILURE);
5161             } else {
5162                 for (c = 0; *modules; modules++, c++);
5163             }
5164         }
5165 
5166         if (c) {
5167             /* enlarge the array */
5168             reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
5169             LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
5170             *p = (struct lys_module **)reallocated;
5171             modules = *p;
5172             modules[c + 1] = NULL;
5173         }
5174 
5175         modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
5176         if (!modules[c]) {
5177             return EXIT_FAILURE;
5178         }
5179     }
5180 
5181     return EXIT_SUCCESS;
5182 }
5183