summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c172
1 files changed, 125 insertions, 47 deletions
diff --git a/parser.c b/parser.c
index b5ecd2e..baa9c47 100644
--- a/parser.c
+++ b/parser.c
@@ -949,6 +949,8 @@ mem_error:
int
inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
{
+ if ((ctxt == NULL) || (value == NULL))
+ return(0);
if (ctxt->inputNr >= ctxt->inputMax) {
ctxt->inputMax *= 2;
ctxt->inputTab =
@@ -977,6 +979,8 @@ inputPop(xmlParserCtxtPtr ctxt)
{
xmlParserInputPtr ret;
+ if (ctxt == NULL)
+ return(NULL);
if (ctxt->inputNr <= 0)
return (0);
ctxt->inputNr--;
@@ -1000,16 +1004,19 @@ inputPop(xmlParserCtxtPtr ctxt)
int
nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
{
+ if (ctxt == NULL) return(0);
if (ctxt->nodeNr >= ctxt->nodeMax) {
- ctxt->nodeMax *= 2;
- ctxt->nodeTab =
- (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
- ctxt->nodeMax *
+ xmlNodePtr *tmp;
+
+ tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
+ ctxt->nodeMax * 2 *
sizeof(ctxt->nodeTab[0]));
- if (ctxt->nodeTab == NULL) {
+ if (tmp == NULL) {
xmlErrMemory(ctxt, NULL);
return (0);
}
+ ctxt->nodeTab = tmp;
+ ctxt->nodeMax *= 2;
}
if (((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) {
xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
@@ -1035,8 +1042,9 @@ nodePop(xmlParserCtxtPtr ctxt)
{
xmlNodePtr ret;
+ if (ctxt == NULL) return(NULL);
if (ctxt->nodeNr <= 0)
- return (0);
+ return (NULL);
ctxt->nodeNr--;
if (ctxt->nodeNr > 0)
ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
@@ -1132,6 +1140,8 @@ nameNsPop(xmlParserCtxtPtr ctxt)
int
namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
{
+ if (ctxt == NULL) return (-1);
+
if (ctxt->nameNr >= ctxt->nameMax) {
const xmlChar * *tmp;
ctxt->nameMax *= 2;
@@ -1164,8 +1174,8 @@ namePop(xmlParserCtxtPtr ctxt)
{
const xmlChar *ret;
- if (ctxt->nameNr <= 0)
- return (0);
+ if ((ctxt == NULL) || (ctxt->nameNr <= 0))
+ return (NULL);
ctxt->nameNr--;
if (ctxt->nameNr > 0)
ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
@@ -1412,7 +1422,7 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
*/
xmlChar
xmlPopInput(xmlParserCtxtPtr ctxt) {
- if (ctxt->inputNr == 1) return(0); /* End of main Input */
+ if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
if (xmlParserDebugEntities)
xmlGenericError(xmlGenericErrorContext,
"Popping input %d\n", ctxt->inputNr);
@@ -1926,7 +1936,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
int c,l;
int nbchars = 0;
- if ((str == NULL) || (len < 0))
+ if ((ctxt == NULL) || (str == NULL) || (len < 0))
return(NULL);
last = str + len;
@@ -2068,6 +2078,7 @@ mem_error:
xmlChar *
xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
xmlChar end, xmlChar end2, xmlChar end3) {
+ if ((ctxt == NULL) || (str == NULL)) return(NULL);
return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
end, end2, end3));
}
@@ -2180,6 +2191,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
const xmlChar *cur = name;
int c;
+ if (prefix == NULL) return(NULL);
*prefix = NULL;
if (cur == NULL) return(NULL);
@@ -2992,6 +3004,7 @@ mem_error:
xmlChar *
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
+ if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
}
@@ -3199,15 +3212,17 @@ get_more_space:
const xmlChar *tmp = ctxt->input->cur;
ctxt->input->cur = in;
- if (ctxt->sax->ignorableWhitespace !=
- ctxt->sax->characters) {
+ if ((ctxt->sax != NULL) &&
+ (ctxt->sax->ignorableWhitespace !=
+ ctxt->sax->characters)) {
if (areBlanks(ctxt, tmp, nbchar, 1)) {
ctxt->sax->ignorableWhitespace(ctxt->userData,
tmp, nbchar);
} else if (ctxt->sax->characters != NULL)
ctxt->sax->characters(ctxt->userData,
tmp, nbchar);
- } else if (ctxt->sax->characters != NULL) {
+ } else if ((ctxt->sax != NULL) &&
+ (ctxt->sax->characters != NULL)) {
ctxt->sax->characters(ctxt->userData,
tmp, nbchar);
}
@@ -3241,7 +3256,8 @@ get_more:
}
nbchar = in - ctxt->input->cur;
if (nbchar > 0) {
- if ((ctxt->sax->ignorableWhitespace !=
+ if ((ctxt->sax != NULL) &&
+ (ctxt->sax->ignorableWhitespace !=
ctxt->sax->characters) &&
(IS_BLANK_CH(*ctxt->input->cur))) {
const xmlChar *tmp = ctxt->input->cur;
@@ -3255,7 +3271,7 @@ get_more:
tmp, nbchar);
line = ctxt->input->line;
col = ctxt->input->col;
- } else {
+ } else if (ctxt->sax != NULL) {
if (ctxt->sax->characters != NULL)
ctxt->sax->characters(ctxt->userData,
ctxt->input->cur, nbchar);
@@ -8541,6 +8557,9 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
xmlInitParser();
+ if ((ctxt == NULL) || (ctxt->input == NULL))
+ return(-1);
+
GROW;
/*
@@ -8700,6 +8719,9 @@ xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
xmlChar start[4];
xmlCharEncoding enc;
+ if ((ctxt == NULL) || (ctxt->input == NULL))
+ return(-1);
+
xmlDefaultSAXHandlerInit();
xmlDetectSAX2(ctxt);
@@ -8942,6 +8964,9 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
xmlChar cur, next;
const xmlChar *lastlt, *lastgt;
+ if (ctxt->input == NULL)
+ return(0);
+
#ifdef DEBUG_PUSH
switch (ctxt->instate) {
case XML_PARSER_EOF:
@@ -9801,6 +9826,8 @@ done:
int
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
+ if (ctxt == NULL)
+ return(XML_ERR_INTERNAL_ERROR);
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
if (ctxt->instate == XML_PARSER_START)
@@ -9849,13 +9876,16 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
/*
* Check for termination
*/
- int avail = 0;
+ int avail = 0;
+
+ if (ctxt->input != NULL) {
if (ctxt->input->buf == NULL)
- avail = ctxt->input->length -
- (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use -
- (ctxt->input->cur - ctxt->input->base);
+ avail = ctxt->input->length -
+ (ctxt->input->cur - ctxt->input->base);
+ else
+ avail = ctxt->input->buf->buffer->use -
+ (ctxt->input->cur - ctxt->input->base);
+ }
if ((ctxt->instate != XML_PARSER_EOF) &&
(ctxt->instate != XML_PARSER_EPILOG)) {
@@ -9957,7 +9987,11 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlFreeParserCtxt(ctxt);
return(NULL);
}
- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+ memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
+ if (sax->initialized == XML_SAX2_MAGIC)
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+ else
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
if (user_data != NULL)
ctxt->userData = user_data;
}
@@ -10038,6 +10072,8 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
xmlParserInputBufferPtr buf;
+
+ if (ioread == NULL) return(NULL);
buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
if (buf == NULL) return(NULL);
@@ -10058,7 +10094,11 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlFree(ctxt);
return(NULL);
}
- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+ memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
+ if (sax->initialized == XML_SAX2_MAGIC)
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+ else
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
if (user_data != NULL)
ctxt->userData = user_data;
}
@@ -10253,7 +10293,8 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
if (input == NULL) {
if (sax != NULL) ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
- xmlFree(systemIdCanonic);
+ if (systemIdCanonic != NULL)
+ xmlFree(systemIdCanonic);
return(NULL);
}
@@ -10362,6 +10403,8 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
xmlChar start[4];
xmlCharEncoding enc;
+ if (ctx == NULL) return(-1);
+
if (ctx->depth > 40) {
return(XML_ERR_ENTITY_LOOP);
}
@@ -11163,7 +11206,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
xmlParserCtxtPtr ctxt;
xmlDocPtr newDoc;
xmlSAXHandlerPtr oldsax = NULL;
- xmlNodePtr content;
+ xmlNodePtr content, newRoot;
int size;
int ret = 0;
@@ -11193,14 +11236,23 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
xmlFreeParserCtxt(ctxt);
return(-1);
}
- newDoc->dict = ctxt->dict;
- xmlDictReference(newDoc->dict);
+ if ((doc != NULL) && (doc->dict != NULL)) {
+ xmlDictFree(ctxt->dict);
+ ctxt->dict = doc->dict;
+ xmlDictReference(ctxt->dict);
+ ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+ ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+ ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+ ctxt->dictNames = 1;
+ } else {
+ xmlCtxtUseOptions(ctxt, XML_PARSE_NODICT);
+ }
if (doc != NULL) {
newDoc->intSubset = doc->intSubset;
newDoc->extSubset = doc->extSubset;
}
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
+ newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+ if (newRoot == NULL) {
if (sax != NULL)
ctxt->sax = oldsax;
xmlFreeParserCtxt(ctxt);
@@ -11209,7 +11261,8 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
xmlFreeDoc(newDoc);
return(-1);
}
- nodePush(ctxt, newDoc->children);
+ xmlAddChild((xmlNodePtr) newDoc, newRoot);
+ nodePush(ctxt, newRoot);
if (doc == NULL) {
ctxt->myDoc = newDoc;
} else {
@@ -11253,21 +11306,22 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
ret = 0;
}
- if (lst != NULL && (ret == 0 || recover == 1)) {
- xmlNodePtr cur;
+ if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
+ xmlNodePtr cur;
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
+ /*
+ * Return the newly created nodeset after unlinking it from
+ * they pseudo parent.
+ */
+ cur = newDoc->children->children;
+ *lst = cur;
+ while (cur != NULL) {
+ xmlSetTreeDoc(cur, doc);
+ cur->parent = NULL;
+ cur = cur->next;
}
+ newDoc->children->children = NULL;
+ }
if (sax != NULL)
ctxt->sax = oldsax;
@@ -11627,10 +11681,13 @@ xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
{
xmlParserInputPtr input;
+ if ((ctxt == NULL) || (buffer == NULL))
+ return;
+
input = xmlNewInputStream(ctxt);
if (input == NULL) {
xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
- xmlFree(ctxt);
+ xmlClearParserCtxt(ctxt);
return;
}
@@ -11684,6 +11741,10 @@ xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
}
if (sax != NULL)
ctxt->sax = NULL;
+ if (ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
xmlFreeParserCtxt(ctxt);
return ret;
@@ -11886,6 +11947,10 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
ret = -1;
}
ctxt->sax = oldsax;
+ if (ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
xmlFreeParserCtxt(ctxt);
return ret;
@@ -11929,6 +11994,7 @@ xmlDocPtr
xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlSAXHandlerPtr oldsax = NULL;
if (cur == NULL) return(NULL);
@@ -11936,6 +12002,7 @@ xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
ctxt = xmlCreateDocParserCtxt(cur);
if (ctxt == NULL) return(NULL);
if (sax != NULL) {
+ oldsax = ctxt->sax;
ctxt->sax = sax;
ctxt->userData = NULL;
}
@@ -11948,8 +12015,8 @@ xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
- if (sax != NULL)
- ctxt->sax = NULL;
+ if (sax != NULL)
+ ctxt->sax = oldsax;
xmlFreeParserCtxt(ctxt);
return(ret);
@@ -12083,6 +12150,10 @@ xmlCleanupParser(void) {
#ifdef LIBXML_OUTPUT_ENABLED
xmlCleanupOutputCallbacks();
#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+ xmlSchemaCleanupTypes();
+ xmlRelaxNGCleanupTypes();
+#endif
xmlCleanupGlobals();
xmlResetLastError();
xmlCleanupThreads(); /* must be last if called not from the main thread */
@@ -12118,7 +12189,12 @@ void
xmlCtxtReset(xmlParserCtxtPtr ctxt)
{
xmlParserInputPtr input;
- xmlDictPtr dict = ctxt->dict;
+ xmlDictPtr dict;
+
+ if (ctxt == NULL)
+ return;
+
+ dict = ctxt->dict;
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
xmlFreeInputStream(input);
@@ -12314,6 +12390,8 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
int
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
{
+ if (ctxt == NULL)
+ return(-1);
if (options & XML_PARSE_RECOVER) {
ctxt->recovery = 1;
options -= XML_PARSE_RECOVER;