diff options
author | Sumit Bose <sbose@nb.localdomain> | 2008-12-08 09:19:13 +0100 |
---|---|---|
committer | Sumit Bose <sbose@nb.localdomain> | 2008-12-08 09:19:13 +0100 |
commit | 73635bb1b32450a86c78866ed8c485cc1ce3a1de (patch) | |
tree | 8540c0825412e021c691e976f16b7e17c6a2e238 | |
parent | 1be6a957fa90294f982f9e8531a05c86c49028fb (diff) | |
download | ipa_policy-73635bb1b32450a86c78866ed8c485cc1ce3a1de.tar.gz ipa_policy-73635bb1b32450a86c78866ed8c485cc1ce3a1de.tar.xz ipa_policy-73635bb1b32450a86c78866ed8c485cc1ce3a1de.zip |
some memory handling fixes
-rw-r--r-- | ipaaction/ipaaction_example_policy.xml | 2 | ||||
-rw-r--r-- | pam_selinux_roles/pam_selinux_roles.rng | 2 | ||||
-rw-r--r-- | pam_selinux_roles/pam_selinux_roles.xsl | 2 | ||||
-rw-r--r-- | pam_selinux_roles/pam_selinux_roles_example_policy.xml | 2 | ||||
-rw-r--r-- | selinux_booleans/selinux_booleans_example_policy.xml | 2 | ||||
-rw-r--r-- | worker/debug.c | 9 | ||||
-rw-r--r-- | worker/helpers.c | 17 | ||||
-rw-r--r-- | worker/ipaaction.c | 68 | ||||
-rw-r--r-- | worker/output_handler.c | 80 | ||||
-rw-r--r-- | worker/util.h | 7 | ||||
-rw-r--r-- | worker/worker.c | 17 | ||||
-rw-r--r-- | worker/xml_helper.c | 63 |
12 files changed, 171 insertions, 100 deletions
diff --git a/ipaaction/ipaaction_example_policy.xml b/ipaaction/ipaaction_example_policy.xml index d2b9045..810b002 100644 --- a/ipaaction/ipaaction_example_policy.xml +++ b/ipaaction/ipaaction_example_policy.xml @@ -27,7 +27,7 @@ </file> <run> <command>/bin/rm /tmp/something.txt</command> - <user>adm</user> + <user>root</user> </run> </ipaaction> diff --git a/pam_selinux_roles/pam_selinux_roles.rng b/pam_selinux_roles/pam_selinux_roles.rng index c00ea43..7bbe755 100644 --- a/pam_selinux_roles/pam_selinux_roles.rng +++ b/pam_selinux_roles/pam_selinux_roles.rng @@ -35,7 +35,7 @@ xmlns:pa="http://freeipa.org/xml/rng/ns/plugable_architecture/1.0"> <a:version>0.1</a:version> <define name="rng_filename"><value>pam_selinux_roles.rng</value></define> - <define name="xslt_filename"><value>pam_selinux_roles.xslt</value></define> + <define name="xslt_filename"><value>pam_selinux_roles.xsl</value></define> <define name="application_name"><value>pam_selinux_roles</value></define> <include href="policy_metadata.rng"/> diff --git a/pam_selinux_roles/pam_selinux_roles.xsl b/pam_selinux_roles/pam_selinux_roles.xsl index 587133c..177c158 100644 --- a/pam_selinux_roles/pam_selinux_roles.xsl +++ b/pam_selinux_roles/pam_selinux_roles.xsl @@ -27,7 +27,7 @@ MA 02111-1307, USA. xmlns:pse="http://freeipa.org/xml/rng/pam_selinux_roles/1.0"> <md:output_handler> - <file name="/tmp/pam_selinux-SAFE.ldif" owner="root" group="root" permission="400"/> + <md:file md:name="/tmp/pam_selinux-SAFE.ldif" md:owner="root" md:group="root" md:permission="400"/> </md:output_handler> <xsl:output method="text" indent="no"/> diff --git a/pam_selinux_roles/pam_selinux_roles_example_policy.xml b/pam_selinux_roles/pam_selinux_roles_example_policy.xml index a2b341d..256d643 100644 --- a/pam_selinux_roles/pam_selinux_roles_example_policy.xml +++ b/pam_selinux_roles/pam_selinux_roles_example_policy.xml @@ -5,7 +5,7 @@ <author>sbose@redhat.com</author> <version>0.7071</version> <RNGfile>pam_selinux_roles.rng</RNGfile> - <XSLTfile>pam_selinux_roles.xslt</XSLTfile> + <XSLTfile>pam_selinux_roles.xsl</XSLTfile> <app>pam_selinux_roles</app> </metadata> diff --git a/selinux_booleans/selinux_booleans_example_policy.xml b/selinux_booleans/selinux_booleans_example_policy.xml index 3eaa0b7..5535780 100644 --- a/selinux_booleans/selinux_booleans_example_policy.xml +++ b/selinux_booleans/selinux_booleans_example_policy.xml @@ -11,7 +11,7 @@ <ipaconfig> <selinux_boolean> - <name>webadm_manage_user_files</name> + <name>wwwebadm_manage_user_files</name> <value>true</value> </selinux_boolean> <selinux_boolean> diff --git a/worker/debug.c b/worker/debug.c index 6c65342..7253f41 100644 --- a/worker/debug.c +++ b/worker/debug.c @@ -4,16 +4,21 @@ #include <stdarg.h> #include <stdlib.h> -int debug_level = 3; +int debug_level = 5; void debug_fn(const char *format, ...) { va_list ap; char *s = NULL; + int ret; va_start(ap, format); - vasprintf(&s, format, ap); + ret=vasprintf(&s, format, ap); va_end(ap); + if (ret==-1) { + fprintf(stderr, "DEBUG_FN: vasprintf failed!!!\n"); + return; + } /*write(state.fd, s, strlen(s)); */ fprintf(stderr, s); diff --git a/worker/helpers.c b/worker/helpers.c index 5359422..18b4d77 100644 --- a/worker/helpers.c +++ b/worker/helpers.c @@ -44,7 +44,6 @@ int open_temporary_file(char *name, const char *permission, const char *user, co int ret; struct passwd *pwd_info; struct group *grp_info; - pwd_info=getpwnam(user); CHECK(pwd_info, NULL, ("Cannot find user %s.\n", user), return -1); grp_info=getgrnam(group); @@ -69,7 +68,6 @@ int open_temporary_file(char *name, const char *permission, const char *user, co CHECK(ret, -1, ("fsetfilecon failed: %s\n",strerror(errno)), return -1); } - return fd; } @@ -134,12 +132,12 @@ int exec_command(const char *command, const char *user, const char *group, char } ret=pipe(stdout_pipe); - CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), return -1); + CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), goto error); ret=pipe(stderr_pipe); - CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), return -1); + CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), goto error); pid=fork(); - CHECK(pid, -1, ("fork failed: %s",strerror(errno)), return -1); + CHECK(pid, -1, ("fork failed: %s",strerror(errno)), goto error); if (!pid) { /* FIXME: missing error checking */ close(stdout_pipe[0]); @@ -173,6 +171,9 @@ int exec_command(const char *command, const char *user, const char *group, char buffer[ret]='\0'; DEBUG(3,("stderr from child: >>%s<<\n",buffer)); + close(stdout_pipe[0]); + close(stderr_pipe[0]); + ret = waitpid(pid, & status, 0); if (WIFEXITED(status)) { DEBUG(3,("Child terminated normally with exit status %d\n",WEXITSTATUS(status))); @@ -185,4 +186,10 @@ int exec_command(const char *command, const char *user, const char *group, char free(argv[i]); } return WEXITSTATUS(status); + +error: + for(i=0;i<c;i++){ + free(argv[i]); + } + return -1; } diff --git a/worker/ipaaction.c b/worker/ipaaction.c index de01d94..f175a49 100644 --- a/worker/ipaaction.c +++ b/worker/ipaaction.c @@ -77,7 +77,6 @@ int check_ipaaction_condition(const xmlDocPtr doc, const xmlChar *default_namesp ret=exec_command(condition, user, group, arguments, NULL); - free(arguments); free(group); free(user); free(condition); @@ -86,15 +85,15 @@ int check_ipaaction_condition(const xmlDocPtr doc, const xmlChar *default_namesp } int ipaaction_file(const xmlDocPtr doc, const xmlChar *default_namespace) { - char *url; - char *data; - char *path; - char *owner; - char *group; - char *access; - char *selinux_context; + char *url=NULL; + char *data=NULL; + char *path=NULL; + char *owner=NULL; + char *group=NULL; + char *access=NULL; + char *selinux_context=NULL; //char **acl; - char *cleanup; + char *cleanup=NULL; CURL *curl_context; CURLcode curl_result; char *tmp_file_name; @@ -113,14 +112,14 @@ int ipaaction_file(const xmlDocPtr doc, const xmlChar *default_namespace) { } if (url!=NULL && data!=NULL) { DEBUG(0,("Only url or data element are allowed for ipaaction file, not both. This should never happen.\n")); - return -1; + goto failed; } path = find_value(doc, XPATH_IPAACTION_FILE_PATH, NULL); - CHECK(path, NULL, ("Path for ipaaction file not found.\n"), return -1); + CHECK(path, NULL, ("Path for ipaaction file not found.\n"), goto failed); DEBUG(3, ("Found path for ipaaction file: %s\n", path)); ret=stat(path, &stat_buffer); - CHECK(ret, 0, ("Destination file %s alread exists.\n", path), return -1); + CHECK(ret, 0, ("Destination file %s alread exists.\n", path), goto failed); owner = find_value(doc, XPATH_IPAACTION_FILE_OWNER, "root"); DEBUG(3, ("Found owner for ipaaction file: %s\n", owner)); @@ -139,16 +138,16 @@ int ipaaction_file(const xmlDocPtr doc, const xmlChar *default_namespace) { tmp_file_name=(char *) malloc(strlen(path)+7); - CHECK(tmp_file_name,NULL, ("malloc failed."), return -1); + CHECK(tmp_file_name,NULL, ("malloc failed."), goto failed); strcpy(tmp_file_name, path); strcat(tmp_file_name, ".XXXXXX"); fd=open_temporary_file(tmp_file_name, access, owner, group, selinux_context); - CHECK(fd, -1, ("Failed to open temporary file.\n"), return -1); + CHECK(fd, -1, ("Failed to open temporary file.\n"), goto failed); output_file=fdopen(fd,"w"); - CHECK(output_file, NULL, ("fdopen failed: %s\n", strerror(errno)), return -1); + CHECK(output_file, NULL, ("fdopen failed: %s\n", strerror(errno)), goto failed); if (url!=NULL) { curl_context=curl_easy_init(); - CHECK(curl_context, NULL, ("curl_easy_init failed.\n"), return -1); + CHECK(curl_context, NULL, ("curl_easy_init failed.\n"), goto failed); curl_result=curl_easy_setopt(curl_context, CURLOPT_URL, url); DEBUG(3,("curl result: %d\n",curl_result)); curl_result=curl_easy_setopt(curl_context, CURLOPT_WRITEDATA, output_file); @@ -162,10 +161,30 @@ int ipaaction_file(const xmlDocPtr doc, const xmlChar *default_namespace) { fclose(output_file); /* this should close fd, too */ ret=rename(tmp_file_name, path); - CHECK_MINUS_ONE_RETURN(ret, ("Cannot rename %s to %s: %s\n", tmp_file_name, path, strerror(errno) )); - free(tmp_file_name); + CHECK(ret, -1, ("Cannot rename %s to %s: %s\n", tmp_file_name, path, strerror(errno) ), goto failed); + free(tmp_file_name); + free(url); + free(data); + free(path); + free(owner); + free(group); + free(access); + free(selinux_context); + free(cleanup); return 0; + +failed: + free(tmp_file_name); + free(url); + free(data); + free(path); + free(owner); + free(group); + free(access); + free(selinux_context); + free(cleanup); + return -1; } int ipaaction_run(const xmlDocPtr doc, const xmlChar *default_namespace) { @@ -194,7 +213,6 @@ int ipaaction_run(const xmlDocPtr doc, const xmlChar *default_namespace) { ret=exec_command(command, user, group, arguments, NULL); - free(arguments); free(group); free(user); free(command); @@ -214,22 +232,28 @@ int handle_ipaaction(const char *policy_name, const xmlChar *default_namespace) ret=check_ipaaction_condition(doc, default_namespace); if (ret!=0) { DEBUG(0,("IPA action condition failed\n")); - return -1; + goto failed; } ret=ipaaction_file(doc, default_namespace); if (ret!=0) { DEBUG(0,("IPA action file failed\n")); - return -1; + goto failed; } ret=ipaaction_run(doc, default_namespace); if (ret!=0) { DEBUG(0,("IPA action run failed\n")); - return -1; + goto failed; } xmlFreeDoc(doc); + xmlCleanupParser(); return 0; + +failed: + xmlFreeDoc(doc); + xmlCleanupParser(); + return -1; } diff --git a/worker/output_handler.c b/worker/output_handler.c index ca55f07..7300f1d 100644 --- a/worker/output_handler.c +++ b/worker/output_handler.c @@ -45,16 +45,16 @@ char *get_output_handler_parameter(xmlNode *node, const char *name, const char * } int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_file_name) { - char *name; - char *owner; - char *group; - char *permission; - char *param_name; - char *param_value; + char *name=NULL; + char *owner=NULL; + char *group=NULL; + char *permission=NULL; + char *param_name=NULL; + char *param_value=NULL; struct stat stat_buffer; - char *dir_name; - char *tmp_file_name; - char *buffer; + char *dir_name=NULL; + char *tmp_file_name=NULL; + char *buffer=NULL; int ret; int fd; xsltStylesheetPtr parsed_stylesheet = NULL; @@ -67,25 +67,20 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil dir_name=dirname(buffer); if( (ret=stat(dir_name, &stat_buffer)) == -1) { DEBUG(0,("stat on %s failed: %s\n",dir_name, strerror(errno))); - free(name); - return -1; + goto failed; } if(!S_ISDIR(stat_buffer.st_mode)) { DEBUG(0,("%s is not a directory!\n",dir_name)); - free(name); - return -1; + goto failed; } - free(buffer); if( (ret=lstat(name, &stat_buffer)) == -1) { DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); - free(name); - return -1; + goto failed; } if(!S_ISREG(stat_buffer.st_mode)) { DEBUG(0,("%s is not a regular file!\n",name)); - free(name); - return -1; + goto failed; } owner=get_output_handler_parameter(node, "owner", "root", 0); @@ -102,7 +97,7 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil strcpy(tmp_file_name, name); strcat(tmp_file_name, ".XXXXXX"); fd=open_temporary_file(tmp_file_name, permission, owner, group, NULL); - CHECK(fd, -1, ("Failed to open temporary file.\n"), return -1); + CHECK(fd, -1, ("Failed to open temporary file.\n"), goto failed); parsed_stylesheet = xsltParseStylesheetFile((xmlChar *) xslt_file_name); CHECK_NULL_FATAL(parsed_stylesheet, ("Cannot parse stylesheet!\n")); @@ -121,6 +116,7 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil ret=rename(tmp_file_name, name); CHECK_MINUS_ONE_RETURN(ret, ("Cannot rename %s to %s: %s\n", tmp_file_name, name, strerror(errno) )); + free(buffer); free(tmp_file_name); free(name); @@ -130,6 +126,18 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil free(param_name); free(param_value); return 0; + +failed: + free(buffer); + free(tmp_file_name); + + free(name); + free(owner); + free(group); + free(permission); + free(param_name); + free(param_value); + return -1; } int output_handler_exec_with_args(xmlNode *node, const xmlDocPtr doc, const char *xslt_file_name) { @@ -177,6 +185,7 @@ int output_handler_exec_with_args(xmlNode *node, const xmlDocPtr doc, const char } xmlFreeDoc(res); xsltFreeStylesheet(parsed_stylesheet); + xsltCleanupGlobals(); cur=(char *)result_string; while ( (end_of_line = strchr(cur, '\n'))!=NULL ) { @@ -200,10 +209,10 @@ int output_handler_exec_with_args(xmlNode *node, const xmlDocPtr doc, const char int find_output_handler(const char *policy_file_name, const char *xslt_file_name) { int i; - xmlXPathContextPtr xpath_context; - xmlXPathObjectPtr xpath_obj; - xmlDocPtr xslt_doc; - xmlDocPtr doc; + xmlXPathContextPtr xpath_context=NULL; + xmlXPathObjectPtr xpath_obj=NULL; + xmlDocPtr xslt_doc=NULL; + xmlDocPtr doc=NULL; doc = xmlParseFile(policy_file_name); CHECK(doc, NULL, ("Cannot parse file %s!\n", policy_file_name), exit(1)); @@ -218,8 +227,7 @@ int find_output_handler(const char *policy_file_name, const char *xslt_file_name DEBUG(0, ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", XSLT_METADATA_NAMESPACE_PREFIX, XSLT_METADATA_NAMESPACE)); - xmlXPathFreeContext(xpath_context); - return 0; + goto failed; } xpath_obj = xmlXPathEvalExpression(XPATH_OUTPUT_HANDLER, xpath_context); @@ -227,29 +235,24 @@ int find_output_handler(const char *policy_file_name, const char *xslt_file_name DEBUG(0, ("Error: unable to evaluate xpath expression \"%s\"\n", XPATH_OUTPUT_HANDLER)); - xmlXPathFreeContext(xpath_context); - return 0; + goto failed; } if (xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)) { DEBUG(0, ("Nothing found for %s\n", XPATH_OUTPUT_HANDLER)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return 0; + goto failed; } for (i=0; i<xmlXPathNodeSetGetLength(xpath_obj->nodesetval); i++) { DEBUG(3, ("found output_handler: %s\n",(char *) xpath_obj->nodesetval->nodeTab[i]->name)); - print_all_attributes(xpath_obj->nodesetval->nodeTab[i]); + /*print_all_attributes(xpath_obj->nodesetval->nodeTab[i]);*/ if ( xmlStrEqual(xpath_obj->nodesetval->nodeTab[i]->name, (xmlChar *) "file" )) { output_handler_file(xpath_obj->nodesetval->nodeTab[i], doc, xslt_file_name); } else if ( xmlStrEqual(xpath_obj->nodesetval->nodeTab[i]->name, (xmlChar *) "exec_with_args" )) { output_handler_exec_with_args(xpath_obj->nodesetval->nodeTab[i], doc, xslt_file_name); } else { DEBUG(0, ("Unknow outout handler '%s'.\n", xpath_obj->nodesetval->nodeTab[i]->name)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return -1; + goto failed; } } @@ -258,5 +261,14 @@ int find_output_handler(const char *policy_file_name, const char *xslt_file_name xmlXPathFreeContext(xpath_context); xmlFreeDoc(xslt_doc); xmlFreeDoc(doc); + xmlCleanupParser(); return 0; + +failed: + xmlXPathFreeObject(xpath_obj); + xmlXPathFreeContext(xpath_context); + xmlFreeDoc(xslt_doc); + xmlFreeDoc(doc); + xmlCleanupParser(); + return -1; } diff --git a/worker/util.h b/worker/util.h index 77126b4..5bf0541 100644 --- a/worker/util.h +++ b/worker/util.h @@ -4,6 +4,13 @@ extern int debug_level; void debug_fn(const char *format, ...); +#include <malloc.h> +#define MEMINFO do{ \ + struct mallinfo minfo; \ + minfo=mallinfo(); \ + DEBUG(5, ("---allocated space: %d-----\n",minfo.uordblks)); \ +}while(0) + #define DEBUG(level, body) do { \ if (level <= debug_level) { \ debug_fn("DEBUG-%d (%s,%d): %s: ", level, __FILE__, __LINE__ , __FUNCTION__); \ diff --git a/worker/worker.c b/worker/worker.c index cb8e813..01a7be7 100644 --- a/worker/worker.c +++ b/worker/worker.c @@ -21,6 +21,8 @@ #define _GNU_SOURCE #include <string.h> #include <stdlib.h> +#include <malloc.h> +#include <mcheck.h> #include "helpers.h" @@ -29,6 +31,13 @@ #include "ipaaction.h" #include "output_handler.h" +int my_mallinfo () { + struct mallinfo info = mallinfo(); + printf ("arena: %d\n", info.arena); + return 0; +} + + int main(int argc, char **argv) { @@ -37,6 +46,8 @@ int main(int argc, char **argv) char *ipa_policy_type; char *policy_file_name; + mtrace(); + if (argc != 2) { DEBUG(0, ("missing or to many arguments, I expect a single filename!\n")); @@ -47,11 +58,13 @@ int main(int argc, char **argv) validate_policy(policy_file_name, &ipa_policy_type, &xslt_file_name); + if ( strncmp( ipa_policy_type, "ipaaction", 9)==0) { handle_ipaaction(policy_file_name); } else { find_output_handler(policy_file_name, xslt_file_name); + find_output_handler(policy_file_name, xslt_file_name); free(xslt_file_name); } @@ -59,5 +72,9 @@ int main(int argc, char **argv) free(ipa_policy_type); free(policy_file_name); + xmlCleanupParser(); + printf("xmlMemUsed: %d\n",xmlMemUsed()); + + muntrace(); return 0; } diff --git a/worker/xml_helper.c b/worker/xml_helper.c index 35932e8..8eff726 100644 --- a/worker/xml_helper.c +++ b/worker/xml_helper.c @@ -46,13 +46,14 @@ xmlChar *default_namespace_prefix = (xmlChar *) "def"; int validate_policy(const char *policy_file_name, char **ipa_policy_type, char **xslt_file_name) { xmlDocPtr doc; char *rng_file_name; + xmlRelaxNGParserCtxtPtr rng_parser_context; + xmlRelaxNGPtr rng_schema; xmlRelaxNGValidCtxtPtr rng_context; xmlChar xpath_expr[XMLCHARLEN]; doc = xmlParseFile(policy_file_name); CHECK(doc, NULL, ("Cannot parse document %s!\n", policy_file_name), exit(1)); - xmlStrPrintf(xpath_expr, XMLCHARLEN, (xmlChar *) "//%s:ipa/*[2]", default_namespace_prefix); *ipa_policy_type = find_by_xpath(doc, xpath_expr, FIND_NAME); @@ -73,11 +74,12 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * DEBUG(3, ("Found name of RELAX NG schema file: %s\n", rng_file_name)); - /* validate the document */ - rng_context = - xmlRelaxNGNewValidCtxt(xmlRelaxNGParse - (xmlRelaxNGNewParserCtxt(rng_file_name))); + rng_parser_context = xmlRelaxNGNewParserCtxt(rng_file_name); + CHECK(rng_parser_context, NULL, ("Failed to parse RNG file\n"), exit(1)); + rng_schema = xmlRelaxNGParse(rng_parser_context); + CHECK(rng_schema, NULL, ("Failed to create RNG schema\n"), exit(1)); + rng_context = xmlRelaxNGNewValidCtxt(rng_schema); CHECK(rng_context, NULL, ("Failed to create RNG context\n"), exit(1)); if (xmlRelaxNGValidateDoc(rng_context, doc) == 0) { DEBUG(3, ("The document is valid.\n")); @@ -87,6 +89,8 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * } xmlRelaxNGFreeValidCtxt(rng_context); + xmlRelaxNGFree(rng_schema); + xmlRelaxNGFreeParserCtxt(rng_parser_context); free(rng_file_name); @@ -99,6 +103,7 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * } xmlFreeDoc(doc); + xmlCleanupParser(); return 0; } @@ -140,7 +145,7 @@ xmlChar *get_default_namespace(xmlDocPtr doc) { } CHECK(root_node->ns->href, NULL, ("Root node of the current document must define a namespace!\n"), return NULL); - default_namespace = xmlStrndup(root_node->ns->href, XMLCHARLEN); + default_namespace = xmlStrdup(root_node->ns->href); CHECK(default_namespace, NULL, ("Cannot copy namespace!\n"), return NULL); DEBUG(3, ("Default namespace is %s\n", default_namespace)); @@ -164,47 +169,36 @@ xmlChar *get_default_namespace(xmlDocPtr doc) { */ char *find_by_xpath(const xmlDocPtr doc, const xmlChar * xpath_expr, const int type) { - - xmlXPathContextPtr xpath_context; - xmlXPathObjectPtr xpath_obj; + int ret; + xmlXPathContextPtr xpath_context=NULL; + xmlXPathObjectPtr xpath_obj=NULL; char *result = NULL; - xmlChar *namespace; + xmlChar *namespace=NULL; namespace = get_default_namespace(doc); CHECK(namespace, NULL, ("No default namespace found.\n"), return NULL); /* Create xpath evaluation context */ xpath_context = xmlXPathNewContext(doc); - CHECK_NULL_FATAL(xpath_context, - ("Error: unable to create new XPath context\n")); + CHECK(xpath_context, NULL, + ("Error: unable to create new XPath context\n"), goto failed); /* Register a namespace */ - if (xmlXPathRegisterNs(xpath_context, default_namespace_prefix, namespace) != 0) { - DEBUG(0, - ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", - default_namespace_prefix , namespace)); - xmlXPathFreeContext(xpath_context); - return NULL; - } + ret=xmlXPathRegisterNs(xpath_context, default_namespace_prefix, namespace); + CHECK(ret, -1, + ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", + default_namespace_prefix , namespace), goto failed); /* Evaluate xpath expression */ xpath_obj = xmlXPathEvalExpression(xpath_expr, xpath_context); - if (xpath_obj == NULL) { - DEBUG(0, - ("Error: unable to evaluate xpath expression \"%s\"\n", - xpath_expr)); - xmlXPathFreeContext(xpath_context); - return NULL; - } + CHECK(xpath_obj, NULL, + ("Error: unable to evaluate xpath expression \"%s\"\n", xpath_expr), + goto failed); if (xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)) { DEBUG(0, ("Nothing found for %s\n", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return NULL; + goto failed; } else if (xmlXPathNodeSetGetLength(xpath_obj->nodesetval) != 1) { DEBUG(0, ("More than one node found for %s!", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return NULL; + goto failed; } else { switch (type) { case FIND_NAME: @@ -226,4 +220,9 @@ char *find_by_xpath(const xmlDocPtr doc, const xmlChar * xpath_expr, const int t xmlXPathFreeContext(xpath_context); return result; +failed: + xmlFree(namespace); + xmlXPathFreeObject(xpath_obj); + xmlXPathFreeContext(xpath_context); + return NULL; } |