Commit 5d90b6c9 authored by Daniel Veillard's avatar Daniel Veillard
Browse files

added support and APIs needed for the catalog PI cleanup Daniel

* include/libxml/catalog.h include/libxml/parser.h
  include/libxml/xmlerror.h catalog.c parser.c parserInternals.c
  xmlIO.c: added support and APIs needed for the catalog PI
* include/libxml/xmlIO.h: cleanup
Daniel
parent e2940ddb
Wed Aug 22 16:27:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
* include/libxml/catalog.h include/libxml/parser.h
include/libxml/xmlerror.h catalog.c parser.c parserInternals.c
xmlIO.c: added support and APIs needed for the catalog PI
* include/libxml/xmlIO.h: cleanup
Wed Aug 22 02:03:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
* catalog.c parser.c xmlIO.c xmlcatalog.c xmllint.c
......
......@@ -93,10 +93,11 @@ struct _xmlCatalogEntry {
xmlCatalogPrefer prefer;
};
static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_SYSTEM;
static xmlHashTablePtr xmlDefaultCatalog;
static xmlCatalogEntryPtr xmlDefaultXMLCatalogList = NULL;
static int xmlCatalogInitialized = 0;
static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_SYSTEM;
/* Catalog stack */
......@@ -1562,7 +1563,17 @@ xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
*/
static const xmlChar *
xmlCatalogSGMLResolve(const xmlChar *pubID, const xmlChar *sysID) {
TODO
const xmlChar *ret = NULL;
if (xmlDefaultCatalog == NULL)
return(NULL);
if (pubID != NULL)
ret = xmlCatalogGetSGMLPublic(xmlDefaultCatalog, pubID);
if (ret != NULL)
return(ret);
if (sysID != NULL)
ret = xmlCatalogGetSGMLSystem(xmlDefaultCatalog, sysID);
return(NULL);
}
......@@ -2010,12 +2021,59 @@ xmlCatalogRemove(const xmlChar *value) {
return(res);
}
/**
* xmlCatalogGetDefaults:
*
* Used to get the user preference w.r.t. to what catalogs should
* be accepted
*
* Returns the current xmlCatalogAllow value
*/
xmlCatalogAllow
xmlCatalogGetDefaults(void) {
return(xmlCatalogDefaultAllow);
}
/**
* xmlCatalogSetDefaults:
*
* Used to set the user preference w.r.t. to what catalogs should
* be accepted
*/
void
xmlCatalogSetDefaults(xmlCatalogAllow allow) {
if (!xmlCatalogInitialized)
xmlInitializeCatalog();
if (xmlDebugCatalogs) {
switch (allow) {
case XML_CATA_ALLOW_NONE:
xmlGenericError(xmlGenericErrorContext,
"Disabling catalog usage\n");
break;
case XML_CATA_ALLOW_GLOBAL:
xmlGenericError(xmlGenericErrorContext,
"Allowing only global catalogs\n");
break;
case XML_CATA_ALLOW_DOCUMENT:
xmlGenericError(xmlGenericErrorContext,
"Allowing only catalogs from the document\n");
break;
case XML_CATA_ALLOW_ALL:
xmlGenericError(xmlGenericErrorContext,
"Allowing all catalogs\n");
break;
}
}
xmlCatalogDefaultAllow = allow;
}
/**
* xmlCatalogSetDefaultPrefer:
* @prefer: the default preference for delegation
*
* Allows to set the preference between public and system for deletion
* in XML Catalog resolution. C.f. section 4.1.1 of the spec
* Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
*
* Returns the previous value of the default preference for delegation
*/
......@@ -2023,6 +2081,25 @@ xmlCatalogPrefer
xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
if (!xmlCatalogInitialized)
xmlInitializeCatalog();
if (prefer == XML_CATA_PREFER_NONE)
return(ret);
if (xmlDebugCatalogs) {
switch (prefer) {
case XML_CATA_PREFER_PUBLIC:
xmlGenericError(xmlGenericErrorContext,
"Setting catalog preference to PUBLIC\n");
break;
case XML_CATA_PREFER_SYSTEM:
xmlGenericError(xmlGenericErrorContext,
"Setting catalog preference to SYSTEM\n");
break;
case XML_CATA_PREFER_NONE:
break;
}
}
xmlCatalogDefaultPrefer = prefer;
return(ret);
}
......@@ -2046,4 +2123,83 @@ xmlCatalogSetDebug(int level) {
xmlDebugCatalogs = level;
return(ret);
}
/**
* xmlCatalogFreeLocal:
* @catalogs: a document's list of catalogs
*
* Free up the memory associated to the catalog list
*/
void
xmlCatalogFreeLocal(void *catalogs) {
xmlCatalogEntryPtr catal;
catal = (xmlCatalogEntryPtr) catalogs;
if (catal != NULL)
xmlFreeCatalogEntryList(catal);
}
/**
* xmlCatalogAddLocal:
* @catalogs: a document's list of catalogs
* @URL: the URL to a new local catalog
*
* Add the new entry to the catalog list
*
* Returns the updated list
*/
void *
xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
xmlCatalogEntryPtr catal, add;
if (!xmlCatalogInitialized)
xmlInitializeCatalog();
if (URL == NULL)
return(catalogs);
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Adding document catalog %s\n", URL);
add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL,
xmlCatalogDefaultPrefer);
if (add == NULL)
return(catalogs);
catal = (xmlCatalogEntryPtr) catalogs;
if (catal == NULL)
return((void *) add);
while (catal->next != NULL)
catal = catal->next;
catal->next = add;
return(catalogs);
}
/**
* xmlCatalogLocalResolve:
* @catalogs: a document's list of catalogs
* @pubId: the public ID string
* @sysId: the system ID string
*
* Do a complete resolution lookup of an External Identifier using a
* document's private catalog list
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
const xmlChar *sysID) {
xmlCatalogEntryPtr catal;
if (!xmlCatalogInitialized)
xmlInitializeCatalog();
catal = (xmlCatalogEntryPtr) catalogs;
if (catal == NULL)
return(NULL);
return(xmlCatalogListXMLResolve(catal, pubID, sysID));
}
#endif /* LIBXML_CATALOG_ENABLED */
......@@ -33,8 +33,10 @@ extern "C" {
*
* The namespace for the XML Catalogs elements
*/
#define XML_CATALOGS_NAMESPACE \
#define XML_CATALOGS_NAMESPACE \
(const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
#define XML_CATALOG_PI \
(const xmlChar *) "oasis-xml-catalog"
/*
* The API is voluntarily limited to general cataloging
......@@ -45,6 +47,13 @@ typedef enum {
XML_CATA_PREFER_SYSTEM
} xmlCatalogPrefer;
typedef enum {
XML_CATA_ALLOW_NONE = 0,
XML_CATA_ALLOW_GLOBAL = 1,
XML_CATA_ALLOW_DOCUMENT = 2,
XML_CATA_ALLOW_ALL = 3
} xmlCatalogAllow;
void xmlInitializeCatalog (void);
int xmlLoadCatalog (const char *filename);
void xmlLoadCatalogs (const char *paths);
......@@ -58,8 +67,24 @@ int xmlCatalogAdd (const xmlChar *type,
const xmlChar *orig,
const xmlChar *replace);
int xmlCatalogRemove (const xmlChar *value);
/*
* Strictly minimal interfaces for per-document catalogs used
* by the parser.
*/
void xmlCatalogFreeLocal (void *catalogs);
void * xmlCatalogAddLocal (void *catalogs,
const xmlChar *URL);
xmlChar * xmlCatalogLocalResolve (void *catalogs,
const xmlChar *pubID,
const xmlChar *sysID);
/*
* Preference settings
*/
int xmlCatalogSetDebug (int level);
xmlCatalogPrefer xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
void xmlCatalogSetDefaults (xmlCatalogAllow allow);
xmlCatalogAllow xmlCatalogGetDefaults (void);
/* DEPRECATED interfaces */
const xmlChar * xmlCatalogGetSystem (const xmlChar *sysID);
......
......@@ -217,6 +217,7 @@ struct _xmlParserCtxt {
int loadsubset; /* should the external subset be loaded */
int linenumbers; /* set line number in element content */
void *catalogs; /* document's own catalog */
};
/**
......
......@@ -165,7 +165,7 @@ int xmlRegisterOutputCallbacks (xmlOutputMatchCallback matchFunc,
#ifdef LIBXML_HTTP_ENABLED
void * xmlIOHTTPOpenW (const char * post_uri,
int compression );
void xmlRegisterHTTPPostCallbacksI (void );
void xmlRegisterHTTPPostCallbacks (void );
#endif
/*
......
......@@ -132,7 +132,8 @@ typedef enum {
XML_ERR_ENTITY_LOOP, /* 89 */
XML_ERR_ENTITY_BOUNDARY, /* 90 */
XML_ERR_INVALID_URI, /* 91 */
XML_ERR_URI_FRAGMENT /* 92 */
XML_ERR_URI_FRAGMENT, /* 92 */
XML_WAR_CATALOG_PI /* 93 */
}xmlParserErrors;
/*
......
......@@ -50,6 +50,9 @@
#include <libxml/encoding.h>
#include <libxml/xmlIO.h>
#include <libxml/uri.h>
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
......@@ -2941,6 +2944,69 @@ xmlParsePITarget(xmlParserCtxtPtr ctxt) {
return(name);
}
#ifdef LIBXML_CATALOG_ENABLED
/**
* xmlParseCatalogPI:
* @ctxt: an XML parser context
* @catalog: the PI value string
*
* parse an XML Catalog Processing Instruction.
*
* <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
*
* Occurs only if allowed by the user and if happening in the Misc
* part of the document before any doctype informations
* This will add the given catalog to the parsing context in order
* to be used if there is a resolution need further down in the document
*/
static void
xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
xmlChar *URL = NULL;
const xmlChar *tmp, *base;
xmlChar marker;
tmp = catalog;
while (IS_BLANK(*tmp)) tmp++;
if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
goto error;
tmp += 7;
while (IS_BLANK(*tmp)) tmp++;
if (*tmp != '=') {
return;
}
tmp++;
while (IS_BLANK(*tmp)) tmp++;
marker = *tmp;
if ((marker != '\'') && (marker != '"'))
goto error;
tmp++;
base = tmp;
while ((*tmp != 0) && (*tmp != marker)) tmp++;
if (*tmp == 0)
goto error;
URL = xmlStrndup(base, tmp - base);
tmp++;
while (IS_BLANK(*tmp)) tmp++;
if (*tmp != 0)
goto error;
if (URL != NULL) {
ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
xmlFree(URL);
}
return;
error:
ctxt->errNo = XML_WAR_CATALOG_PI;
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Catalog PI syntax error: %s\n", catalog);
if (URL != NULL)
xmlFree(URL);
}
#endif
/**
* xmlParsePI:
* @ctxt: an XML parser context
......@@ -3063,6 +3129,18 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
}
SKIP(2);
#ifdef LIBXML_CATALOG_ENABLED
if (((state == XML_PARSER_MISC) ||
(state == XML_PARSER_START)) &&
(xmlStrEqual(target, XML_CATALOG_PI))) {
xmlCatalogAllow allow = xmlCatalogGetDefaults();
if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
(allow == XML_CATA_ALLOW_ALL))
xmlParseCatalogPI(ctxt, buf);
}
#endif
/*
* SAX: PI detected.
*/
......@@ -5324,7 +5402,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
ctxt->disableSAX = 1;
} else {
ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Entity '%s' not defined\n", name);
}
......
......@@ -46,6 +46,9 @@
#include <libxml/valid.h>
#include <libxml/xmlIO.h>
#include <libxml/uri.h>
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
#endif
void xmlUpgradeOldNs(xmlDocPtr doc);
......@@ -2270,6 +2273,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
ctxt->errNo = XML_ERR_OK;
ctxt->depth = 0;
ctxt->charset = XML_CHAR_ENCODING_UTF8;
ctxt->catalogs = NULL;
xmlInitNodeInfoSeq(&ctxt->node_seq);
}
......@@ -2308,6 +2312,10 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
xmlFree(ctxt->sax);
if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
#ifdef LIBXML_CATALOG_ENABLED
if (ctxt->catalogs != NULL)
xmlCatalogFreeLocal(ctxt->catalogs);
#endif
xmlFree(ctxt);
}
......
......@@ -2374,6 +2374,7 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
xmlChar *resource = NULL;
#ifdef LIBXML_CATALOG_ENABLED
struct stat info;
xmlCatalogAllow pref;
#endif
#ifdef DEBUG_EXTERNAL_ENTITIES
......@@ -2385,11 +2386,40 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
* If the resource doesn't exists as a file,
* try to load it from the resource pointed in the catalog
*/
pref = xmlCatalogGetDefaults();
if ((pref != XML_CATA_ALLOW_NONE)
#ifdef HAVE_STAT
&& ((URL == NULL) || (stat(URL, &info) < 0))
#endif
) {
/*
* Do a local lookup
*/
if ((ctxt->catalogs != NULL) &&
((pref == XML_CATA_ALLOW_ALL) ||
(pref == XML_CATA_ALLOW_DOCUMENT))) {
resource = xmlCatalogLocalResolve(ctxt->catalogs,
(const xmlChar *)ID,
(const xmlChar *)URL);
}
/*
* Do a global lookup
*/
if (((resource == NULL)
#ifdef HAVE_STAT
if ((URL == NULL) || (stat(URL, &info) < 0))
|| (stat((const char *) resource, &info) < 0)
#endif
resource = xmlCatalogResolve((const xmlChar *)ID,
(const xmlChar *)URL);
) && ((pref == XML_CATA_ALLOW_ALL) ||
(pref == XML_CATA_ALLOW_GLOBAL))) {
resource = xmlCatalogResolve((const xmlChar *)ID,
(const xmlChar *)URL);
}
/*
* TODO: do an URI lookup on the reference
*/
}
#endif
if (resource == NULL)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment