summaryrefslogtreecommitdiff
path: root/xmllint.c
diff options
context:
space:
mode:
Diffstat (limited to 'xmllint.c')
-rw-r--r--xmllint.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/xmllint.c b/xmllint.c
index e91707c..a72fcca 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -92,6 +92,9 @@
#ifdef LIBXML_PATTERN_ENABLED
#include <libxml/pattern.h>
#endif
+#ifdef LIBXML_C14N_ENABLED
+#include <libxml/c14n.h>
+#endif
#ifndef XML_XML_DEFAULT_CATALOG
#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
@@ -168,6 +171,9 @@ static int dropdtd = 0;
static int catalogs = 0;
static int nocatalogs = 0;
#endif
+#ifdef LIBXML_C14N_ENABLED
+static int canonical = 0;
+#endif
#ifdef LIBXML_READER_ENABLED
static int stream = 0;
static int walker = 0;
@@ -184,6 +190,115 @@ static xmlPatternPtr patternc = NULL;
static int options = 0;
/************************************************************************
+ * *
+ * Entity loading control and customization. *
+ * *
+ ************************************************************************/
+#define MAX_PATHS 64
+static xmlChar *paths[MAX_PATHS + 1];
+static int nbpaths = 0;
+static int load_trace = 0;
+
+static
+void parsePath(const xmlChar *path) {
+ const xmlChar *cur;
+
+ if (path == NULL)
+ return;
+ while (*path != 0) {
+ if (nbpaths >= MAX_PATHS) {
+ fprintf(stderr, "MAX_PATHS reached: too many paths\n");
+ return;
+ }
+ cur = path;
+ while ((*cur == ' ') || (*cur == ':'))
+ cur++;
+ path = cur;
+ while ((*cur != 0) && (*cur != ' ') && (*cur != ':'))
+ cur++;
+ if (cur != path) {
+ paths[nbpaths] = xmlStrndup(path, cur - path);
+ if (paths[nbpaths] != NULL)
+ nbpaths++;
+ path = cur;
+ }
+ }
+}
+
+xmlExternalEntityLoader defaultEntityLoader = NULL;
+
+static xmlParserInputPtr
+xmllintExternalEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ xmlParserInputPtr ret;
+ warningSAXFunc warning = NULL;
+
+ int i;
+ const char *lastsegment = URL;
+ const char *iter = URL;
+
+ if (nbpaths > 0) {
+ while (*iter != 0) {
+ if (*iter == '/')
+ lastsegment = iter + 1;
+ iter++;
+ }
+ }
+
+ if ((ctxt != NULL) && (ctxt->sax != NULL)) {
+ warning = ctxt->sax->warning;
+ ctxt->sax->warning = NULL;
+ }
+
+ if (defaultEntityLoader != NULL) {
+ ret = defaultEntityLoader(URL, ID, ctxt);
+ if (ret != NULL) {
+ if (warning != NULL)
+ ctxt->sax->warning = warning;
+ if (load_trace) {
+ fprintf \
+ (stderr,
+ "Loaded URL=\"%s\" ID=\"%s\"\n",
+ URL ? URL : "(null)",
+ ID ? ID : "(null)");
+ }
+ return(ret);
+ }
+ }
+ for (i = 0;i < nbpaths;i++) {
+ xmlChar *newURL;
+
+ newURL = xmlStrdup((const xmlChar *) paths[i]);
+ newURL = xmlStrcat(newURL, (const xmlChar *) "/");
+ newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
+ if (newURL != NULL) {
+ ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
+ if (ret != NULL) {
+ if (warning != NULL)
+ ctxt->sax->warning = warning;
+ if (load_trace) {
+ fprintf \
+ (stderr,
+ "Loaded URL=\"%s\" ID=\"%s\"\n",
+ newURL,
+ ID ? ID : "(null)");
+ }
+ xmlFree(newURL);
+ return(ret);
+ }
+ xmlFree(newURL);
+ }
+ }
+ if (warning != NULL) {
+ ctxt->sax->warning = warning;
+ if (URL != NULL)
+ warning(ctxt, "failed to load external entity \"%s\"\n", URL);
+ else if (ID != NULL)
+ warning(ctxt, "failed to load external entity \"%s\"\n", ID);
+ }
+ return(NULL);
+}
+/************************************************************************
* *
* Memory allocation consumption debugging *
* *
@@ -1209,6 +1324,21 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
}
} else
#endif
+#ifdef LIBXML_C14N_ENABLED
+ if (canonical) {
+ xmlChar *result = NULL;
+ int size;
+
+ size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
+ if (size >= 0) {
+ write(1, result, size);
+ xmlFree(result);
+ } else {
+ fprintf(stderr, "Failed to canonicalize\n");
+ progresult = XMLLINT_ERR_OUT;
+ }
+ } else
+#endif
#ifdef HAVE_SYS_MMAN_H
if (memory) {
xmlChar *result;
@@ -1228,6 +1358,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
}
if (result == NULL) {
fprintf(stderr, "Failed to save\n");
+ progresult = XMLLINT_ERR_OUT;
} else {
write(1, result, len);
xmlFree(result);
@@ -1542,6 +1673,8 @@ static void usage(const char *name) {
printf("\t--recover : output what was parsable on broken XML documents\n");
printf("\t--noent : substitute entity references by their value\n");
printf("\t--noout : don't output the result tree\n");
+ printf("\t--path 'paths': provide a set of paths for resources\n");
+ printf("\t--load-trace : print trace of all external entites loaded\n");
printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
printf("\t--htmlout : output results as HTML\n");
printf("\t--nowrap : do not put HTML doc wrapper\n");
@@ -1579,6 +1712,9 @@ static void usage(const char *name) {
printf("\t--encode encoding : output in the given encoding\n");
printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
#endif /* LIBXML_OUTPUT_ENABLED */
+ printf("\t--c14n: save in W3C canonical format (with comments)\n");
+#ifdef LIBXML_C14N_ENABLED
+#endif /* LIBXML_C14N_ENABLED */
printf("\t--nsclean : remove redundant namespace declarations\n");
printf("\t--testIO : test user I/O support\n");
#ifdef LIBXML_CATALOG_ENABLED
@@ -1590,6 +1726,7 @@ static void usage(const char *name) {
printf("\t--auto : generate a small doc on the fly\n");
#ifdef LIBXML_XINCLUDE_ENABLED
printf("\t--xinclude : do XInclude processing\n");
+ printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
#endif
printf("\t--loaddtd : fetch external DTD\n");
printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
@@ -1777,6 +1914,12 @@ main(int argc, char **argv) {
xinclude++;
options |= XML_PARSE_XINCLUDE;
}
+ else if ((!strcmp(argv[i], "-noxincludenode")) ||
+ (!strcmp(argv[i], "--noxincludenode"))) {
+ xinclude++;
+ options |= XML_PARSE_XINCLUDE;
+ options |= XML_PARSE_NOXINCNODE;
+ }
#endif
#ifdef LIBXML_OUTPUT_ENABLED
#ifdef HAVE_ZLIB_H
@@ -1806,6 +1949,13 @@ main(int argc, char **argv) {
xmlParserDebugEntities = 1;
}
#endif
+#ifdef LIBXML_C14N_ENABLED
+ else if ((!strcmp(argv[i], "-c14n")) ||
+ (!strcmp(argv[i], "--c14n"))) {
+ canonical++;
+ options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+ }
+#endif
#ifdef LIBXML_CATALOG_ENABLED
else if ((!strcmp(argv[i], "-catalogs")) ||
(!strcmp(argv[i], "--catalogs"))) {
@@ -1883,6 +2033,13 @@ main(int argc, char **argv) {
} else if ((!strcmp(argv[i], "-nonet")) ||
(!strcmp(argv[i], "--nonet"))) {
options |= XML_PARSE_NONET;
+ } else if ((!strcmp(argv[i], "-load-trace")) ||
+ (!strcmp(argv[i], "--load-trace"))) {
+ load_trace++;
+ } else if ((!strcmp(argv[i], "-path")) ||
+ (!strcmp(argv[i], "--path"))) {
+ i++;
+ parsePath(BAD_CAST argv[i]);
#ifdef LIBXML_PATTERN_ENABLED
} else if ((!strcmp(argv[i], "-pattern")) ||
(!strcmp(argv[i], "--pattern"))) {
@@ -1929,6 +2086,9 @@ main(int argc, char **argv) {
}
+ defaultEntityLoader = xmlGetExternalEntityLoader();
+ xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
+
xmlLineNumbersDefault(1);
if (loaddtd != 0)
xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
@@ -2036,6 +2196,11 @@ main(int argc, char **argv) {
(!strcmp(argv[i], "--dtdvalid"))) {
i++;
continue;
+ }
+ if ((!strcmp(argv[i], "-path")) ||
+ (!strcmp(argv[i], "--path"))) {
+ i++;
+ continue;
}
if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
(!strcmp(argv[i], "--dtdvalidfpi"))) {