| Index: third_party/libxml/src/xmlreader.c
|
| diff --git a/third_party/libxml/src/xmlreader.c b/third_party/libxml/src/xmlreader.c
|
| index e39faec8008c5e2c50b3a0da566c8dbeefc164f6..f19e1233828a65109ec266a0da1f3f04ebba83fe 100644
|
| --- a/third_party/libxml/src/xmlreader.c
|
| +++ b/third_party/libxml/src/xmlreader.c
|
| @@ -44,14 +44,15 @@
|
| #include <libxml/pattern.h>
|
| #endif
|
|
|
| +#include "buf.h"
|
| +
|
| #define MAX_ERR_MSG_SIZE 64000
|
|
|
| /*
|
| * The following VA_COPY was coded following an example in
|
| * the Samba project. It may not be sufficient for some
|
| - * esoteric implementations of va_list (i.e. it may need
|
| - * something involving a memcpy) but (hopefully) will be
|
| - * sufficient for libxml2.
|
| + * esoteric implementations of va_list but (hopefully) will
|
| + * be sufficient for libxml2.
|
| */
|
| #ifndef VA_COPY
|
| #ifdef HAVE_VA_COPY
|
| @@ -60,7 +61,12 @@
|
| #ifdef HAVE___VA_COPY
|
| #define VA_COPY(dest,src) __va_copy(dest, src)
|
| #else
|
| - #define VA_COPY(dest,src) (dest) = (src)
|
| + #ifndef VA_LIST_IS_ARRAY
|
| + #define VA_COPY(dest,src) (dest) = (src)
|
| + #else
|
| + #include <string.h>
|
| + #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
|
| + #endif
|
| #endif
|
| #endif
|
| #endif
|
| @@ -135,7 +141,7 @@ struct _xmlTextReader {
|
| int depth; /* depth of the current node */
|
| xmlNodePtr faketext;/* fake xmlNs chld */
|
| int preserve;/* preserve the resulting document */
|
| - xmlBufferPtr buffer; /* used to return const xmlChar * */
|
| + xmlBufPtr buffer; /* used to return const xmlChar * */
|
| xmlDictPtr dict; /* the context dictionnary */
|
|
|
| /* entity stack when traversing entities content */
|
| @@ -152,6 +158,7 @@ struct _xmlTextReader {
|
| /* Handling of RelaxNG validation */
|
| xmlRelaxNGPtr rngSchemas; /* The Relax NG schemas */
|
| xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
|
| + int rngPreserveCtxt; /* 1 if the context was provided by the user */
|
| int rngValidErrors;/* The number of errors detected */
|
| xmlNodePtr rngFullNode; /* the node if RNG not progressive */
|
| /* Handling of Schemas validation */
|
| @@ -279,7 +286,10 @@ static void
|
| xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
| xmlDictPtr dict;
|
|
|
| - dict = reader->ctxt->dict;
|
| + if ((reader != NULL) && (reader->ctxt != NULL))
|
| + dict = reader->ctxt->dict;
|
| + else
|
| + dict = NULL;
|
| if (cur == NULL) return;
|
|
|
| if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
|
| @@ -316,7 +326,7 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
| static void
|
| xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
| xmlAttrPtr next;
|
| - if (cur == NULL) return;
|
| +
|
| while (cur != NULL) {
|
| next = cur->next;
|
| xmlTextReaderFreeProp(reader, cur);
|
| @@ -337,7 +347,10 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
| xmlNodePtr next;
|
| xmlDictPtr dict;
|
|
|
| - dict = reader->ctxt->dict;
|
| + if ((reader != NULL) && (reader->ctxt != NULL))
|
| + dict = reader->ctxt->dict;
|
| + else
|
| + dict = NULL;
|
| if (cur == NULL) return;
|
| if (cur->type == XML_NAMESPACE_DECL) {
|
| xmlFreeNsList((xmlNsPtr) cur);
|
| @@ -414,7 +427,10 @@ static void
|
| xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
| xmlDictPtr dict;
|
|
|
| - dict = reader->ctxt->dict;
|
| + if ((reader != NULL) && (reader->ctxt != NULL))
|
| + dict = reader->ctxt->dict;
|
| + else
|
| + dict = NULL;
|
| if (cur->type == XML_DTD_NODE) {
|
| xmlFreeDtd((xmlDtdPtr) cur);
|
| return;
|
| @@ -806,9 +822,10 @@ xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
|
| */
|
| static int
|
| xmlTextReaderPushData(xmlTextReaderPtr reader) {
|
| - xmlBufferPtr inbuf;
|
| + xmlBufPtr inbuf;
|
| int val, s;
|
| xmlTextReaderState oldstate;
|
| + int alloc;
|
|
|
| if ((reader->input == NULL) || (reader->input->buffer == NULL))
|
| return(-1);
|
| @@ -816,17 +833,18 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
|
| oldstate = reader->state;
|
| reader->state = XML_TEXTREADER_NONE;
|
| inbuf = reader->input->buffer;
|
| + alloc = xmlBufGetAllocationScheme(inbuf);
|
|
|
| while (reader->state == XML_TEXTREADER_NONE) {
|
| - if (inbuf->use < reader->cur + CHUNK_SIZE) {
|
| + if (xmlBufUse(inbuf) < reader->cur + CHUNK_SIZE) {
|
| /*
|
| * Refill the buffer unless we are at the end of the stream
|
| */
|
| if (reader->mode != XML_TEXTREADER_MODE_EOF) {
|
| val = xmlParserInputBufferRead(reader->input, 4096);
|
| if ((val == 0) &&
|
| - (inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
|
| - if (inbuf->use == reader->cur) {
|
| + (alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
|
| + if (xmlBufUse(inbuf) == reader->cur) {
|
| reader->mode = XML_TEXTREADER_MODE_EOF;
|
| reader->state = oldstate;
|
| }
|
| @@ -849,21 +867,23 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
|
| * parse by block of CHUNK_SIZE bytes, various tests show that
|
| * it's the best tradeoff at least on a 1.2GH Duron
|
| */
|
| - if (inbuf->use >= reader->cur + CHUNK_SIZE) {
|
| + if (xmlBufUse(inbuf) >= reader->cur + CHUNK_SIZE) {
|
| val = xmlParseChunk(reader->ctxt,
|
| - (const char *) &inbuf->content[reader->cur],
|
| - CHUNK_SIZE, 0);
|
| + (const char *) xmlBufContent(inbuf) + reader->cur,
|
| + CHUNK_SIZE, 0);
|
| reader->cur += CHUNK_SIZE;
|
| - if ((val != 0) || (reader->ctxt->wellFormed == 0))
|
| - return(-1);
|
| + if (val != 0)
|
| + reader->ctxt->wellFormed = 0;
|
| + if (reader->ctxt->wellFormed == 0)
|
| + break;
|
| } else {
|
| - s = inbuf->use - reader->cur;
|
| + s = xmlBufUse(inbuf) - reader->cur;
|
| val = xmlParseChunk(reader->ctxt,
|
| - (const char *) &inbuf->content[reader->cur],
|
| - s, 0);
|
| + (const char *) xmlBufContent(inbuf) + reader->cur,
|
| + s, 0);
|
| reader->cur += s;
|
| - if ((val != 0) || (reader->ctxt->wellFormed == 0))
|
| - return(-1);
|
| + if (val != 0)
|
| + reader->ctxt->wellFormed = 0;
|
| break;
|
| }
|
| }
|
| @@ -872,10 +892,10 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
|
| * Discard the consumed input when needed and possible
|
| */
|
| if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
|
| - if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
|
| + if (alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
|
| if ((reader->cur >= 4096) &&
|
| - (inbuf->use - reader->cur <= CHUNK_SIZE)) {
|
| - val = xmlBufferShrink(inbuf, reader->cur);
|
| + (xmlBufUse(inbuf) - reader->cur <= CHUNK_SIZE)) {
|
| + val = xmlBufShrink(inbuf, reader->cur);
|
| if (val >= 0) {
|
| reader->cur -= val;
|
| }
|
| @@ -889,17 +909,26 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
|
| */
|
| else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
|
| if (reader->state != XML_TEXTREADER_DONE) {
|
| - s = inbuf->use - reader->cur;
|
| + s = xmlBufUse(inbuf) - reader->cur;
|
| val = xmlParseChunk(reader->ctxt,
|
| - (const char *) &inbuf->content[reader->cur],
|
| - s, 1);
|
| - reader->cur = inbuf->use;
|
| + (const char *) xmlBufContent(inbuf) + reader->cur,
|
| + s, 1);
|
| + reader->cur = xmlBufUse(inbuf);
|
| reader->state = XML_TEXTREADER_DONE;
|
| - if ((val != 0) || (reader->ctxt->wellFormed == 0))
|
| - return(-1);
|
| + if (val != 0) {
|
| + if (reader->ctxt->wellFormed)
|
| + reader->ctxt->wellFormed = 0;
|
| + else
|
| + return(-1);
|
| + }
|
| }
|
| }
|
| reader->state = oldstate;
|
| + if (reader->ctxt->wellFormed == 0) {
|
| + reader->mode = XML_TEXTREADER_MODE_EOF;
|
| + return(-1);
|
| + }
|
| +
|
| return(0);
|
| }
|
|
|
| @@ -968,7 +997,7 @@ printf("Expand failed !\n");
|
| * xmlTextReaderValidateCData:
|
| * @reader: the xmlTextReaderPtr used
|
| * @data: pointer to the CData
|
| - * @len: lenght of the CData block in bytes.
|
| + * @len: length of the CData block in bytes.
|
| *
|
| * Push some CData for validation
|
| */
|
| @@ -1212,6 +1241,9 @@ xmlTextReaderCollectSiblings(xmlNodePtr node)
|
| xmlBufferPtr buffer;
|
| xmlChar *ret;
|
|
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| + return(NULL);
|
| +
|
| buffer = xmlBufferCreate();
|
| if (buffer == NULL)
|
| return NULL;
|
| @@ -1264,8 +1296,6 @@ xmlTextReaderRead(xmlTextReaderPtr reader) {
|
| return(xmlTextReaderReadTree(reader));
|
| if (reader->ctxt == NULL)
|
| return(-1);
|
| - if (reader->ctxt->wellFormed != 1)
|
| - return(-1);
|
|
|
| #ifdef DEBUG_READER
|
| fprintf(stderr, "\nREAD ");
|
| @@ -1392,7 +1422,7 @@ get_next_node:
|
| #endif
|
| (reader->entNr == 0) &&
|
| (reader->node->prev != NULL) &&
|
| - (reader->node->prev->type != XML_DTD_NODE)) {
|
| + (reader->node->prev->type != XML_DTD_NODE)) {
|
| xmlNodePtr tmp = reader->node->prev;
|
| if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
|
| xmlUnlinkNode(tmp);
|
| @@ -1410,7 +1440,7 @@ get_next_node:
|
| goto node_found;
|
| }
|
| #ifdef LIBXML_REGEXP_ENABLED
|
| - if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
|
| + if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node->type == XML_ELEMENT_NODE))
|
| xmlTextReaderValidatePop(reader);
|
| #endif /* LIBXML_REGEXP_ENABLED */
|
| if ((reader->preserves > 0) &&
|
| @@ -1543,7 +1573,7 @@ node_found:
|
| goto get_next_node;
|
| }
|
| #ifdef LIBXML_REGEXP_ENABLED
|
| - if ((reader->validate) && (reader->node != NULL)) {
|
| + if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node != NULL)) {
|
| xmlNodePtr node = reader->node;
|
|
|
| if ((node->type == XML_ELEMENT_NODE) &&
|
| @@ -1707,9 +1737,9 @@ xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
|
| *
|
| * Reads the contents of the current node, including child nodes and markup.
|
| *
|
| - * Returns a string containing the XML content, or NULL if the current node
|
| - * is neither an element nor attribute, or has no child nodes. The
|
| - * string must be deallocated by the caller.
|
| + * Returns a string containing the node and any XML content, or NULL if the
|
| + * current node cannot be serialized. The string must be deallocated
|
| + * by the caller.
|
| */
|
| xmlChar *
|
| xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
|
| @@ -1724,7 +1754,11 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
|
| if (xmlTextReaderExpand(reader) == NULL) {
|
| return NULL;
|
| }
|
| - node = xmlDocCopyNode(node, doc, 1);
|
| + if (node->type == XML_DTD_NODE) {
|
| + node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
|
| + } else {
|
| + node = xmlDocCopyNode(node, doc, 1);
|
| + }
|
| buff = xmlBufferCreate();
|
| if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
|
| xmlFreeNode(node);
|
| @@ -1769,6 +1803,7 @@ xmlTextReaderReadString(xmlTextReaderPtr reader)
|
| if (xmlTextReaderDoExpand(reader) != -1) {
|
| return xmlTextReaderCollectSiblings(node->children);
|
| }
|
| + break;
|
| case XML_ATTRIBUTE_NODE:
|
| TODO
|
| break;
|
| @@ -2049,7 +2084,7 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
|
| ret->entMax = 0;
|
| ret->entNr = 0;
|
| ret->input = input;
|
| - ret->buffer = xmlBufferCreateSize(100);
|
| + ret->buffer = xmlBufCreateSize(100);
|
| if (ret->buffer == NULL) {
|
| xmlFree(ret);
|
| xmlGenericError(xmlGenericErrorContext,
|
| @@ -2058,7 +2093,7 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
|
| }
|
| ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
|
| if (ret->sax == NULL) {
|
| - xmlBufferFree(ret->buffer);
|
| + xmlBufFree(ret->buffer);
|
| xmlFree(ret);
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlNewTextReader : malloc failed\n");
|
| @@ -2091,12 +2126,13 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
|
| ret->mode = XML_TEXTREADER_MODE_INITIAL;
|
| ret->node = NULL;
|
| ret->curnode = NULL;
|
| - if (ret->input->buffer->use < 4) {
|
| + if (xmlBufUse(ret->input->buffer) < 4) {
|
| xmlParserInputBufferRead(input, 4);
|
| }
|
| - if (ret->input->buffer->use >= 4) {
|
| + if (xmlBufUse(ret->input->buffer) >= 4) {
|
| ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
|
| - (const char *) ret->input->buffer->content, 4, URI);
|
| + (const char *) xmlBufContent(ret->input->buffer),
|
| + 4, URI);
|
| ret->base = 0;
|
| ret->cur = 4;
|
| } else {
|
| @@ -2108,7 +2144,7 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
|
| if (ret->ctxt == NULL) {
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlNewTextReader : malloc failed\n");
|
| - xmlBufferFree(ret->buffer);
|
| + xmlBufFree(ret->buffer);
|
| xmlFree(ret->sax);
|
| xmlFree(ret);
|
| return(NULL);
|
| @@ -2181,7 +2217,8 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
|
| reader->rngSchemas = NULL;
|
| }
|
| if (reader->rngValidCtxt != NULL) {
|
| - xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| + if (! reader->rngPreserveCtxt)
|
| + xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| reader->rngValidCtxt = NULL;
|
| }
|
| if (reader->xsdPlug != NULL) {
|
| @@ -2237,7 +2274,7 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
|
| if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT))
|
| xmlFreeParserInputBuffer(reader->input);
|
| if (reader->buffer != NULL)
|
| - xmlBufferFree(reader->buffer);
|
| + xmlBufFree(reader->buffer);
|
| if (reader->entTab != NULL)
|
| xmlFree(reader->entTab);
|
| if (reader->dict != NULL)
|
| @@ -3585,16 +3622,17 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
|
| (attr->children->next == NULL))
|
| return(attr->children->content);
|
| else {
|
| - if (reader->buffer == NULL)
|
| - reader->buffer = xmlBufferCreateSize(100);
|
| if (reader->buffer == NULL) {
|
| - xmlGenericError(xmlGenericErrorContext,
|
| - "xmlTextReaderSetup : malloc failed\n");
|
| - return (NULL);
|
| - }
|
| - reader->buffer->use = 0;
|
| - xmlNodeBufGetContent(reader->buffer, node);
|
| - return(reader->buffer->content);
|
| + reader->buffer = xmlBufCreateSize(100);
|
| + if (reader->buffer == NULL) {
|
| + xmlGenericError(xmlGenericErrorContext,
|
| + "xmlTextReaderSetup : malloc failed\n");
|
| + return (NULL);
|
| + }
|
| + } else
|
| + xmlBufEmpty(reader->buffer);
|
| + xmlBufGetNodeContent(reader->buffer, node);
|
| + return(xmlBufContent(reader->buffer));
|
| }
|
| break;
|
| }
|
| @@ -4089,9 +4127,11 @@ xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
|
| reader->rngSchemas = NULL;
|
| }
|
| if (reader->rngValidCtxt != NULL) {
|
| - xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| + if (! reader->rngPreserveCtxt)
|
| + xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| reader->rngValidCtxt = NULL;
|
| }
|
| + reader->rngPreserveCtxt = 0;
|
| return(0);
|
| }
|
| if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
|
| @@ -4101,9 +4141,11 @@ xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
|
| reader->rngSchemas = NULL;
|
| }
|
| if (reader->rngValidCtxt != NULL) {
|
| - xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| + if (! reader->rngPreserveCtxt)
|
| + xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| reader->rngValidCtxt = NULL;
|
| }
|
| + reader->rngPreserveCtxt = 0;
|
| reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
|
| if (reader->rngValidCtxt == NULL)
|
| return(-1);
|
| @@ -4125,6 +4167,60 @@ xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
|
| }
|
|
|
| /**
|
| + * xmlTextReaderLocator:
|
| + * @ctx: the xmlTextReaderPtr used
|
| + * @file: returned file information
|
| + * @line: returned line information
|
| + *
|
| + * Internal locator function for the readers
|
| + *
|
| + * Returns 0 in case the Schema validation could be (des)activated and
|
| + * -1 in case of error.
|
| + */
|
| +static int
|
| +xmlTextReaderLocator(void *ctx, const char **file, unsigned long *line) {
|
| + xmlTextReaderPtr reader;
|
| +
|
| + if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
|
| + return(-1);
|
| +
|
| + if (file != NULL)
|
| + *file = NULL;
|
| + if (line != NULL)
|
| + *line = 0;
|
| +
|
| + reader = (xmlTextReaderPtr) ctx;
|
| + if ((reader->ctxt != NULL) && (reader->ctxt->input != NULL)) {
|
| + if (file != NULL)
|
| + *file = reader->ctxt->input->filename;
|
| + if (line != NULL)
|
| + *line = reader->ctxt->input->line;
|
| + return(0);
|
| + }
|
| + if (reader->node != NULL) {
|
| + long res;
|
| + int ret = 0;
|
| +
|
| + if (line != NULL) {
|
| + res = xmlGetLineNo(reader->node);
|
| + if (res > 0)
|
| + *line = (unsigned long) res;
|
| + else
|
| + ret = -1;
|
| + }
|
| + if (file != NULL) {
|
| + xmlDocPtr doc = reader->node->doc;
|
| + if ((doc != NULL) && (doc->URL != NULL))
|
| + *file = (const char *) doc->URL;
|
| + else
|
| + ret = -1;
|
| + }
|
| + return(ret);
|
| + }
|
| + return(-1);
|
| +}
|
| +
|
| +/**
|
| * xmlTextReaderSetSchema:
|
| * @reader: the xmlTextReaderPtr used
|
| * @schema: a precompiled Schema schema
|
| @@ -4191,6 +4287,10 @@ xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
|
| reader->xsdValidCtxt = NULL;
|
| return(-1);
|
| }
|
| + xmlSchemaValidateSetLocator(reader->xsdValidCtxt,
|
| + xmlTextReaderLocator,
|
| + (void *) reader);
|
| +
|
| if (reader->errorFunc != NULL) {
|
| xmlSchemaSetValidErrors(reader->xsdValidCtxt,
|
| xmlTextReaderValidityErrorRelay,
|
| @@ -4208,67 +4308,91 @@ xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
|
| }
|
|
|
| /**
|
| - * xmlTextReaderRelaxNGValidate:
|
| + * xmlTextReaderRelaxNGValidateInternal:
|
| * @reader: the xmlTextReaderPtr used
|
| * @rng: the path to a RelaxNG schema or NULL
|
| + * @ctxt: the RelaxNG schema validation context or NULL
|
| + * @options: options (not yet used)
|
| *
|
| * Use RelaxNG to validate the document as it is processed.
|
| * Activation is only possible before the first Read().
|
| - * if @rng is NULL, then RelaxNG validation is deactivated.
|
| + * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
|
| *
|
| * Returns 0 in case the RelaxNG validation could be (de)activated and
|
| - * -1 in case of error.
|
| + * -1 in case of error.
|
| */
|
| -int
|
| -xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng) {
|
| - xmlRelaxNGParserCtxtPtr ctxt;
|
| -
|
| +static int
|
| +xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader,
|
| + const char *rng,
|
| + xmlRelaxNGValidCtxtPtr ctxt,
|
| + int options ATTRIBUTE_UNUSED)
|
| +{
|
| if (reader == NULL)
|
| - return(-1);
|
| + return(-1);
|
|
|
| - if (rng == NULL) {
|
| - if (reader->rngValidCtxt != NULL) {
|
| + if ((rng != NULL) && (ctxt != NULL))
|
| + return (-1);
|
| +
|
| + if (((rng != NULL) || (ctxt != NULL)) &&
|
| + ((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
|
| + (reader->ctxt == NULL)))
|
| + return(-1);
|
| +
|
| + /* Cleanup previous validation stuff. */
|
| + if (reader->rngValidCtxt != NULL) {
|
| + if ( !reader->rngPreserveCtxt)
|
| xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| - reader->rngValidCtxt = NULL;
|
| - }
|
| - if (reader->rngSchemas != NULL) {
|
| - xmlRelaxNGFree(reader->rngSchemas);
|
| - reader->rngSchemas = NULL;
|
| - }
|
| - return(0);
|
| + reader->rngValidCtxt = NULL;
|
| }
|
| - if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
|
| - return(-1);
|
| + reader->rngPreserveCtxt = 0;
|
| if (reader->rngSchemas != NULL) {
|
| xmlRelaxNGFree(reader->rngSchemas);
|
| reader->rngSchemas = NULL;
|
| }
|
| - if (reader->rngValidCtxt != NULL) {
|
| - xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
|
| - reader->rngValidCtxt = NULL;
|
| - }
|
| - ctxt = xmlRelaxNGNewParserCtxt(rng);
|
| - if (reader->errorFunc != NULL) {
|
| - xmlRelaxNGSetParserErrors(ctxt,
|
| - xmlTextReaderValidityErrorRelay,
|
| - xmlTextReaderValidityWarningRelay,
|
| - reader);
|
| - }
|
| - if (reader->sErrorFunc != NULL) {
|
| - xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
|
| - xmlTextReaderValidityStructuredRelay,
|
| - reader);
|
| +
|
| + if ((rng == NULL) && (ctxt == NULL)) {
|
| + /* We just want to deactivate the validation, so get out. */
|
| + return(0);
|
| }
|
| - reader->rngSchemas = xmlRelaxNGParse(ctxt);
|
| - xmlRelaxNGFreeParserCtxt(ctxt);
|
| - if (reader->rngSchemas == NULL)
|
| - return(-1);
|
| - reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
|
| - if (reader->rngValidCtxt == NULL) {
|
| - xmlRelaxNGFree(reader->rngSchemas);
|
| - reader->rngSchemas = NULL;
|
| - return(-1);
|
| +
|
| +
|
| + if (rng != NULL) {
|
| + xmlRelaxNGParserCtxtPtr pctxt;
|
| + /* Parse the schema and create validation environment. */
|
| +
|
| + pctxt = xmlRelaxNGNewParserCtxt(rng);
|
| + if (reader->errorFunc != NULL) {
|
| + xmlRelaxNGSetParserErrors(pctxt,
|
| + xmlTextReaderValidityErrorRelay,
|
| + xmlTextReaderValidityWarningRelay,
|
| + reader);
|
| + }
|
| + if (reader->sErrorFunc != NULL) {
|
| + xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
|
| + xmlTextReaderValidityStructuredRelay,
|
| + reader);
|
| + }
|
| + reader->rngSchemas = xmlRelaxNGParse(pctxt);
|
| + xmlRelaxNGFreeParserCtxt(pctxt);
|
| + if (reader->rngSchemas == NULL)
|
| + return(-1);
|
| + reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
|
| + if (reader->rngValidCtxt == NULL) {
|
| + xmlRelaxNGFree(reader->rngSchemas);
|
| + reader->rngSchemas = NULL;
|
| + return(-1);
|
| + }
|
| + } else {
|
| + /* Use the given validation context. */
|
| + reader->rngValidCtxt = ctxt;
|
| + reader->rngPreserveCtxt = 1;
|
| }
|
| + /*
|
| + * Redirect the validation context's error channels to use
|
| + * the reader channels.
|
| + * TODO: In case the user provides the validation context we
|
| + * could make this redirection optional.
|
| + */
|
| if (reader->errorFunc != NULL) {
|
| xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
|
| xmlTextReaderValidityErrorRelay,
|
| @@ -4381,6 +4505,9 @@ xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
|
| return(-1);
|
| }
|
| }
|
| + xmlSchemaValidateSetLocator(reader->xsdValidCtxt,
|
| + xmlTextReaderLocator,
|
| + (void *) reader);
|
| /*
|
| * Redirect the validation context's error channels to use
|
| * the reader channels.
|
| @@ -4441,6 +4568,46 @@ xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
|
| {
|
| return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
|
| }
|
| +
|
| +/**
|
| + * xmlTextReaderRelaxNGValidateCtxt:
|
| + * @reader: the xmlTextReaderPtr used
|
| + * @ctxt: the RelaxNG schema validation context or NULL
|
| + * @options: options (not used yet)
|
| + *
|
| + * Use RelaxNG schema context to validate the document as it is processed.
|
| + * Activation is only possible before the first Read().
|
| + * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
|
| + *
|
| + * Returns 0 in case the schemas validation could be (de)activated and
|
| + * -1 in case of error.
|
| + */
|
| +int
|
| +xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader,
|
| + xmlRelaxNGValidCtxtPtr ctxt,
|
| + int options)
|
| +{
|
| + return(xmlTextReaderRelaxNGValidateInternal(reader, NULL, ctxt, options));
|
| +}
|
| +
|
| +/**
|
| + * xmlTextReaderRelaxNGValidate:
|
| + * @reader: the xmlTextReaderPtr used
|
| + * @rng: the path to a RelaxNG schema or NULL
|
| + *
|
| + * Use RelaxNG schema to validate the document as it is processed.
|
| + * Activation is only possible before the first Read().
|
| + * If @rng is NULL, then RelaxNG schema validation is deactivated.
|
| + *
|
| + * Returns 0 in case the schemas validation could be (de)activated and
|
| + * -1 in case of error.
|
| + */
|
| +int
|
| +xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng)
|
| +{
|
| + return(xmlTextReaderRelaxNGValidateInternal(reader, rng, NULL, 0));
|
| +}
|
| +
|
| #endif
|
|
|
| /**
|
| @@ -4958,7 +5125,7 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
|
| reader->allocs |= XML_TEXTREADER_INPUT;
|
| }
|
| if (reader->buffer == NULL)
|
| - reader->buffer = xmlBufferCreateSize(100);
|
| + reader->buffer = xmlBufCreateSize(100);
|
| if (reader->buffer == NULL) {
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlTextReaderSetup : malloc failed\n");
|
| @@ -4999,13 +5166,14 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
|
| reader->node = NULL;
|
| reader->curnode = NULL;
|
| if (input != NULL) {
|
| - if (reader->input->buffer->use < 4) {
|
| + if (xmlBufUse(reader->input->buffer) < 4) {
|
| xmlParserInputBufferRead(input, 4);
|
| }
|
| if (reader->ctxt == NULL) {
|
| - if (reader->input->buffer->use >= 4) {
|
| + if (xmlBufUse(reader->input->buffer) >= 4) {
|
| reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
|
| - (const char *) reader->input->buffer->content, 4, URL);
|
| + (const char *) xmlBufContent(reader->input->buffer),
|
| + 4, URL);
|
| reader->base = 0;
|
| reader->cur = 4;
|
| } else {
|
| @@ -5034,10 +5202,7 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
|
| inputStream->filename = (char *)
|
| xmlCanonicPath((const xmlChar *) URL);
|
| inputStream->buf = buf;
|
| - inputStream->base = inputStream->buf->buffer->content;
|
| - inputStream->cur = inputStream->buf->buffer->content;
|
| - inputStream->end =
|
| - &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
|
| + xmlBufResetInput(buf->buffer, inputStream);
|
|
|
| inputPush(reader->ctxt, inputStream);
|
| reader->cur = 0;
|
| @@ -5325,8 +5490,11 @@ xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
|
|
|
| input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
|
| XML_CHAR_ENCODING_NONE);
|
| - if (input == NULL)
|
| + if (input == NULL) {
|
| + if (ioclose != NULL)
|
| + ioclose(ioctx);
|
| return (NULL);
|
| + }
|
| reader = xmlNewTextReader(input, URL);
|
| if (reader == NULL) {
|
| xmlFreeParserInputBuffer(input);
|
| @@ -5543,10 +5711,14 @@ xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
|
|
|
| input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
|
| XML_CHAR_ENCODING_NONE);
|
| - if (input == NULL)
|
| + if (input == NULL) {
|
| + if (ioclose != NULL)
|
| + ioclose(ioctx);
|
| return (-1);
|
| + }
|
| return (xmlTextReaderSetup(reader, input, URL, encoding, options));
|
| }
|
| +
|
| /************************************************************************
|
| * *
|
| * Utilities *
|
|
|