summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorMike Hommey <mh@glandium.org>2004-09-10 05:26:00 +0000
committerMike Hommey <mh@glandium.org>2004-09-10 05:26:00 +0000
commit09deb06614c3408ec0816a3c88920138bae2083c (patch)
treea1b841a7dc28eecb98ca361c9371ecd1449a1908 /parser.c
parentc14c53a3645d81281058d4bb4cff24fa8d6faf33 (diff)
downloadlibxml2-09deb06614c3408ec0816a3c88920138bae2083c.tar.gz
Load /tmp/tmp.BmUFjT/libxml2-2.6.13 intoupstream/2.6.13
packages/libxml2/branches/upstream/current.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c242
1 files changed, 235 insertions, 7 deletions
diff --git a/parser.c b/parser.c
index 77a12f5..672c79c 100644
--- a/parser.c
+++ b/parser.c
@@ -605,6 +605,10 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
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);
+ if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
+ (ctxt->str_xml_ns == NULL)) {
+ xmlErrMemory(ctxt, NULL);
+ }
}
typedef struct _xmlDefAttrs xmlDefAttrs;
@@ -3470,13 +3474,16 @@ xmlParseComment(xmlParserCtxtPtr ctxt) {
xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
}
if (len + 5 >= size) {
+ xmlChar *new_buf;
size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
+ new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ if (new_buf == NULL) {
+ xmlFree (buf);
xmlErrMemory(ctxt, NULL);
ctxt->instate = state;
return;
}
+ buf = new_buf;
}
COPY_BUF(ql,buf,len,q);
q = r;
@@ -7628,7 +7635,8 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
}
SKIP(2);
- if ((tlen > 0) && (strncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
+ if ((tlen > 0) && (strncmp(ctxt->input->cur,
+ (const char *)ctxt->name, tlen) == 0)) {
if (ctxt->input->cur[tlen] == '>') {
ctxt->input->cur += tlen + 1;
goto done;
@@ -9075,6 +9083,10 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
ctxt->sax->setDocumentLocator(ctxt->userData,
&xmlDefaultSAXLocator);
ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+ if (ctxt->version == NULL) {
+ xmlErrMemory(ctxt, NULL);
+ break;
+ }
if ((ctxt->sax) && (ctxt->sax->startDocument) &&
(!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
@@ -9733,8 +9745,14 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
(ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
int cur = ctxt->input->cur - ctxt->input->base;
+ int res;
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+ res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+ if (res < 0) {
+ ctxt->errNo = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ return (XML_PARSER_EOF);
+ }
ctxt->input->base = ctxt->input->buf->buffer->content + base;
ctxt->input->cur = ctxt->input->base + cur;
ctxt->input->end =
@@ -9893,9 +9911,15 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
if (filename == NULL)
inputStream->filename = NULL;
- else
+ else {
inputStream->filename = (char *)
xmlCanonicPath((const xmlChar *) filename);
+ if (inputStream->filename == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ xmlFreeParserInputBuffer(buf);
+ return(NULL);
+ }
+ }
inputStream->buf = buf;
inputStream->base = inputStream->buf->buffer->content;
inputStream->cur = inputStream->buf->buffer->content;
@@ -10127,6 +10151,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
xmlParserCtxtPtr ctxt;
xmlParserInputPtr input = NULL;
xmlCharEncoding enc;
+ xmlChar* systemIdCanonic;
if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
@@ -10144,16 +10169,26 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
ctxt->sax = sax;
ctxt->userData = ctxt;
}
+
+ /*
+ * Canonicalise the system ID
+ */
+ systemIdCanonic = xmlCanonicPath(SystemID);
+ if (systemIdCanonic == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
/*
* Ask the Entity resolver to load the damn thing
*/
if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
- input = ctxt->sax->resolveEntity(ctxt, ExternalID, SystemID);
+ input = ctxt->sax->resolveEntity(ctxt, ExternalID, systemIdCanonic);
if (input == NULL) {
if (sax != NULL) ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
+ xmlFree(systemIdCanonic);
return(NULL);
}
@@ -10167,7 +10202,9 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
}
if (input->filename == NULL)
- input->filename = (char *) xmlCanonicPath(SystemID);
+ input->filename = (char *) systemIdCanonic;
+ else
+ xmlFree(systemIdCanonic);
input->line = 1;
input->col = 1;
input->base = ctxt->input->cur;
@@ -10359,6 +10396,7 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
ctxt->dictNames = ctx->dictNames;
ctxt->attsDefault = ctx->attsDefault;
ctxt->attsSpecial = ctx->attsSpecial;
+ ctxt->linenumbers = ctx->linenumbers;
xmlParseContent(ctxt);
@@ -10807,6 +10845,196 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
return(ret);
}
+/**
+ * xmlParseInNodeContext:
+ * @node: the context node
+ * @data: the input string
+ * @datalen: the input string length in bytes
+ * @options: a combination of xmlParserOption
+ * @lst: the return value for the set of parsed nodes
+ *
+ * Parse a well-balanced chunk of an XML document
+ * within the context (DTD, namespaces, etc ...) of the given node.
+ *
+ * The allowed sequence for the data is a Well Balanced Chunk defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns XML_ERR_OK if the chunk is well balanced, and the parser
+ * error code otherwise
+ */
+xmlParserErrors
+xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
+ int options, xmlNodePtr *lst) {
+#ifdef SAX2
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc = NULL;
+ xmlNodePtr fake, cur;
+ int nsnr = 0;
+
+ xmlParserErrors ret = XML_ERR_OK;
+
+ /*
+ * check all input parameters, grab the document
+ */
+ if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
+ return(XML_ERR_INTERNAL_ERROR);
+ switch (node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ break;
+ default:
+ return(XML_ERR_INTERNAL_ERROR);
+
+ }
+ while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
+ (node->type != XML_DOCUMENT_NODE) &&
+ (node->type != XML_HTML_DOCUMENT_NODE))
+ node = node->parent;
+ if (node == NULL)
+ return(XML_ERR_INTERNAL_ERROR);
+ if (node->type == XML_ELEMENT_NODE)
+ doc = node->doc;
+ else
+ doc = (xmlDocPtr) node;
+ if (doc == NULL)
+ return(XML_ERR_INTERNAL_ERROR);
+
+ /*
+ * allocate a context and set-up everything not related to the
+ * node position in the tree
+ */
+ if (doc->type == XML_DOCUMENT_NODE)
+ ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
+#ifdef LIBXML_HTML_ENABLED
+ else if (doc->type == XML_HTML_DOCUMENT_NODE)
+ ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
+#endif
+ else
+ return(XML_ERR_INTERNAL_ERROR);
+
+ if (ctxt == NULL)
+ return(XML_ERR_NO_MEMORY);
+ fake = xmlNewComment(NULL);
+ if (fake == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ return(XML_ERR_NO_MEMORY);
+ }
+ xmlAddChild(node, fake);
+
+ xmlCtxtUseOptions(ctxt, options);
+ if (doc->dict != NULL) {
+ if (ctxt->dict != NULL)
+ xmlDictFree(ctxt->dict);
+ ctxt->dict = doc->dict;
+ }
+ xmlDetectSAX2(ctxt);
+ ctxt->myDoc = doc;
+
+ if (node->type == XML_ELEMENT_NODE) {
+ nodePush(ctxt, node);
+ /*
+ * initialize the SAX2 namespaces stack
+ */
+ cur = node;
+ while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
+ xmlNsPtr ns = cur->nsDef;
+ const xmlChar *iprefix, *ihref;
+
+ while (ns != NULL) {
+ if (ctxt->dict) {
+ iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
+ ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
+ } else {
+ iprefix = ns->prefix;
+ ihref = ns->href;
+ }
+
+ if (xmlGetNamespace(ctxt, iprefix) == NULL) {
+ nsPush(ctxt, iprefix, ihref);
+ nsnr++;
+ }
+ ns = ns->next;
+ }
+ cur = cur->parent;
+ }
+ ctxt->instate = XML_PARSER_CONTENT;
+ }
+
+ if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
+ /*
+ * ID/IDREF registration will be done in xmlValidateElement below
+ */
+ ctxt->loadsubset |= XML_SKIP_IDS;
+ }
+
+ xmlParseContent(ctxt);
+ nsPop(ctxt, nsnr);
+ if ((RAW == '<') && (NXT(1) == '/')) {
+ xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+ } else if (RAW != 0) {
+ xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+ }
+ if ((ctxt->node != NULL) && (ctxt->node != node)) {
+ xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+ ctxt->wellFormed = 0;
+ }
+
+ if (!ctxt->wellFormed) {
+ if (ctxt->errNo == 0)
+ ret = XML_ERR_INTERNAL_ERROR;
+ else
+ ret = (xmlParserErrors)ctxt->errNo;
+ } else {
+ ret = XML_ERR_OK;
+ }
+
+ /*
+ * Return the newly created nodeset after unlinking it from
+ * the pseudo sibling.
+ */
+
+ cur = fake->next;
+ fake->next = NULL;
+ node->last = fake;
+
+ if (cur != NULL) {
+ cur->prev = NULL;
+ }
+
+ *lst = cur;
+
+ while (cur != NULL) {
+ cur->parent = NULL;
+ cur = cur->next;
+ }
+
+ xmlUnlinkNode(fake);
+ xmlFreeNode(fake);
+
+
+ if (ret != XML_ERR_OK) {
+ xmlFreeNodeList(*lst);
+ *lst = NULL;
+ }
+
+ ctxt->dict = NULL;
+ xmlFreeParserCtxt(ctxt);
+
+ return(ret);
+#else /* !SAX2 */
+ return(XML_ERR_INTERNAL_ERROR);
+#endif
+}
+
#ifdef LIBXML_SAX1_ENABLED
/**
* xmlParseBalancedChunkMemoryRecover: