static void test_similar_strings(void **state) { (void) state; /* unused */ const char *ret = NULL; ret = lydict_insert(ctx, "aaab", 4); if (!ret) { fail(); } assert_string_equal(ret, "aaab"); ret = lydict_insert(ctx, "aaa", 3); if (!ret) { fail(); } assert_string_equal(ret, "aaa"); ret = lydict_insert(ctx, "bbb", 3); if (!ret) { fail(); } assert_string_equal(ret, "bbb"); ret = lydict_insert(ctx, "bbba", 4); if (!ret) { fail(); } assert_string_equal(ret, "bbba"); lydict_remove(ctx, "aaa"); lydict_remove(ctx, "aaab"); lydict_remove(ctx, "bbb"); lydict_remove(ctx, "bbba"); }
static void test_lydict_remove(void **state) { (void) state; /* unused */ char *value = NULL, *value2; const char *str; value = strdup("new_name"); if (!value) { fail(); } value2 = strdup("new_name"); if (!value2) { fail(); } const char *string; string = lydict_insert_zc(ctx, value); /* 1st instance */ if (!string) { free(value); fail(); } assert_string_equal("new_name", string); str = lydict_insert(ctx, "new_name", 0); /* 2nd instance */ assert_ptr_equal(str, string); lydict_remove(ctx, string); /* remove 2nd instance */ lydict_remove(ctx, string); /* remove 1st instance */ /* string content is supposed to be invalid since now! */ str = lydict_insert_zc(ctx, value2); assert_ptr_not_equal(str, NULL); assert_ptr_not_equal(str, string); lydict_remove(ctx, str); }
static void test_lydict_insert(void **state) { (void) state; /* unused */ const char *value = "x"; const char *string; size_t len = 1; string = lydict_insert(ctx, value, len); if (!string) { fail(); } assert_string_equal(value, string); value = "bubba"; len = 5; string = lydict_insert(ctx, value, len); if (!string) { fail(); } assert_string_equal(value, string); lydict_remove(ctx, "bubba"); lydict_remove(ctx, "x"); }
static void test_lydict_insert_zc(void **state) { (void) state; /* unused */ char *value = NULL; value = strdup("x"); if (!value) { fail(); } const char *string; string = lydict_insert_zc(ctx, value); if (!string) { free(value); fail(); } assert_string_equal("x", string); value = strdup("bubba"); if (!value) { free(value); fail(); } string = lydict_insert_zc(ctx, value); if (!string) { fail(); } assert_string_equal("bubba", string); lydict_remove(ctx, "bubba"); lydict_remove(ctx, "x"); }
static int _xml_get_value(struct lyd_node *node, struct lys_type *node_type, struct lyxml_elem *xml, int options, struct unres_data **unres, int log) { #define DECSIZE 21 struct lyd_node_leaf *leaf = (struct lyd_node_leaf *)node; struct lys_type *type; struct lyxml_ns *ns; char dec[DECSIZE]; char *strptr; const char *name; int64_t num; uint64_t unum; int len; int c, i, j, d; int found; struct unres_data *new_unres; leaf->value_str = xml->content; xml->content = NULL; /* will be change in case of union */ leaf->value_type = node_type->base; if ((options & LYD_OPT_FILTER) && !leaf->value_str) { /* no value in filter (selection) node -> nothing more is needed */ return EXIT_SUCCESS; } switch (node_type->base) { case LY_TYPE_BINARY: leaf->value.binary = leaf->value_str; if (node_type->info.binary.length && validate_length_range(0, strlen(leaf->value.binary), 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } break; case LY_TYPE_BITS: /* locate bits structure with the bits definitions */ for (type = node_type; type->der->type.der; type = &type->der->type); /* allocate the array of pointers to bits definition */ leaf->value.bit = calloc(type->info.bits.count, sizeof *leaf->value.bit); if (!leaf->value_str) { /* no bits set */ break; } c = 0; i = 0; while (leaf->value_str[c]) { /* skip leading whitespaces */ while(isspace(leaf->value_str[c])) { c++; } /* get the length of the bit identifier */ for (len = 0; leaf->value_str[c] && !isspace(leaf->value_str[c]); c++, len++); /* go back to the beginning of the identifier */ c = c - len; /* find bit definition, identifiers appear ordered by their posititon */ for (found = 0; i < type->info.bits.count; i++) { if (!strncmp(type->info.bits.bit[i].name, &leaf->value_str[c], len) && !type->info.bits.bit[i].name[len]) { /* we have match, store the pointer */ leaf->value.bit[i] = &type->info.bits.bit[i]; /* stop searching */ i++; found = 1; break; } } if (!found) { /* referenced bit value does not exists */ if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } c = c + len; } break; case LY_TYPE_BOOL: if (!strcmp(leaf->value_str, "true")) { leaf->value.bool = 1; } /* else false, so keep it zero */ break; case LY_TYPE_DEC64: /* locate dec64 structure with the fraction-digits value */ for (type = node_type; type->der->type.der; type = &type->der->type); for (c = 0; isspace(leaf->value_str[c]); c++); for (len = 0; leaf->value_str[c] && !isspace(leaf->value_str[c]); c++, len++); c = c - len; if (len > DECSIZE) { /* too long */ if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } /* normalize the number */ dec[0] = '\0'; for (i = j = d = found = 0; i < DECSIZE; i++) { if (leaf->value_str[c + i] == '.') { found = 1; j = type->info.dec64.dig; i--; c++; continue; } if (leaf->value_str[c + i] == '\0') { c--; if (!found) { j = type->info.dec64.dig; found = 1; } if (!j) { dec[i] = '\0'; break; } d++; if (d > DECSIZE - 2) { if (log) { LOGVAL(LYE_OORVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } dec[i] = '0'; } else { if (!isdigit(leaf->value_str[c + i])) { if (i || leaf->value_str[c] != '-') { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } } else { d++; } if (d > DECSIZE - 2 || (found && !j)) { if (log) { LOGVAL(LYE_OORVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } dec[i] = leaf->value_str[c + i]; } if (j) { j--; } } if (parse_int(dec, xml, -9223372036854775807L - 1L, 9223372036854775807L, 10, &num, log) || validate_length_range(2, 0, 0, ((long double)num)/(1 << type->info.dec64.dig), node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.dec64 = num; break; case LY_TYPE_EMPTY: /* just check that it is empty */ if (leaf->value_str && leaf->value_str[0]) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } break; case LY_TYPE_ENUM: if (!leaf->value_str) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), "", xml->name); } return EXIT_FAILURE; } /* locate enums structure with the enumeration definitions */ for (type = node_type; type->der->type.der; type = &type->der->type); /* find matching enumeration value */ for (i = 0; i < type->info.enums.count; i++) { if (!strcmp(leaf->value_str, type->info.enums.enm[i].name)) { /* we have match, store pointer to the definition */ leaf->value.enm = &type->info.enums.enm[i]; break; } } if (!leaf->value.enm) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } break; case LY_TYPE_IDENT: if ((strptr = strchr(leaf->value_str, ':'))) { len = strptr - leaf->value_str; if (!len) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } strptr = strndup(leaf->value_str, len); } ns = lyxml_get_ns(xml, strptr); if (!ns) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } if (strptr) { free(strptr); name = leaf->value_str + len + 1; } else { name = leaf->value_str; } leaf->value.ident = resolve_identityref(node_type->info.ident.ref, name, ns->value); if (!leaf->value.ident) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } break; case LY_TYPE_INST: if (!leaf->value_str) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), "", xml->name); } return EXIT_FAILURE; } /* convert the path from the XML form using XML namespaces into the JSON format * using module names as namespaces */ xml->content = leaf->value_str; leaf->value_str = instid_xml2json(node->schema->module->ctx, xml); lydict_remove(node->schema->module->ctx, xml->content); xml->content = NULL; if (!leaf->value_str) { return EXIT_FAILURE; } if (options & (LYD_OPT_EDIT | LYD_OPT_FILTER)) { leaf->value_type |= LY_TYPE_INST_UNRES; } else { /* validity checking is performed later, right now the data tree * is not complete, so many instanceids cannot be resolved */ /* remember the leaf for later checking */ new_unres = malloc(sizeof *new_unres); new_unres->is_leafref = 0; new_unres->dnode = node; new_unres->next = *unres; #ifndef NDEBUG new_unres->line = LOGLINE(xml); #endif *unres = new_unres; } break; case LY_TYPE_LEAFREF: if (!leaf->value_str) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), "", xml->name); } return EXIT_FAILURE; } if (options & (LYD_OPT_EDIT | LYD_OPT_FILTER)) { do { type = &((struct lys_node_leaf *)leaf->schema)->type.info.lref.target->type; } while (type->base == LY_TYPE_LEAFREF); leaf->value_type = type->base | LY_TYPE_LEAFREF_UNRES; } else { /* validity checking is performed later, right now the data tree * is not complete, so many leafrefs cannot be resolved */ /* remember the leaf for later checking */ new_unres = malloc(sizeof *new_unres); new_unres->is_leafref = 1; new_unres->dnode = node; new_unres->next = *unres; #ifndef NDEBUG new_unres->line = LOGLINE(xml); #endif *unres = new_unres; } break; case LY_TYPE_STRING: leaf->value.string = leaf->value_str; if (node_type->info.str.length && validate_length_range(0, strlen(leaf->value.string), 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } if (node_type->info.str.patterns && validate_pattern(leaf->value.string, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } break; case LY_TYPE_UNION: found = 0; type = get_next_union_type(node_type, NULL, &found); for (; type; found = 0, type = get_next_union_type(node_type, type, &found)) { xml->content = leaf->value_str; if (!_xml_get_value(node, type, xml, options, unres, 0)) { leaf->value_type = type->base; break; } } if (!type) { if (log) { LOGVAL(LYE_INVAL, LOGLINE(xml), leaf->value_str, xml->name); } return EXIT_FAILURE; } break; case LY_TYPE_INT8: if (parse_int(leaf->value_str, xml, -128, 127, 0, &num, log) || validate_length_range(1, 0, num, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.int8 = num; break; case LY_TYPE_INT16: if (parse_int(leaf->value_str, xml, -32768, 32767, 0, &num, log) || validate_length_range(1, 0, num, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.int16 = num; break; case LY_TYPE_INT32: if (parse_int(leaf->value_str, xml, -2147483648, 2147483647, 0, &num, log) || validate_length_range(1, 0, num, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.int32 = num; break; case LY_TYPE_INT64: if (parse_int(leaf->value_str, xml, -9223372036854775807L - 1L, 9223372036854775807L, 0, &num, log) || validate_length_range(1, 0, num, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.int64 = num; break; case LY_TYPE_UINT8: if (parse_uint(leaf->value_str, xml, 255, 0, &unum, log) || validate_length_range(0, unum, 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.uint8 = unum; break; case LY_TYPE_UINT16: if (parse_uint(leaf->value_str, xml, 65535, 0, &unum, log) || validate_length_range(0, unum, 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.uint16 = unum; break; case LY_TYPE_UINT32: if (parse_uint(leaf->value_str, xml, 4294967295, 0, &unum, log) || validate_length_range(0, unum, 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.uint32 = unum; break; case LY_TYPE_UINT64: if (parse_uint(leaf->value_str, xml, 18446744073709551615UL, 0, &unum, log) || validate_length_range(0, unum, 0, 0, node_type, xml, leaf->value_str, log)) { return EXIT_FAILURE; } leaf->value.uint64 = unum; break; default: return EXIT_FAILURE; }