static void edns_opt_bad_test(const char *txt, int code) { int ret; uint8_t b[64]; size_t b_len = sizeof(b); yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, edns_opt_to_bin, edns_opt_to_txt } }; diag("edns option \"%s\":", txt); ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); ok(ret == code, "invalid txt to bin"); }
static void addr_range_test(const char *txt) { int ret; uint8_t b[64]; size_t b_len = sizeof(b); char t[64]; size_t t_len = sizeof(t); yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, addr_range_to_bin, addr_range_to_txt } }; diag("address range \"%s\":", txt); ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); ok(ret == KNOT_EOK, "txt to bin"); ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); ok(ret == KNOT_EOK, "bin to txt"); ok(strlen(t) == t_len, "txt ret length"); ok(strlen(txt) == t_len, "txt length"); ok(memcmp(txt, t, t_len) == 0, "compare"); }
int yp_item_to_bin( const yp_item_t *item, const char *txt, size_t txt_len, uint8_t *bin, size_t *bin_len) { if (item == NULL || txt == NULL || bin == NULL || bin_len == NULL) { return KNOT_EINVAL; } switch (item->type) { case YP_TINT: return yp_int_to_bin(txt, txt_len, bin, bin_len, item->var.i.min, item->var.i.max, 0, item->var.i.unit); case YP_TBOOL: return yp_bool_to_bin(txt, txt_len, bin, bin_len); case YP_TOPT: return yp_option_to_bin(txt, txt_len, bin, bin_len, item->var.o.opts); case YP_TSTR: return yp_str_to_bin(txt, txt_len, bin, bin_len); case YP_TADDR: return yp_addr_to_bin(txt, txt_len, bin, bin_len, false); case YP_TNET: return yp_addr_to_bin(txt, txt_len, bin, bin_len, true); case YP_TDNAME: return yp_dname_to_bin(txt, txt_len, bin, bin_len); case YP_TB64: return yp_base64_to_bin(txt, txt_len, bin, bin_len); case YP_TDATA: return item->var.d.to_bin(txt, txt_len, bin, bin_len); case YP_TREF: return yp_item_to_bin(item->var.r.ref->var.g.id, txt, txt_len, bin, bin_len); default: *bin_len = 0; return KNOT_EOK; } }
static void edns_opt_test(const char *txt, uint16_t code, const char *val) { int ret; uint8_t b[64]; size_t b_len = sizeof(b); char t[64]; size_t t_len = sizeof(t); yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, edns_opt_to_bin, edns_opt_to_txt } }; diag("edns option \"%s\":", txt); ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); ok(ret == KNOT_EOK, "txt to bin"); uint64_t c = wire_read_u64(b); ok(c == code, "compare code"); ok(memcmp(yp_bin(b + sizeof(uint64_t)), val, yp_bin_len(b + sizeof(uint64_t))) == 0, "compare"); ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); ok(ret == KNOT_EOK, "bin to txt"); ok(strlen(t) == t_len, "txt ret length"); ok(strlen(txt) == t_len, "txt length"); ok(memcmp(txt, t, t_len) == 0, "compare"); }
static int check_item( const char *key, size_t key_len, const char *data, size_t data_len, yp_check_ctx_t *ctx, bool allow_key1_without_id) { yp_node_t *node = &ctx->nodes[ctx->current]; yp_node_t *parent = node->parent; bool is_id = false; if (parent != NULL) { // Check for invalid indentation. if (parent->item == NULL) { return KNOT_YP_EINVAL_INDENT; } // Check if valid group parent. if (parent->item->type != YP_TGRP) { return KNOT_YP_EINVAL_ITEM; } // Check if valid subitem. node->item = find_item(key, key_len, parent->item->sub_items); } else { node->item = find_item(key, key_len, ctx->scheme); } if (node->item == NULL) { return KNOT_YP_EINVAL_ITEM; } // Check if the parent requires id specification. if (parent != NULL && parent->item->var.g.id != NULL) { // Check if id. if (node->item == parent->item->var.g.id) { is_id = true; // Move current to the parent. --(ctx->current); // Check for missing id. } else if (parent->id_len == 0 && !allow_key1_without_id) { return KNOT_YP_ENOID; } } // Return if no data provided. if (data == NULL) { return KNOT_EOK; } // Group cannot have data. if (data_len != 0 && node->item->type == YP_TGRP) { return KNOT_YP_ENOTSUP_DATA; } // Convert item data to binary format. const yp_item_t *item = (node->item->type != YP_TREF) ? node->item : node->item->var.r.ref->var.g.id; if (is_id) { // Textual id must not be empty. if (data_len == 0) { return KNOT_YP_ENODATA; } parent->id_len = sizeof(((yp_node_t *)NULL)->id); int ret = yp_item_to_bin(item, data, data_len, parent->id, &parent->id_len); // Binary id must not be empty. if (ret == KNOT_EOK && parent->id_len == 0) { return KNOT_YP_EINVAL_DATA; } return ret; } else { node->data_len = sizeof(((yp_node_t *)NULL)->data); int ret = yp_item_to_bin(item, data, data_len, node->data, &node->data_len); return ret; } }