From e87d2f9ef8a4a298de5514b30ec2d43d3c90a644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Neira=20Ayuso?= Date: Mon, 6 Jan 2014 00:51:14 +0100 Subject: src: new error reporting approach for XML/JSON parsers I have added a new structure for reporting some errors in parser that we can't cover with errno. In this patch, we have three errors that we can't cover with errno: NFT_PARSE_EBADINPUT : Bad XML/JSON format in the input NFT_PARSE_EMISSINGNODE : Missing node in our input NFT_PARSE_EBADTYPE : Wrong type value in a node Signed-off-by: Alvaro Neira Ayuso Signed-off-by: Pablo Neira Ayuso --- src/mxml.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 21 deletions(-) (limited to 'src/mxml.c') diff --git a/src/mxml.c b/src/mxml.c index 82156b7..bd09bb3 100644 --- a/src/mxml.c +++ b/src/mxml.c @@ -22,13 +22,18 @@ #include #ifdef XML_PARSING -mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename) +mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename, + struct nft_parse_err *err) { mxml_node_t *tree; tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK); - if (tree == NULL) + if (tree == NULL) { + err->error = NFT_PARSE_EBADINPUT; + err->line = 0; + err->column = 0; goto err; + } if (strcmp(tree->value.opaque, treename) == 0) return tree; @@ -39,7 +44,8 @@ err: return NULL; } -struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node) +struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node, + struct nft_parse_err *err) { mxml_node_t *tree; struct nft_rule_expr *e; @@ -48,8 +54,11 @@ struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node) int ret; expr_name = mxmlElementGetAttr(node, "type"); - if (expr_name == NULL) + if (expr_name == NULL) { + err->node_name = "type"; + err->error = NFT_PARSE_EMISSINGNODE; goto err; + } e = nft_rule_expr_alloc(expr_name); if (e == NULL) @@ -65,7 +74,7 @@ struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node) if (tree == NULL) goto err_expr; - ret = e->ops->xml_parse(e, tree); + ret = e->ops->xml_parse(e, tree, err); mxmlDelete(tree); return ret < 0 ? NULL : e; @@ -77,20 +86,24 @@ err: return NULL; } -int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags) +int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags, + struct nft_parse_err *err) { mxml_node_t *node; uint64_t val; node = mxmlFindElement(tree, tree, reg_name, NULL, NULL, flags); if (node == NULL) { + err->error = NFT_PARSE_EMISSINGNODE; errno = EINVAL; goto err; } if (nft_strtoi(node->child->value.opaque, BASE_DEC, &val, - NFT_TYPE_U64) != 0) + NFT_TYPE_U64) != 0) { + err->error = NFT_PARSE_EBADTYPE; goto err; + } if (val > NFT_REG_MAX) { errno = ERANGE; @@ -98,73 +111,101 @@ int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags) } return val; err: + err->node_name = reg_name; return -1; } int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, - union nft_data_reg *data_reg, uint16_t flags) + union nft_data_reg *data_reg, uint16_t flags, + struct nft_parse_err *err) { mxml_node_t *node; node = mxmlFindElement(tree, tree, node_name, NULL, NULL, MXML_DESCEND_FIRST); if (node == NULL || node->child == NULL) { - if (!(flags & NFT_XML_OPT)) + if (!(flags & NFT_XML_OPT)) { + err->error = NFT_PARSE_EMISSINGNODE; + err->node_name = node_name; errno = EINVAL; + } return DATA_NONE; } - return nft_data_reg_xml_parse(data_reg, node); + return nft_data_reg_xml_parse(data_reg, node, err); } int nft_mxml_num_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags, int base, void *number, - enum nft_type type, uint16_t flags) + enum nft_type type, uint16_t flags, + struct nft_parse_err *err) { mxml_node_t *node = NULL; + int ret; node = mxmlFindElement(tree, tree, node_name, NULL, NULL, mxml_flags); if (node == NULL || node->child == NULL) { - if (!(flags & NFT_XML_OPT)) + if (!(flags & NFT_XML_OPT)) { errno = EINVAL; - + err->node_name = node_name; + err->error = NFT_PARSE_EMISSINGNODE; + } return -1; } - return nft_strtoi(node->child->value.opaque, base, number, type); + + ret = nft_strtoi(node->child->value.opaque, base, number, type); + + if (ret != 0) { + err->error = NFT_PARSE_EBADTYPE; + err->node_name = node_name; + } + return ret; } const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name, - uint32_t mxml_flags, uint16_t flags) + uint32_t mxml_flags, uint16_t flags, + struct nft_parse_err *err) { mxml_node_t *node; + const char *ret; node = mxmlFindElement(tree, tree, node_name, NULL, NULL, mxml_flags); if (node == NULL || node->child == NULL) { - if (!(flags & NFT_XML_OPT)) + if (!(flags & NFT_XML_OPT)) { errno = EINVAL; - + err->node_name = node_name; + err->error = NFT_PARSE_EMISSINGNODE; + } return NULL; } - return node->child->value.opaque; + ret = node->child->value.opaque; + if (ret == NULL) { + err->node_name = node_name; + err->error = NFT_PARSE_EBADTYPE; + } + return ret; } int nft_mxml_family_parse(mxml_node_t *tree, const char *node_name, - uint32_t mxml_flags, uint16_t flags) + uint32_t mxml_flags, uint16_t flags, + struct nft_parse_err *err) { const char *family_str; int family; family_str = nft_mxml_str_parse(tree, node_name, mxml_flags, - flags); + flags, err); if (family_str == NULL) return -1; family = nft_str2family(family_str); - if (family < 0) + if (family < 0) { + err->node_name = node_name; errno = EAFNOSUPPORT; + } return family; } -- cgit v1.2.3