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 * |