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(¶m, 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, ¶m)) {
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(¶m, 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, ¶m)) {
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, ¬if->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