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"); |