summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>2013-09-13 14:45:21 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-09-16 12:47:57 +0200
commit2f5a7c560ab5e20111f6196181a603e1bd3f8791 (patch)
treefd31f5583e86184e878bf80faab03355cd6667ec
parentf4befc129827632209779c71d804f6139ac03541 (diff)
src: xml: avoid unecessary tree to text to tree conversions
This patch avoid several tree to text to tree conversions in the XML parsing helpers. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/expr/data_reg.c184
-rw-r--r--src/expr/data_reg.h2
-rw-r--r--src/mxml.c59
3 files changed, 50 insertions, 195 deletions
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index fd1dd2e..64a6c16 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -102,118 +102,49 @@ int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data)
}
#ifdef XML_PARSING
-static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg, char *xml)
+static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg,
+ mxml_node_t *tree)
{
- mxml_node_t *tree = NULL;
- mxml_node_t *node = NULL;
int verdict;
const char *verdict_str;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
- MXML_DESCEND_FIRST);
-
- if (node == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- /* Get and validate <data_reg type="verdict" >*/
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp(mxmlElementGetAttr(node, "type"), "verdict") != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
- /* Get and set <verdict> */
- verdict_str = nft_mxml_str_parse(tree, "verdict", MXML_DESCEND,
+ verdict_str = nft_mxml_str_parse(tree, "verdict", MXML_DESCEND_FIRST,
NFT_XML_MAND);
- if (verdict_str == NULL) {
- mxmlDelete(tree);
- return -1;
- }
+ if (verdict_str == NULL)
+ return DATA_NONE;
verdict = nft_str2verdict(verdict_str);
- if (verdict < 0) {
- mxmlDelete(tree);
- return -1;
- }
+ if (verdict < 0)
+ return DATA_NONE;
reg->verdict = (uint32_t)verdict;
- mxmlDelete(tree);
- return 0;
+ return DATA_VERDICT;
}
-static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg, char *xml)
+static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg,
+ mxml_node_t *tree)
{
- mxml_node_t *tree = NULL;
- mxml_node_t *node = NULL;
+ const char *chain;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
- MXML_DESCEND_FIRST);
-
- if (node == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- /* Get and validate <data_reg type="chain" >*/
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp(mxmlElementGetAttr(node, "type"), "chain") != 0) {
- mxmlDelete(tree);
- return -1;
- }
+ chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST,
+ NFT_XML_MAND);
+ if (chain == NULL)
+ return DATA_NONE;
- /* Get and set <chain> */
if (reg->chain)
xfree(reg->chain);
- reg->chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND,
- NFT_XML_MAND);
- if (reg->chain == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- mxmlDelete(tree);
- return 0;
+ reg->chain = strdup(chain);
+ return DATA_CHAIN;
}
-static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, char *xml)
+static int nft_data_reg_value_xml_parse(union nft_data_reg *reg,
+ mxml_node_t *tree)
{
- mxml_node_t *tree = NULL;
- mxml_node_t *node = NULL;
int i;
char node_name[6];
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
- MXML_DESCEND_FIRST);
-
- if (node == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
/*
* <data_reg type="value">
* <len>16</len>
@@ -224,77 +155,52 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, char *xml)
* </data_reg>
*/
- /* Get and validate <data_reg type="value" ... >*/
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp(mxmlElementGetAttr(node, "type"), "value") != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (nft_mxml_num_parse(tree, "len", MXML_DESCEND, BASE_DEC, &reg->len,
- NFT_TYPE_U8, NFT_XML_MAND) != 0) {
- mxmlDelete(tree);
- return -1;
- }
+ if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
+ &reg->len, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+ return DATA_NONE;
/* Get and set <dataN> */
for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
sprintf(node_name, "data%d", i);
- if (nft_mxml_num_parse(tree, node_name, MXML_DESCEND, BASE_HEX,
- &reg->val[i], NFT_TYPE_U32,
- NFT_XML_MAND) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
+ if (nft_mxml_num_parse(tree, node_name, MXML_DESCEND_FIRST,
+ BASE_HEX, &reg->val[i], NFT_TYPE_U32,
+ NFT_XML_MAND) != 0)
+ return DATA_NONE;
}
- mxmlDelete(tree);
- return 0;
+ return DATA_VALUE;
}
#endif
-int nft_data_reg_xml_parse(union nft_data_reg *reg, char *xml)
+int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree)
{
#ifdef XML_PARSING
- mxml_node_t *node = NULL;
- mxml_node_t *tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
-
- if (tree == NULL)
- return -1;
+ const char *type;
+ mxml_node_t *node;
- node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
+ node = mxmlFindElement(tree, tree, "data_reg", "type", NULL,
MXML_DESCEND_FIRST);
if (node == NULL) {
- mxmlDelete(tree);
- return -1;
+ errno = EINVAL;
+ return DATA_NONE;
}
- /* Get <data_reg type="xxx" ... >*/
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
+ type = mxmlElementGetAttr(node, "type");
- /* Select what type of parsing is needed */
- if (strcmp(mxmlElementGetAttr(node, "type"), "value") == 0) {
- mxmlDelete(tree);
- return nft_data_reg_value_xml_parse(reg, xml);
- } else if (strcmp(mxmlElementGetAttr(node, "type"), "verdict") == 0) {
- mxmlDelete(tree);
- return nft_data_reg_verdict_xml_parse(reg, xml);
- } else if (strcmp(mxmlElementGetAttr(node, "type"), "chain") == 0) {
- mxmlDelete(tree);
- return nft_data_reg_chain_xml_parse(reg, xml);
+ if (type == NULL) {
+ errno = EINVAL;
+ return DATA_NONE;
}
- mxmlDelete(tree);
- return -1;
+ if (strcmp(type, "value") == 0)
+ return nft_data_reg_value_xml_parse(reg, node);
+ else if (strcmp(type, "verdict") == 0)
+ return nft_data_reg_verdict_xml_parse(reg, node);
+ else if (strcmp(type, "chain") == 0)
+ return nft_data_reg_chain_xml_parse(reg, node);
+
+ return DATA_NONE;
#else
errno = EOPNOTSUPP;
return -1;
diff --git a/src/expr/data_reg.h b/src/expr/data_reg.h
index 3e0217d..f41a483 100644
--- a/src/expr/data_reg.h
+++ b/src/expr/data_reg.h
@@ -25,7 +25,7 @@ union nft_data_reg {
int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg,
uint32_t output_format, uint32_t flags, int reg_type);
-int nft_data_reg_xml_parse(union nft_data_reg *reg, char *xml);
+int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree);
int nft_parse_data(union nft_data_reg *data, struct nlattr *attr, int *type);
int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data);
diff --git a/src/mxml.c b/src/mxml.c
index 94d26e4..6b7ca68 100644
--- a/src/mxml.c
+++ b/src/mxml.c
@@ -86,68 +86,17 @@ int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name,
union nft_data_reg *data_reg, uint16_t flags)
{
mxml_node_t *node;
- const char *type;
- char *tmpstr = NULL;
- int ret;
node = mxmlFindElement(tree, tree, node_name, NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL || node->child == NULL) {
- if (flags & NFT_XML_OPT)
- return 0;
-
- errno = EINVAL;
- goto err;
- }
-
- tmpstr = mxmlSaveAllocString(node, MXML_NO_CALLBACK);
- if (tmpstr == NULL) {
- errno = ENOMEM;
- goto err;
- }
-
- ret = nft_data_reg_xml_parse(data_reg, tmpstr);
- xfree(tmpstr);
-
- if (ret < 0) {
- if (flags & NFT_XML_OPT)
- return 0;
-
- errno = EINVAL;
- goto err;
- }
-
- node = mxmlFindElement(node, node, "data_reg", NULL, NULL,
- MXML_DESCEND);
- if (node == NULL || node->child == NULL) {
- if (flags & NFT_XML_OPT)
- return 0;
-
- errno = EINVAL;
- goto err;
- }
-
- type = mxmlElementGetAttr(node, "type");
- if (type == NULL) {
- if (flags & NFT_XML_OPT)
- return DATA_NONE;
-
- errno = EINVAL;
- goto err;
- }
+ if (!(flags & NFT_XML_OPT))
+ errno = EINVAL;
- if (strcmp(type, "value") == 0)
- return DATA_VALUE;
- else if (strcmp(type, "verdict") == 0)
- return DATA_VERDICT;
- else if (strcmp(type, "chain") == 0)
- return DATA_CHAIN;
- else if (flags & NFT_XML_OPT)
return DATA_NONE;
+ }
- errno = EINVAL;
-err:
- return -1;
+ return nft_data_reg_xml_parse(data_reg, node);
}
int