| Index: third_party/libxml/src/SAX2.c
|
| diff --git a/third_party/libxml/src/SAX2.c b/third_party/libxml/src/SAX2.c
|
| index 84c1f00481cb2581c9be56ab0b5099713aaf9a88..ffef3e14689260103d852d0ad33a223701d9fbe7 100644
|
| --- a/third_party/libxml/src/SAX2.c
|
| +++ b/third_party/libxml/src/SAX2.c
|
| @@ -45,7 +45,7 @@
|
| *> values "system" and "public". I have made the default be "system" to
|
| *> match yours.
|
| */
|
| -#define TODO \
|
| +#define TODO \
|
| xmlGenericError(xmlGenericErrorContext, \
|
| "Unimplemented block at %s:%d\n", \
|
| __FILE__, __LINE__);
|
| @@ -57,12 +57,29 @@
|
| */
|
| static void
|
| xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
|
| + xmlStructuredErrorFunc schannel = NULL;
|
| + const char *str1 = "out of memory\n";
|
| +
|
| if (ctxt != NULL) {
|
| - if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
|
| - ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg);
|
| + ctxt->errNo = XML_ERR_NO_MEMORY;
|
| + if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
|
| + schannel = ctxt->sax->serror;
|
| + __xmlRaiseError(schannel,
|
| + ctxt->vctxt.error, ctxt->vctxt.userData,
|
| + ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
|
| + XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
| + NULL, NULL, 0, 0,
|
| + msg, (const char *) str1, NULL);
|
| ctxt->errNo = XML_ERR_NO_MEMORY;
|
| ctxt->instate = XML_PARSER_EOF;
|
| ctxt->disableSAX = 1;
|
| + } else {
|
| + __xmlRaiseError(schannel,
|
| + NULL, NULL,
|
| + ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
|
| + XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
| + NULL, NULL, 0, 0,
|
| + msg, (const char *) str1, NULL);
|
| }
|
| }
|
|
|
| @@ -126,7 +143,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
| if (ctxt != NULL)
|
| ctxt->errNo = error;
|
| __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
|
| - XML_ERR_FATAL, NULL, 0,
|
| + XML_ERR_FATAL, NULL, 0,
|
| (const char *) str1, (const char *) str2,
|
| NULL, 0, 0, msg, str1, str2);
|
| if (ctxt != NULL) {
|
| @@ -157,7 +174,7 @@ xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
| if (ctxt != NULL)
|
| ctxt->errNo = error;
|
| __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
|
| - XML_ERR_WARNING, NULL, 0,
|
| + XML_ERR_WARNING, NULL, 0,
|
| (const char *) str1, NULL,
|
| NULL, 0, 0, msg, str1);
|
| }
|
| @@ -182,7 +199,7 @@ xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
| if (ctxt != NULL)
|
| ctxt->errNo = error;
|
| __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
| - XML_ERR_ERROR, NULL, 0,
|
| + XML_ERR_ERROR, NULL, 0,
|
| (const char *) str1, (const char *) str2,
|
| NULL, 0, 0, msg, str1, str2);
|
| }
|
| @@ -206,7 +223,7 @@ xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
| if (ctxt != NULL)
|
| ctxt->errNo = error;
|
| __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
| - XML_ERR_WARNING, NULL, 0,
|
| + XML_ERR_WARNING, NULL, 0,
|
| (const char *) str1, (const char *) str2,
|
| NULL, 0, 0, msg, str1, str2);
|
| }
|
| @@ -240,7 +257,7 @@ xmlSAX2GetSystemId(void *ctx)
|
| {
|
| xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
| if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
|
| - return((const xmlChar *) ctxt->input->filename);
|
| + return((const xmlChar *) ctxt->input->filename);
|
| }
|
|
|
| /**
|
| @@ -355,7 +372,7 @@ xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
|
| xmlFreeDtd(dtd);
|
| ctxt->myDoc->intSubset = NULL;
|
| }
|
| - ctxt->myDoc->intSubset =
|
| + ctxt->myDoc->intSubset =
|
| xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
|
| if (ctxt->myDoc->intSubset == NULL)
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
|
| @@ -394,6 +411,7 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
|
| xmlParserInputPtr input = NULL;
|
| xmlCharEncoding enc;
|
| int oldcharset;
|
| + const xmlChar *oldencoding;
|
|
|
| /*
|
| * Ask the Entity resolver to load the damn thing
|
| @@ -415,6 +433,8 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
|
| oldinputMax = ctxt->inputMax;
|
| oldinputTab = ctxt->inputTab;
|
| oldcharset = ctxt->charset;
|
| + oldencoding = ctxt->encoding;
|
| + ctxt->encoding = NULL;
|
|
|
| ctxt->inputTab = (xmlParserInputPtr *)
|
| xmlMalloc(5 * sizeof(xmlParserInputPtr));
|
| @@ -425,6 +445,7 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
|
| ctxt->inputMax = oldinputMax;
|
| ctxt->inputTab = oldinputTab;
|
| ctxt->charset = oldcharset;
|
| + ctxt->encoding = oldencoding;
|
| return;
|
| }
|
| ctxt->inputNr = 0;
|
| @@ -470,6 +491,11 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
|
| ctxt->inputMax = oldinputMax;
|
| ctxt->inputTab = oldinputTab;
|
| ctxt->charset = oldcharset;
|
| + if ((ctxt->encoding != NULL) &&
|
| + ((ctxt->dict == NULL) ||
|
| + (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
|
| + xmlFree((xmlChar *) ctxt->encoding);
|
| + ctxt->encoding = oldencoding;
|
| /* ctxt->wellFormed = oldwellFormed; */
|
| }
|
| }
|
| @@ -574,6 +600,7 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
|
| * parse the external entity
|
| */
|
| xmlNodePtr children;
|
| + unsigned long oldnbent = ctxt->nbentities;
|
|
|
| val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
|
| ret->ExternalID, &children);
|
| @@ -586,8 +613,11 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
|
| return(NULL);
|
| }
|
| ret->owner = 1;
|
| - if (ret->checked == 0)
|
| - ret->checked = 1;
|
| + if (ret->checked == 0) {
|
| + ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
|
| + if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
|
| + ret->checked |= 1;
|
| + }
|
| }
|
| return(ret);
|
| }
|
| @@ -621,8 +651,8 @@ xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
|
| /**
|
| * xmlSAX2EntityDecl:
|
| * @ctx: the user data (XML parser context)
|
| - * @name: the entity name
|
| - * @type: the entity type
|
| + * @name: the entity name
|
| + * @type: the entity type
|
| * @publicId: The public ID of the entity
|
| * @systemId: The system ID of the entity
|
| * @content: the entity value (without processing).
|
| @@ -657,7 +687,7 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
|
| base = ctxt->input->filename;
|
| if (base == NULL)
|
| base = ctxt->directory;
|
| -
|
| +
|
| URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
| ent->URI = URI;
|
| }
|
| @@ -666,7 +696,7 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
|
| systemId, content);
|
| if ((ent == NULL) && (ctxt->pedantic) &&
|
| (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
| - ctxt->sax->warning(ctxt->userData,
|
| + ctxt->sax->warning(ctxt->userData,
|
| "Entity(%s) already defined in the external subset\n", name);
|
| if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
| xmlChar *URI;
|
| @@ -676,7 +706,7 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
|
| base = ctxt->input->filename;
|
| if (base == NULL)
|
| base = ctxt->directory;
|
| -
|
| +
|
| URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
| ent->URI = URI;
|
| }
|
| @@ -691,8 +721,8 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
|
| * xmlSAX2AttributeDecl:
|
| * @ctx: the user data (XML parser context)
|
| * @elem: the name of the element
|
| - * @fullname: the attribute name
|
| - * @type: the attribute type
|
| + * @fullname: the attribute name
|
| + * @type: the attribute type
|
| * @def: the type of default value
|
| * @defaultValue: the attribute default value
|
| * @tree: the tree of enumerated value set
|
| @@ -735,7 +765,7 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
|
| (xmlAttributeDefault) def, defaultValue, tree);
|
| else if (ctxt->inSubset == 2)
|
| attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
|
| - name, prefix, (xmlAttributeType) type,
|
| + name, prefix, (xmlAttributeType) type,
|
| (xmlAttributeDefault) def, defaultValue, tree);
|
| else {
|
| xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
|
| @@ -761,8 +791,8 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
|
| /**
|
| * xmlSAX2ElementDecl:
|
| * @ctx: the user data (XML parser context)
|
| - * @name: the element name
|
| - * @type: the element type
|
| + * @name: the element name
|
| + * @type: the element type
|
| * @content: the element value tree
|
| *
|
| * An element definition has been parsed
|
| @@ -883,7 +913,7 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
|
| publicId, systemId, notationName);
|
| if ((ent == NULL) && (ctxt->pedantic) &&
|
| (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
| - ctxt->sax->warning(ctxt->userData,
|
| + ctxt->sax->warning(ctxt->userData,
|
| "Entity(%s) already defined in the internal subset\n", name);
|
| if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
| xmlChar *URI;
|
| @@ -893,7 +923,7 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
|
| base = ctxt->input->filename;
|
| if (base == NULL)
|
| base = ctxt->directory;
|
| -
|
| +
|
| URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
| ent->URI = URI;
|
| }
|
| @@ -903,7 +933,7 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
|
| publicId, systemId, notationName);
|
| if ((ent == NULL) && (ctxt->pedantic) &&
|
| (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
| - ctxt->sax->warning(ctxt->userData,
|
| + ctxt->sax->warning(ctxt->userData,
|
| "Entity(%s) already defined in the external subset\n", name);
|
| if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
| xmlChar *URI;
|
| @@ -913,7 +943,7 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
|
| base = ctxt->input->filename;
|
| if (base == NULL)
|
| base = ctxt->directory;
|
| -
|
| +
|
| URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
| ent->URI = URI;
|
| }
|
| @@ -964,12 +994,12 @@ xmlSAX2StartDocument(void *ctx)
|
| #ifdef LIBXML_HTML_ENABLED
|
| if (ctxt->myDoc == NULL)
|
| ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
|
| - ctxt->myDoc->properties = XML_DOC_HTML;
|
| - ctxt->myDoc->parseFlags = ctxt->options;
|
| if (ctxt->myDoc == NULL) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
|
| return;
|
| }
|
| + ctxt->myDoc->properties = XML_DOC_HTML;
|
| + ctxt->myDoc->parseFlags = ctxt->options;
|
| #else
|
| xmlGenericError(xmlGenericErrorContext,
|
| "libxml2 built without HTML support\n");
|
| @@ -1048,7 +1078,7 @@ xmlSAX2EndDocument(void *ctx)
|
| }
|
| }
|
|
|
| -#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
|
| +#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
| /**
|
| * xmlSAX2AttributeInternal:
|
| * @ctx: the user data (XML parser context)
|
| @@ -1147,6 +1177,12 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
| 0,0,0);
|
| ctxt->depth--;
|
| + if (val == NULL) {
|
| + xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
| + if (name != NULL)
|
| + xmlFree(name);
|
| + return;
|
| + }
|
| } else {
|
| val = (xmlChar *) value;
|
| }
|
| @@ -1157,12 +1193,12 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| uri = xmlParseURI((const char *)val);
|
| if (uri == NULL) {
|
| if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
| - ctxt->sax->warning(ctxt->userData,
|
| + ctxt->sax->warning(ctxt->userData,
|
| "xmlns: %s not a valid URI\n", val);
|
| } else {
|
| if (uri->scheme == NULL) {
|
| if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
| - ctxt->sax->warning(ctxt->userData,
|
| + ctxt->sax->warning(ctxt->userData,
|
| "xmlns: URI %s is not absolute\n", val);
|
| }
|
| xmlFreeURI(uri);
|
| @@ -1182,7 +1218,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
|
| ctxt->node, prefix, nsret, val);
|
| #endif /* LIBXML_VALID_ENABLED */
|
| - if (name != NULL)
|
| + if (name != NULL)
|
| xmlFree(name);
|
| if (nval != NULL)
|
| xmlFree(nval);
|
| @@ -1204,7 +1240,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| if (val == NULL) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
| xmlFree(ns);
|
| - if (name != NULL)
|
| + if (name != NULL)
|
| xmlFree(name);
|
| return;
|
| }
|
| @@ -1245,7 +1281,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
|
| ctxt->node, prefix, nsret, value);
|
| #endif /* LIBXML_VALID_ENABLED */
|
| - if (name != NULL)
|
| + if (name != NULL)
|
| xmlFree(name);
|
| if (nval != NULL)
|
| xmlFree(nval);
|
| @@ -1311,7 +1347,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| #ifdef LIBXML_VALID_ENABLED
|
| if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
| ctxt->myDoc && ctxt->myDoc->intSubset) {
|
| -
|
| +
|
| /*
|
| * If we don't substitute entities, the validation should be
|
| * done on a value with replaced entities anyway.
|
| @@ -1323,7 +1359,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
| 0,0,0);
|
| ctxt->depth--;
|
| -
|
| +
|
| if (val == NULL)
|
| ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
| ctxt->myDoc, ctxt->node, ret, value);
|
| @@ -1380,7 +1416,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
| error:
|
| if (nval != NULL)
|
| xmlFree(nval);
|
| - if (ns != NULL)
|
| + if (ns != NULL)
|
| xmlFree(ns);
|
| }
|
|
|
| @@ -1479,7 +1515,7 @@ process_external_subset:
|
| * - this is a namespace prefix
|
| * - the user required for completion in the tree
|
| * like XSLT
|
| - * - there isn't already an attribute definition
|
| + * - there isn't already an attribute definition
|
| * in the internal subset overriding it.
|
| */
|
| if (((attr->prefix != NULL) &&
|
| @@ -1568,17 +1604,17 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
|
| /*
|
| * First check on validity:
|
| */
|
| - if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
| + if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
| ((ctxt->myDoc->intSubset == NULL) ||
|
| - ((ctxt->myDoc->intSubset->notations == NULL) &&
|
| + ((ctxt->myDoc->intSubset->notations == NULL) &&
|
| (ctxt->myDoc->intSubset->elements == NULL) &&
|
| - (ctxt->myDoc->intSubset->attributes == NULL) &&
|
| + (ctxt->myDoc->intSubset->attributes == NULL) &&
|
| (ctxt->myDoc->intSubset->entities == NULL)))) {
|
| xmlErrValid(ctxt, XML_ERR_NO_DTD,
|
| "Validation failed: no DTD found !", NULL, NULL);
|
| ctxt->validate = 0;
|
| }
|
| -
|
| +
|
|
|
| /*
|
| * Split the full name into a namespace prefix and the tag name
|
| @@ -1756,7 +1792,6 @@ void
|
| xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
| {
|
| xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
| - xmlParserNodeInfo node_info;
|
| xmlNodePtr cur;
|
|
|
| if (ctx == NULL) return;
|
| @@ -1767,13 +1802,13 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
| else
|
| xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
|
| #endif
|
| -
|
| +
|
| /* Capture end position and add node */
|
| if (cur != NULL && ctxt->record_info) {
|
| - node_info.end_pos = ctxt->input->cur - ctxt->input->base;
|
| - node_info.end_line = ctxt->input->line;
|
| - node_info.node = cur;
|
| - xmlParserAddNodeInfo(ctxt, &node_info);
|
| + ctxt->nodeInfo->end_pos = ctxt->input->cur - ctxt->input->base;
|
| + ctxt->nodeInfo->end_line = ctxt->input->line;
|
| + ctxt->nodeInfo->node = cur;
|
| + xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
|
| }
|
| ctxt->nodemem = -1;
|
|
|
| @@ -1784,7 +1819,7 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
| cur);
|
| #endif /* LIBXML_VALID_ENABLED */
|
|
|
| -
|
| +
|
| /*
|
| * end of parsing of this node.
|
| */
|
| @@ -1793,15 +1828,15 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
| #endif
|
| nodePop(ctxt);
|
| }
|
| -#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
|
| +#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
|
|
|
| /*
|
| * xmlSAX2TextNode:
|
| * @ctxt: the parser context
|
| * @str: the input string
|
| * @len: the string length
|
| - *
|
| - * Remove the entities from an attribute value
|
| + *
|
| + * Callback for a text node
|
| *
|
| * Returns the newly allocated string or NULL if not needed or error
|
| */
|
| @@ -1834,7 +1869,7 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
|
|
|
| if ((len < (int) (2 * sizeof(void *))) &&
|
| (ctxt->options & XML_PARSE_COMPACT)) {
|
| - /* store the string in the node overrithing properties and nsDef */
|
| + /* store the string in the node overriding properties and nsDef */
|
| xmlChar *tmp = (xmlChar *) &(ret->properties);
|
| memcpy(tmp, str, len);
|
| tmp[len] = 0;
|
| @@ -1866,8 +1901,17 @@ skip:
|
| } else
|
| ret->content = (xmlChar *) intern;
|
|
|
| - if (ctxt->input != NULL)
|
| - ret->line = ctxt->input->line;
|
| + if (ctxt->linenumbers) {
|
| + if (ctxt->input != NULL) {
|
| + if (ctxt->input->line < 65535)
|
| + ret->line = (short) ctxt->input->line;
|
| + else {
|
| + ret->line = 65535;
|
| + if (ctxt->options & XML_PARSE_BIG_LINES)
|
| + ret->psvi = (void *) (long) ctxt->input->line;
|
| + }
|
| + }
|
| + }
|
|
|
| if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
|
| xmlRegisterNodeDefaultValue(ret);
|
| @@ -1880,7 +1924,7 @@ skip:
|
| * @ctxt: the parser context
|
| * @str: the input string
|
| * @len: the string length
|
| - *
|
| + *
|
| * Remove the entities from an attribute value
|
| *
|
| * Returns the newly allocated string or NULL if not needed or error
|
| @@ -1946,7 +1990,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
| memset(ret, 0, sizeof(xmlAttr));
|
| ret->type = XML_ATTRIBUTE_NODE;
|
|
|
| - ret->parent = ctxt->node;
|
| + ret->parent = ctxt->node;
|
| ret->doc = ctxt->myDoc;
|
| ret->ns = namespace;
|
|
|
| @@ -1970,7 +2014,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
| xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
|
| } else {
|
| if (ctxt->dictNames)
|
| - ret = xmlNewNsPropEatName(ctxt->node, namespace,
|
| + ret = xmlNewNsPropEatName(ctxt->node, namespace,
|
| (xmlChar *) localname, NULL);
|
| else
|
| ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
|
| @@ -2056,7 +2100,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
| xmlChar *nvalnorm;
|
| xmlChar fn[50];
|
| xmlChar *fullname;
|
| -
|
| +
|
| fullname = xmlBuildQName(localname, prefix, fn, 50);
|
| if (fullname != NULL) {
|
| ctxt->vctxt.valid = 1;
|
| @@ -2107,6 +2151,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
| */
|
| if (dup == NULL)
|
| dup = xmlStrndup(value, valueend - value);
|
| +#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
| #ifdef LIBXML_VALID_ENABLED
|
| if (xmlValidateNCName(dup, 1) != 0) {
|
| xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
|
| @@ -2114,6 +2159,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
| (const char *) dup, NULL);
|
| }
|
| #endif
|
| +#endif
|
| xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
| } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
|
| /* might be worth duplicate entry points and not copy */
|
| @@ -2163,6 +2209,7 @@ xmlSAX2StartElementNs(void *ctx,
|
| xmlNodePtr parent;
|
| xmlNsPtr last = NULL, ns;
|
| const xmlChar *uri, *pref;
|
| + xmlChar *lname = NULL;
|
| int i, j;
|
|
|
| if (ctx == NULL) return;
|
| @@ -2170,18 +2217,32 @@ xmlSAX2StartElementNs(void *ctx,
|
| /*
|
| * First check on validity:
|
| */
|
| - if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
| + if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
| ((ctxt->myDoc->intSubset == NULL) ||
|
| - ((ctxt->myDoc->intSubset->notations == NULL) &&
|
| + ((ctxt->myDoc->intSubset->notations == NULL) &&
|
| (ctxt->myDoc->intSubset->elements == NULL) &&
|
| - (ctxt->myDoc->intSubset->attributes == NULL) &&
|
| + (ctxt->myDoc->intSubset->attributes == NULL) &&
|
| (ctxt->myDoc->intSubset->entities == NULL)))) {
|
| - xmlErrValid(ctxt, XML_ERR_NO_DTD,
|
| + xmlErrValid(ctxt, XML_DTD_NO_DTD,
|
| "Validation failed: no DTD found !", NULL, NULL);
|
| ctxt->validate = 0;
|
| }
|
|
|
| /*
|
| + * Take care of the rare case of an undefined namespace prefix
|
| + */
|
| + if ((prefix != NULL) && (URI == NULL)) {
|
| + if (ctxt->dictNames) {
|
| + const xmlChar *fullname;
|
| +
|
| + fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
|
| + if (fullname != NULL)
|
| + localname = fullname;
|
| + } else {
|
| + lname = xmlBuildQName(localname, prefix, NULL, 0);
|
| + }
|
| + }
|
| + /*
|
| * allocate the node
|
| */
|
| if (ctxt->freeElems != NULL) {
|
| @@ -2194,7 +2255,10 @@ xmlSAX2StartElementNs(void *ctx,
|
| if (ctxt->dictNames)
|
| ret->name = localname;
|
| else {
|
| - ret->name = xmlStrdup(localname);
|
| + if (lname == NULL)
|
| + ret->name = xmlStrdup(localname);
|
| + else
|
| + ret->name = lname;
|
| if (ret->name == NULL) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
| return;
|
| @@ -2204,10 +2268,13 @@ xmlSAX2StartElementNs(void *ctx,
|
| xmlRegisterNodeDefaultValue(ret);
|
| } else {
|
| if (ctxt->dictNames)
|
| - ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
|
| + ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
|
| (xmlChar *) localname, NULL);
|
| - else
|
| + else if (lname == NULL)
|
| ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
|
| + else
|
| + ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
|
| + (xmlChar *) lname, NULL);
|
| if (ret == NULL) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
| return;
|
| @@ -2222,7 +2289,7 @@ xmlSAX2StartElementNs(void *ctx,
|
| }
|
| }
|
|
|
| - if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
|
| + if (parent == NULL) {
|
| xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
|
| }
|
| /*
|
| @@ -2242,8 +2309,12 @@ xmlSAX2StartElementNs(void *ctx,
|
| if ((URI != NULL) && (prefix == pref))
|
| ret->ns = ns;
|
| } else {
|
| - xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
| - return;
|
| + /*
|
| + * any out of memory error would already have been raised
|
| + * but we can't be garanteed it's the actual error due to the
|
| + * API, best is to skip in this case
|
| + */
|
| + continue;
|
| }
|
| #ifdef LIBXML_VALID_ENABLED
|
| if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
| @@ -2310,8 +2381,33 @@ xmlSAX2StartElementNs(void *ctx,
|
| */
|
| if (nb_attributes > 0) {
|
| for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
|
| + /*
|
| + * Handle the rare case of an undefined atribute prefix
|
| + */
|
| + if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
|
| + if (ctxt->dictNames) {
|
| + const xmlChar *fullname;
|
| +
|
| + fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
|
| + attributes[j]);
|
| + if (fullname != NULL) {
|
| + xmlSAX2AttributeNs(ctxt, fullname, NULL,
|
| + attributes[j+3], attributes[j+4]);
|
| + continue;
|
| + }
|
| + } else {
|
| + lname = xmlBuildQName(attributes[j], attributes[j+1],
|
| + NULL, 0);
|
| + if (lname != NULL) {
|
| + xmlSAX2AttributeNs(ctxt, lname, NULL,
|
| + attributes[j+3], attributes[j+4]);
|
| + xmlFree(lname);
|
| + continue;
|
| + }
|
| + }
|
| + }
|
| xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
|
| - attributes[j+3], attributes[j+4]);
|
| + attributes[j+3], attributes[j+4]);
|
| }
|
| }
|
|
|
| @@ -2382,7 +2478,7 @@ xmlSAX2EndElementNs(void *ctx,
|
| * @ctx: the user data (XML parser context)
|
| * @name: The entity name
|
| *
|
| - * called when an entity xmlSAX2Reference is detected.
|
| + * called when an entity xmlSAX2Reference is detected.
|
| */
|
| void
|
| xmlSAX2Reference(void *ctx, const xmlChar *name)
|
| @@ -2482,12 +2578,16 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
|
| (xmlDictOwns(ctxt->dict, lastChild->content))) {
|
| lastChild->content = xmlStrdup(lastChild->content);
|
| }
|
| + if (lastChild->content == NULL) {
|
| + xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
|
| + return;
|
| + }
|
| if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
|
| ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
|
| return;
|
| }
|
| - if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
|
| + if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
|
| (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
|
| xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
|
| return;
|
| @@ -2591,7 +2691,7 @@ xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
|
| xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
|
| return;
|
| }
|
| - if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
|
| + if (parent == NULL) {
|
| #ifdef DEBUG_SAX_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "Setting PI %s as root\n", target);
|
| @@ -2652,7 +2752,7 @@ xmlSAX2Comment(void *ctx, const xmlChar *value)
|
| xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
|
| return;
|
| }
|
| - if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
|
| + if (parent == NULL) {
|
| #ifdef DEBUG_SAX_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "Setting xmlSAX2Comment as root\n");
|
|
|