diff options
| author | Mike Hommey <glandium@debian.org> | 2006-10-26 11:17:37 +0200 |
|---|---|---|
| committer | Mike Hommey <glandium@debian.org> | 2006-10-26 11:17:37 +0200 |
| commit | 968041a8b2ec86c39b5074024ce97d136ecd9a95 (patch) | |
| tree | 6971d7bce63213fd376b0e66311d0c67a8da4d64 /parser.c | |
| parent | a7e9d3f37d5e9fba4b9acaa43e7c12b6d9a669ae (diff) | |
| download | libxml2-upstream/2.6.27.dfsg.tar.gz | |
Load /tmp/libxml2-2.6.27 intoupstream/2.6.27.dfsg
libxml2/branches/upstream/current.
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 197 |
1 files changed, 151 insertions, 46 deletions
@@ -807,6 +807,12 @@ xmlHasFeature(xmlFeature feature) #else return(0); #endif + case XML_WITH_ZLIB: +#ifdef LIBXML_ZLIB_ENABLED + return(1); +#else + return(0); +#endif default: break; } @@ -1442,7 +1448,7 @@ static int spacePop(xmlParserCtxtPtr ctxt) { if (ctxt->spaceNr > 0) ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1]; else - ctxt->space = NULL; + ctxt->space = &ctxt->spaceTab[0]; ret = ctxt->spaceTab[ctxt->spaceNr]; ctxt->spaceTab[ctxt->spaceNr] = -1; return(ret); @@ -2356,7 +2362,8 @@ static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, /* * Check for xml:space value. */ - if (*(ctxt->space) == 1) + if ((ctxt->space == NULL) || (*(ctxt->space) == 1) || + (*(ctxt->space) == -2)) return(0); /* @@ -2485,10 +2492,12 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { buffer[len] = 0; } - /* nasty but well=formed if ((c == ':') && (*cur == 0)) { + if (buffer != NULL) + xmlFree(buffer); + *prefix = NULL; return(xmlStrdup(name)); - } */ + } if (buffer == NULL) ret = xmlStrndup(buf, len); @@ -3500,9 +3509,13 @@ get_more_space: if (ctxt->sax->ignorableWhitespace != NULL) 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) + ctxt->sax->characters(ctxt->userData, + tmp, nbchar); + if (*ctxt->space == -1) + *ctxt->space = -2; + } } else if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) { ctxt->sax->characters(ctxt->userData, @@ -3549,9 +3562,13 @@ get_more: if (ctxt->sax->ignorableWhitespace != NULL) 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) + ctxt->sax->characters(ctxt->userData, + tmp, nbchar); + if (*ctxt->space == -1) + *ctxt->space = -2; + } line = ctxt->input->line; col = ctxt->input->col; } else if (ctxt->sax != NULL) { @@ -3634,6 +3651,10 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) { } else { if (ctxt->sax->characters != NULL) ctxt->sax->characters(ctxt->userData, buf, nbchar); + if ((ctxt->sax->characters != + ctxt->sax->ignorableWhitespace) && + (*ctxt->space == -1)) + *ctxt->space = -2; } } nbchar = 0; @@ -3658,6 +3679,9 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) { } else { if (ctxt->sax->characters != NULL) ctxt->sax->characters(ctxt->userData, buf, nbchar); + if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) && + (*ctxt->space == -1)) + *ctxt->space = -2; } } } @@ -5923,10 +5947,13 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ctxt->sax->characters(ctxt->userData, out, i); } } else { + int was_checked; + ent = xmlParseEntityRef(ctxt); if (ent == NULL) return; if (!ctxt->wellFormed) return; + was_checked = ent->checked; if ((ent->name != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) { xmlNodePtr list = NULL; @@ -5938,8 +5965,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { * where the ent->children is filled with the result from * the parsing. */ - if (ent->children == NULL) { + if (ent->checked == 0) { xmlChar *value; + value = ent->content; /* @@ -6074,15 +6102,69 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { list = NULL; } } + ent->checked = 1; + } + + if (ent->children == NULL) { + /* + * Probably running in SAX mode and the callbacks don't + * build the entity content. So unless we already went + * though parsing for first checking go though the entity + * content to generate callbacks associated to the entity + */ + if (was_checked == 1) { + void *user_data; + /* + * This is a bit hackish but this seems the best + * way to make sure both SAX and DOM entity support + * behaves okay. + */ + if (ctxt->userData == ctxt) + user_data = NULL; + else + user_data = ctxt->userData; + + if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { + ctxt->depth++; + ret = xmlParseBalancedChunkMemoryInternal(ctxt, + ent->content, user_data, NULL); + ctxt->depth--; + } else if (ent->etype == + XML_EXTERNAL_GENERAL_PARSED_ENTITY) { + ctxt->depth++; + ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, + ctxt->sax, user_data, ctxt->depth, + ent->URI, ent->ExternalID, NULL); + ctxt->depth--; + } else { + ret = XML_ERR_ENTITY_PE_INTERNAL; + xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, + "invalid entity type found\n", NULL); + } + if (ret == XML_ERR_ENTITY_LOOP) { + xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); + return; + } + } + if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) && + (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) { + /* + * Entity reference callback comes second, it's somewhat + * superfluous but a compatibility to historical behaviour + */ + ctxt->sax->reference(ctxt->userData, ent->name); + } + return; } if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) && - (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) { + (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) { /* * Create a node. */ ctxt->sax->reference(ctxt->userData, ent->name); return; - } else if (ctxt->replaceEntities) { + } + if ((ctxt->replaceEntities) || (ent->children == NULL)) { /* * There is a problem on the handling of _private for entities * (bug 155816): Should we copy the content of the field from @@ -6206,31 +6288,6 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ctxt->nodemem = 0; ctxt->nodelen = 0; return; - } else { - /* - * Probably running in SAX mode - */ - xmlParserInputPtr input; - - input = xmlNewEntityInputStream(ctxt, ent); - xmlPushInput(ctxt, input); - if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) && - (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && - (IS_BLANK_CH(NXT(5)))) { - xmlParseTextDecl(ctxt); - if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { - /* - * The XML REC instructs us to stop parsing right here - */ - ctxt->instate = XML_PARSER_EOF; - return; - } - if (input->standalone == 1) { - xmlFatalErr(ctxt, XML_ERR_EXT_ENTITY_STANDALONE, - NULL); - } - } - return; } } } else { @@ -6337,7 +6394,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) { if ((ctxt->inSubset == 0) && (ctxt->sax != NULL) && (ctxt->sax->reference != NULL)) { - ctxt->sax->reference(ctxt, name); + ctxt->sax->reference(ctxt->userData, name); } } ctxt->valid = 0; @@ -7808,7 +7865,7 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref, const xmlChar **atts = ctxt->atts; int maxatts = ctxt->maxatts; int nratts, nbatts, nbdef; - int i, j, nbNs, attval; + int i, j, nbNs, attval, oldline, oldcol; const xmlChar *base; unsigned long cur; int nsNr = ctxt->nsNr; @@ -7827,6 +7884,8 @@ reparse: SHRINK; base = ctxt->input->base; cur = ctxt->input->cur - ctxt->input->base; + oldline = ctxt->input->line; + oldcol = ctxt->input->col; nbatts = 0; nratts = 0; nbdef = 0; @@ -7861,6 +7920,12 @@ reparse: attname = xmlParseAttribute2(ctxt, prefix, localname, &aprefix, &attvalue, &len, &alloc); + if (ctxt->input->base != base) { + if ((attvalue != NULL) && (alloc != 0)) + xmlFree(attvalue); + attvalue = NULL; + goto base_changed; + } if ((attname != NULL) && (attvalue != NULL)) { if (len < 0) len = xmlStrlen(attvalue); if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) { @@ -8152,6 +8217,8 @@ base_changed: xmlFree((xmlChar *) atts[i]); } ctxt->input->cur = ctxt->input->base + cur; + ctxt->input->line = oldline; + ctxt->input->col = oldcol; if (ctxt->wellFormed == 1) { goto reparse; } @@ -8349,7 +8416,8 @@ void xmlParseContent(xmlParserCtxtPtr ctxt) { GROW; while ((RAW != 0) && - ((RAW != '<') || (NXT(1) != '/'))) { + ((RAW != '<') || (NXT(1) != '/')) && + (ctxt->instate != XML_PARSER_EOF)) { const xmlChar *test = CUR_PTR; unsigned int cons = ctxt->input->consumed; const xmlChar *cur = ctxt->input->cur; @@ -8442,6 +8510,14 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { xmlNodePtr ret; int nsNr = ctxt->nsNr; + if ((unsigned int) ctxt->nameNr > xmlParserMaxDepth) { + xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR, + "Excessive depth in document: change xmlParserMaxDepth = %d\n", + xmlParserMaxDepth); + ctxt->instate = XML_PARSER_EOF; + return; + } + /* Capture start position */ if (ctxt->record_info) { node_info.begin_pos = ctxt->input->consumed + @@ -8451,6 +8527,8 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { if (ctxt->spaceNr == 0) spacePush(ctxt, -1); + else if (*ctxt->space == -2) + spacePush(ctxt, -1); else spacePush(ctxt, *ctxt->space); @@ -9767,6 +9845,8 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { } if (ctxt->spaceNr == 0) spacePush(ctxt, -1); + else if (*ctxt->space == -2) + spacePush(ctxt, -1); else spacePush(ctxt, *ctxt->space); #ifdef LIBXML_SAX1_ENABLED @@ -10759,7 +10839,7 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data, * Load and parse a DTD * * Returns the resulting xmlDtdPtr or NULL in case of error. - * @input will be freed at parsing end. + * @input will be freed by the function in any case. */ xmlDtdPtr @@ -10775,6 +10855,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { + xmlFreeParserInputBuffer(input); return(NULL); } @@ -10796,6 +10877,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); if (pinput == NULL) { if (sax != NULL) ctxt->sax = NULL; + xmlFreeParserInputBuffer(input); xmlFreeParserCtxt(ctxt); return(NULL); } @@ -10919,7 +11001,8 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, */ if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) - input = ctxt->sax->resolveEntity(ctxt, ExternalID, systemIdCanonic); + input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, + systemIdCanonic); if (input == NULL) { if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); @@ -11032,6 +11115,8 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL, int ret = 0; xmlChar start[4]; xmlCharEncoding enc; + xmlParserInputPtr inputStream; + char *directory = NULL; if (ctx == NULL) return(-1); @@ -11046,11 +11131,27 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL, if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */ return(-1); - - ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL); - if (ctxt == NULL) return(-1); + ctxt = xmlNewParserCtxt(); + if (ctxt == NULL) { + return(-1); + } + ctxt->userData = ctxt; ctxt->_private = ctx->_private; + + inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt); + if (inputStream == NULL) { + xmlFreeParserCtxt(ctxt); + return(-1); + } + + inputPush(ctxt, inputStream); + + if ((ctxt->directory == NULL) && (directory == NULL)) + directory = xmlParserGetDirectory((char *)URL); + if ((ctxt->directory == NULL) && (directory != NULL)) + ctxt->directory = directory; + oldsax = ctxt->sax; ctxt->sax = ctx->sax; xmlDetectSAX2(ctxt); @@ -11897,6 +11998,9 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, } else { ctxt->myDoc = newDoc; newDoc->children->doc = doc; + /* Ensure that doc has XML spec namespace */ + xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE); + newDoc->oldNs = doc->oldNs; } ctxt->instate = XML_PARSER_CONTENT; ctxt->depth = depth; @@ -11957,6 +12061,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, xmlFreeParserCtxt(ctxt); newDoc->intSubset = NULL; newDoc->extSubset = NULL; + newDoc->oldNs = NULL; xmlFreeDoc(newDoc); return(ret); |
