diff --git a/ChangeLog b/ChangeLog index 2e3c4550..dfd89a47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sun Apr 18 22:51:43 CEST 2004 Daniel Veillard + + * xpath.c: relaxed id() to not check taht the name(s) passed + are actually NCName, decided this in agreement with Aleksey Sanin + since existing specs like Visa3D broke that conformance checking + and other tools seems to not implement it sigh... + * SAX2.c: check attribute decls for xml:id and the value is an + NCName. + * test/xmlid/id_err* result/xmlid/id_err*: added error testing + Sun Apr 18 21:46:17 CEST 2004 Daniel Veillard * xpath.c: work around Microsoft compiler NaN bug raise reported diff --git a/SAX2.c b/SAX2.c index fdc537a5..781a666a 100644 --- a/SAX2.c +++ b/SAX2.c @@ -573,6 +573,16 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n", elem, fullname, type, def, defaultValue); #endif + if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) && + (type != XML_ATTRIBUTE_ID)) { + /* + * Raise the error but keep the validity flag + */ + int tmp = ctxt->valid; + xmlErrValid(ctxt, XML_DTD_XMLID_TYPE, + "xml:id : attribute type should be ID\n", NULL, NULL); + ctxt->valid = tmp; + } /* TODO: optimize name/prefix allocation */ name = xmlSplitQName(ctxt, fullname, &prefix); ctxt->vctxt.valid = 1; @@ -1210,6 +1220,11 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, * * Open issue: normalization of the value. */ + if (xmlValidateNCName(value, 1) != 0) { + xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, + "xml:id : attribute value %s is not an NCName\n", + (const char *) value, NULL); + } xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); } } @@ -1943,6 +1958,11 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt, */ if (dup == NULL) dup = xmlStrndup(value, valueend - value); + if (xmlValidateNCName(dup, 1) != 0) { + xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, + "xml:id : attribute value %s is not an NCName\n", + (const char *) dup, NULL); + } xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); } } diff --git a/configure.in b/configure.in index 391dda77..c8a15367 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_CANONICAL_HOST LIBXML_MAJOR_VERSION=2 LIBXML_MINOR_VERSION=6 -LIBXML_MICRO_VERSION=8 +LIBXML_MICRO_VERSION=9 LIBXML_MICRO_VERSION_SUFFIX= LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h index 76515582..777cd0d3 100644 --- a/include/libxml/xmlerror.h +++ b/include/libxml/xmlerror.h @@ -235,6 +235,8 @@ typedef enum { XML_DTD_UNKNOWN_ID, /* 536 */ XML_DTD_UNKNOWN_NOTATION, /* 537 */ XML_DTD_STANDALONE_DEFAULTED, /* 538 */ + XML_DTD_XMLID_VALUE, /* 539 */ + XML_DTD_XMLID_TYPE, /* 540 */ XML_HTML_STRUCURE_ERROR = 800, XML_HTML_UNKNOWN_TAG, /* 801 */ XML_RNGP_ANYNAME_ATTR_ANCESTOR = 1000, diff --git a/result/xmlid/id_err1.xml b/result/xmlid/id_err1.xml new file mode 100644 index 00000000..2e47afde --- /dev/null +++ b/result/xmlid/id_err1.xml @@ -0,0 +1,2 @@ +Object is a Node Set : +Set contains 0 nodes: diff --git a/result/xmlid/id_err1.xml.err b/result/xmlid/id_err1.xml.err new file mode 100644 index 00000000..9efeb47b --- /dev/null +++ b/result/xmlid/id_err1.xml.err @@ -0,0 +1,3 @@ +./test/xmlid/id_err1.xml:1: validity error : xml:id : attribute value 0bar is not an NCName + + ^ diff --git a/result/xmlid/id_err2.xml b/result/xmlid/id_err2.xml new file mode 100644 index 00000000..33ee896d --- /dev/null +++ b/result/xmlid/id_err2.xml @@ -0,0 +1,6 @@ +Object is a Node Set : +Set contains 1 nodes: +1 ELEMENT foo + ATTRIBUTE id + TEXT + content=bar diff --git a/result/xmlid/id_err2.xml.err b/result/xmlid/id_err2.xml.err new file mode 100644 index 00000000..9e974d46 --- /dev/null +++ b/result/xmlid/id_err2.xml.err @@ -0,0 +1,3 @@ +./test/xmlid/id_err2.xml:3: validity error : xml:id : attribute type should be ID + + ^ diff --git a/test/xmlid/id_err1.xml b/test/xmlid/id_err1.xml new file mode 100644 index 00000000..d8c47cc8 --- /dev/null +++ b/test/xmlid/id_err1.xml @@ -0,0 +1 @@ + diff --git a/test/xmlid/id_err2.xml b/test/xmlid/id_err2.xml new file mode 100644 index 00000000..99010a7c --- /dev/null +++ b/test/xmlid/id_err2.xml @@ -0,0 +1,5 @@ + + +]> + diff --git a/xpath.c b/xpath.c index ccf6c6cd..554350d9 100644 --- a/xpath.c +++ b/xpath.c @@ -6089,18 +6089,23 @@ xmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) { ID = xmlStrndup(ids, cur - ids); if (ID != NULL) { - if (xmlValidateNCName(ID, 1) == 0) { - attr = xmlGetID(doc, ID); - if (attr != NULL) { - if (attr->type == XML_ATTRIBUTE_NODE) - elem = attr->parent; - else if (attr->type == XML_ELEMENT_NODE) - elem = (xmlNodePtr) attr; - else - elem = NULL; - if (elem != NULL) - xmlXPathNodeSetAdd(ret, elem); - } + /* + * We used to check the fact that the value passed + * was an NCName, but this generated much troubles for + * me and Aleksey Sanin, people blatantly violated that + * constaint, like Visa3D spec. + * if (xmlValidateNCName(ID, 1) == 0) + */ + attr = xmlGetID(doc, ID); + if (attr != NULL) { + if (attr->type == XML_ATTRIBUTE_NODE) + elem = attr->parent; + else if (attr->type == XML_ELEMENT_NODE) + elem = (xmlNodePtr) attr; + else + elem = NULL; + if (elem != NULL) + xmlXPathNodeSetAdd(ret, elem); } xmlFree(ID); }