mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-03 08:58:17 +03:00
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
This commit is contained in:
parent
e2940ddb35
commit
5d90b6c983
@ -1,3 +1,10 @@
|
||||
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
|
||||
|
160
catalog.c
160
catalog.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 */
|
||||
|
@ -35,6 +35,8 @@ extern "C" {
|
||||
*/
|
||||
#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;
|
||||
|
||||
/*
|
||||
|
80
parser.c
80
parser.c
@ -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);
|
||||
}
|
||||
|
||||
|
32
xmlIO.c
32
xmlIO.c
@ -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
|
||||
if ((URL == NULL) || (stat(URL, &info) < 0))
|
||||
&& ((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
|
||||
|| (stat((const char *) resource, &info) < 0)
|
||||
#endif
|
||||
) && ((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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user