diff --git a/HTMLparser.c b/HTMLparser.c index b9a257bd..3b3e6cc5 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -6319,10 +6319,22 @@ htmlCtxtUseOptions(htmlParserCtxtPtr ctxt, int options) * Returns the resulting document tree or NULL */ htmlDocPtr -htmlCtxtParseDocument(htmlParserCtxtPtr ctxt) +htmlCtxtParseDocument(htmlParserCtxtPtr ctxt, xmlParserInputPtr input) { htmlDocPtr ret; + if ((ctxt == NULL) || (input == NULL)) + return(NULL); + + /* assert(ctxt->inputNr == 0); */ + while (ctxt->inputNr > 0) + xmlFreeInputStream(inputPop(ctxt)); + + if (inputPush(ctxt, input) < 0) { + xmlFreeInputStream(input); + return(NULL); + } + ctxt->html = 1; htmlParseDocument(ctxt); @@ -6334,6 +6346,10 @@ htmlCtxtParseDocument(htmlParserCtxtPtr ctxt) } ctxt->myDoc = NULL; + /* assert(ctxt->inputNr == 1); */ + while (ctxt->inputNr > 0) + xmlFreeInputStream(inputPop(ctxt)); + return(ret); } @@ -6367,13 +6383,8 @@ htmlReadDoc(const xmlChar *str, const char *url, const char *encoding, input = xmlNewInputString(ctxt, url, (const char *) str, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) { - htmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = htmlCtxtParseDocument(ctxt); + doc = htmlCtxtParseDocument(ctxt, input); htmlFreeParserCtxt(ctxt); return(doc); @@ -6406,13 +6417,8 @@ htmlReadFile(const char *filename, const char *encoding, int options) htmlCtxtUseOptions(ctxt, options); input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0); - if (input == NULL) { - htmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = htmlCtxtParseDocument(ctxt); + doc = htmlCtxtParseDocument(ctxt, input); htmlFreeParserCtxt(ctxt); return(doc); @@ -6452,13 +6458,8 @@ htmlReadMemory(const char *buffer, int size, const char *url, input = xmlNewInputMemory(ctxt, url, buffer, size, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) { - htmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = htmlCtxtParseDocument(ctxt); + doc = htmlCtxtParseDocument(ctxt, input); htmlFreeParserCtxt(ctxt); return(doc); @@ -6495,14 +6496,9 @@ htmlReadFd(int fd, const char *url, const char *encoding, int options) htmlCtxtUseOptions(ctxt, options); input = xmlNewInputFd(ctxt, url, fd, encoding, 0); - if (input == NULL) { - htmlFreeParserCtxt(ctxt); - return(NULL); - } input->buf->closecallback = NULL; - inputPush(ctxt, input); - doc = htmlCtxtParseDocument(ctxt); + doc = htmlCtxtParseDocument(ctxt, input); htmlFreeParserCtxt(ctxt); return(doc); @@ -6539,15 +6535,8 @@ htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose, htmlCtxtUseOptions(ctxt, options); input = xmlNewInputIO(ctxt, url, ioread, ioclose, ioctx, encoding, 0); - if (input == NULL) { - if (ioclose != NULL) - ioclose(ioctx); - htmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = htmlCtxtParseDocument(ctxt); + doc = htmlCtxtParseDocument(ctxt, input); htmlFreeParserCtxt(ctxt); return(doc); @@ -6580,11 +6569,8 @@ htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar *str, htmlCtxtUseOptions(ctxt, options); input = xmlNewInputString(ctxt, URL, (const char *) str, encoding, 0); - if (input == NULL) - return(NULL); - inputPush(ctxt, input); - return(htmlCtxtParseDocument(ctxt)); + return(htmlCtxtParseDocument(ctxt, input)); } /** @@ -6614,11 +6600,8 @@ htmlCtxtReadFile(htmlParserCtxtPtr ctxt, const char *filename, htmlCtxtUseOptions(ctxt, options); input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0); - if (input == NULL) - return (NULL); - inputPush(ctxt, input); - return(htmlCtxtParseDocument(ctxt)); + return(htmlCtxtParseDocument(ctxt, input)); } /** @@ -6651,11 +6634,8 @@ htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size, input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) - return(NULL); - inputPush(ctxt, input); - return(htmlCtxtParseDocument(ctxt)); + return(htmlCtxtParseDocument(ctxt, input)); } /** @@ -6688,12 +6668,9 @@ htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd, htmlCtxtUseOptions(ctxt, options); input = xmlNewInputFd(ctxt, URL, fd, encoding, 0); - if (input == NULL) - return (NULL); input->buf->closecallback = NULL; - inputPush(ctxt, input); - return(htmlCtxtParseDocument(ctxt)); + return(htmlCtxtParseDocument(ctxt, input)); } /** @@ -6727,14 +6704,8 @@ htmlCtxtReadIO(htmlParserCtxtPtr ctxt, xmlInputReadCallback ioread, htmlCtxtUseOptions(ctxt, options); input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0); - if (input == NULL) { - if (ioclose != NULL) - ioclose(ioctx); - return (NULL); - } - inputPush(ctxt, input); - return(htmlCtxtParseDocument(ctxt)); + return(htmlCtxtParseDocument(ctxt, input)); } #endif /* LIBXML_HTML_ENABLED */ diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h index 47c7598d..952a363f 100644 --- a/include/libxml/HTMLparser.h +++ b/include/libxml/HTMLparser.h @@ -247,7 +247,8 @@ XMLPUBFUN htmlDocPtr const char *encoding, int options); XMLPUBFUN htmlDocPtr - htmlCtxtParseDocument (htmlParserCtxtPtr ctxt); + htmlCtxtParseDocument (htmlParserCtxtPtr ctxt, + xmlParserInputPtr input); XMLPUBFUN htmlDocPtr htmlCtxtReadDoc (xmlParserCtxtPtr ctxt, const xmlChar *cur, diff --git a/include/libxml/parser.h b/include/libxml/parser.h index 37593f4d..bafc7c51 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -1313,7 +1313,8 @@ XMLPUBFUN xmlDocPtr const char *encoding, int options); XMLPUBFUN xmlDocPtr - xmlCtxtParseDocument (xmlParserCtxtPtr ctxt); + xmlCtxtParseDocument (xmlParserCtxtPtr ctxt, + xmlParserInputPtr input); XMLPUBFUN xmlDocPtr xmlCtxtReadDoc (xmlParserCtxtPtr ctxt, const xmlChar *cur, diff --git a/parser.c b/parser.c index ed3fbe20..948a0e77 100644 --- a/parser.c +++ b/parser.c @@ -2433,6 +2433,8 @@ xmlSkipBlankCharsPE(xmlParserCtxtPtr ctxt) { ent = ctxt->input->entity; + ent->flags &= ~XML_ENT_EXPANDING; + if ((ent->flags & XML_ENT_CHECKED) == 0) { consumed = ctxt->input->consumed; xmlSaturatedAddSizeT(&consumed, @@ -2496,8 +2498,6 @@ xmlPopInput(xmlParserCtxtPtr ctxt) { if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0); input = inputPop(ctxt); - if (input->entity != NULL) - input->entity->flags &= ~XML_ENT_EXPANDING; xmlFreeInputStream(input); if (*ctxt->input->cur == 0) xmlParserGrow(ctxt); @@ -11656,8 +11656,6 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data, input = xmlNewInputIO(ctxt, NULL, ioread, ioclose, ioctx, encoding, 0); if (input == NULL) { xmlFreeParserCtxt(ctxt); - if (ioclose != NULL) - ioclose(ioctx); return (NULL); } inputPush(ctxt, input); @@ -12673,29 +12671,22 @@ xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename, int recovery, void *data) { xmlDocPtr ret; xmlParserCtxtPtr ctxt; + xmlParserInputPtr input; - ctxt = xmlCreateFileParserCtxt(filename); - if (ctxt == NULL) { + ctxt = xmlNewSAXParserCtxt(sax, NULL); + if (ctxt == NULL) return(NULL); - } - if (sax != NULL) { - if (sax->initialized == XML_SAX2_MAGIC) { - *ctxt->sax = *sax; - } else { - memset(ctxt->sax, 0, sizeof(*ctxt->sax)); - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1)); - } - } - if (data!=NULL) { + + if (data != NULL) ctxt->_private = data; - } ctxt->recovery = recovery; - ret = xmlCtxtParseDocument(ctxt); + input = xmlNewInputURL(ctxt, filename, NULL, NULL, 0); + + ret = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); - return(ret); } @@ -12920,30 +12911,29 @@ xmlCreateMemoryParserCtxt(const char *buffer, int size) { xmlDocPtr xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer, - int size, int recovery, void *data) { + int size, int recovery, void *data) { xmlDocPtr ret; xmlParserCtxtPtr ctxt; + xmlParserInputPtr input; - ctxt = xmlCreateMemoryParserCtxt(buffer, size); - if (ctxt == NULL) return(NULL); - if (sax != NULL) { - if (sax->initialized == XML_SAX2_MAGIC) { - *ctxt->sax = *sax; - } else { - memset(ctxt->sax, 0, sizeof(*ctxt->sax)); - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1)); - } - } - if (data!=NULL) { + if (size < 0) + return(NULL); + + ctxt = xmlNewSAXParserCtxt(sax, NULL); + if (ctxt == NULL) + return(NULL); + + if (data != NULL) ctxt->_private=data; - } ctxt->recovery = recovery; - ret = xmlCtxtParseDocument(ctxt); + input = xmlNewInputMemory(ctxt, NULL, buffer, size, NULL, + XML_INPUT_BUF_STATIC); + + ret = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); - return(ret); } @@ -13593,16 +13583,30 @@ xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt, unsigned maxAmpl) /** * xmlCtxtParseDocument: * @ctxt: an XML parser context + * @input: parser input * * Parse an XML document and return the resulting document tree. + * Takes ownership of the input object. * * Returns the resulting document tree or NULL */ xmlDocPtr -xmlCtxtParseDocument(xmlParserCtxtPtr ctxt) +xmlCtxtParseDocument(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) { xmlDocPtr ret = NULL; + if ((ctxt == NULL) || (input == NULL)) + return(NULL); + + /* assert(ctxt->inputNr == 0); */ + while (ctxt->inputNr > 0) + xmlFreeInputStream(inputPop(ctxt)); + + if (inputPush(ctxt, input) < 0) { + xmlFreeInputStream(input); + return(NULL); + } + xmlParseDocument(ctxt); if ((ctxt->wellFormed) || @@ -13617,6 +13621,10 @@ xmlCtxtParseDocument(xmlParserCtxtPtr ctxt) } ctxt->myDoc = NULL; + /* assert(ctxt->inputNr == 1); */ + while (ctxt->inputNr > 0) + xmlFreeInputStream(inputPop(ctxt)); + return(ret); } @@ -13650,13 +13658,8 @@ xmlReadDoc(const xmlChar *cur, const char *URL, const char *encoding, input = xmlNewInputString(ctxt, URL, (const char *) cur, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = xmlCtxtParseDocument(ctxt); + doc = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); return(doc); @@ -13689,13 +13692,8 @@ xmlReadFile(const char *filename, const char *encoding, int options) xmlCtxtUseOptions(ctxt, options); input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = xmlCtxtParseDocument(ctxt); + doc = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); return(doc); @@ -13735,13 +13733,8 @@ xmlReadMemory(const char *buffer, int size, const char *url, input = xmlNewInputMemory(ctxt, url, buffer, size, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - inputPush(ctxt, input); - doc = xmlCtxtParseDocument(ctxt); + doc = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); return(doc); @@ -13777,14 +13770,9 @@ xmlReadFd(int fd, const char *URL, const char *encoding, int options) xmlCtxtUseOptions(ctxt, options); input = xmlNewInputFd(ctxt, URL, fd, encoding, 0); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } input->buf->closecallback = NULL; - inputPush(ctxt, input); - doc = xmlCtxtParseDocument(ctxt); + doc = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); return(doc); @@ -13820,15 +13808,8 @@ xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose, xmlCtxtUseOptions(ctxt, options); input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - if (ioclose != NULL) - ioclose(ioctx); - return (NULL); - } - inputPush(ctxt, input); - doc = xmlCtxtParseDocument(ctxt); + doc = xmlCtxtParseDocument(ctxt, input); xmlFreeParserCtxt(ctxt); return(doc); @@ -13865,11 +13846,8 @@ xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar *str, input = xmlNewInputString(ctxt, URL, (const char *) str, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) - return(NULL); - inputPush(ctxt, input); - return(xmlCtxtParseDocument(ctxt)); + return(xmlCtxtParseDocument(ctxt, input)); } /** @@ -13899,11 +13877,8 @@ xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename, xmlCtxtUseOptions(ctxt, options); input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0); - if (input == NULL) - return(NULL); - inputPush(ctxt, input); - return(xmlCtxtParseDocument(ctxt)); + return(xmlCtxtParseDocument(ctxt, input)); } /** @@ -13939,11 +13914,8 @@ xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size, input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding, XML_INPUT_BUF_STATIC); - if (input == NULL) - return(NULL); - inputPush(ctxt, input); - return(xmlCtxtParseDocument(ctxt)); + return(xmlCtxtParseDocument(ctxt, input)); } /** @@ -13979,12 +13951,9 @@ xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd, xmlCtxtUseOptions(ctxt, options); input = xmlNewInputFd(ctxt, URL, fd, encoding, 0); - if (input == NULL) - return (NULL); input->buf->closecallback = NULL; - inputPush(ctxt, input); - return(xmlCtxtParseDocument(ctxt)); + return(xmlCtxtParseDocument(ctxt, input)); } /** @@ -14022,13 +13991,7 @@ xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread, xmlCtxtUseOptions(ctxt, options); input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0); - if (input == NULL) { - if (ioclose != NULL) - ioclose(ioctx); - return (NULL); - } - inputPush(ctxt, input); - return(xmlCtxtParseDocument(ctxt)); + return(xmlCtxtParseDocument(ctxt, input)); } diff --git a/parserInternals.c b/parserInternals.c index 0538cdfa..442df676 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -1490,8 +1490,8 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) { * - a file opened from the filesystem, with automatic detection * of compressed files if support is compiled in. * - * The returned input should be push onto the input stack with - * xmlPushInput. + * The returned input can be passed to xmlCtxtParseDocument or + * htmlCtxtParseDocument. * * This function should not be invoked from user-defined resource * loaders to avoid infinite loops. @@ -1707,6 +1707,8 @@ xmlNewInputIO(xmlParserCtxtPtr ctxt, const char *url, buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE); if (buf == NULL) { xmlCtxtErrMemory(ctxt); + if (ioClose != NULL) + ioClose(ioCtxt); return(NULL); }