mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00
Simplify control flow in xmlParseStartTag2
Remove some goto labels and deduplicate a bit of code after handling namespaces. Before: loop { parseAttribute if (ok) { if (defaultNamespace) { handleDefaultNamespace if (error) goto skip_default_ns; handleDefaultNamespace skip_default_ns: freeAttr nextAttr continue; } if (namespace) { handleNamespace if (error) goto skip_ns; handleNamespace skip_ns: freeAttr nextAttr; continue; } handleAttr } else { freeAttr } nextAttr } After: loop { parseAttribute if (!ok) goto next_attr; if (defaultNamespace) { handleDefaultNamespace if (error) goto next_attr; handleDefaultNamespace } else if (namespace) { handleNamespace if (error) goto next_attr; handleNamespace } else { handleAttr } next_attr: freeAttr nextAttr }
This commit is contained in:
parent
ac9a4560ee
commit
07b7428b69
328
parser.c
328
parser.c
@ -9454,191 +9454,161 @@ reparse:
|
||||
attvalue = NULL;
|
||||
goto base_changed;
|
||||
}
|
||||
if ((attname != NULL) && (attvalue != NULL)) {
|
||||
if (len < 0) len = xmlStrlen(attvalue);
|
||||
if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
|
||||
const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
|
||||
xmlURIPtr uri;
|
||||
if ((attname == NULL) || (attvalue == NULL))
|
||||
goto next_attr;
|
||||
if (len < 0) len = xmlStrlen(attvalue);
|
||||
|
||||
if (URL == NULL) {
|
||||
xmlErrMemory(ctxt, "dictionary allocation failure");
|
||||
if ((attvalue != NULL) && (alloc != 0))
|
||||
xmlFree(attvalue);
|
||||
return(NULL);
|
||||
}
|
||||
if (*URL != 0) {
|
||||
uri = xmlParseURI((const char *) URL);
|
||||
if (uri == NULL) {
|
||||
xmlNsErr(ctxt, XML_WAR_NS_URI,
|
||||
"xmlns: '%s' is not a valid URI\n",
|
||||
URL, NULL, NULL);
|
||||
} else {
|
||||
if (uri->scheme == NULL) {
|
||||
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
|
||||
"xmlns: URI %s is not absolute\n",
|
||||
URL, NULL, NULL);
|
||||
}
|
||||
xmlFreeURI(uri);
|
||||
}
|
||||
if (URL == ctxt->str_xml_ns) {
|
||||
if (attname != ctxt->str_xml) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace URI cannot be the default namespace\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
goto skip_default_ns;
|
||||
}
|
||||
if ((len == 29) &&
|
||||
(xmlStrEqual(URL,
|
||||
BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"reuse of the xmlns namespace name is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto skip_default_ns;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* check that it's not a defined namespace
|
||||
*/
|
||||
for (j = 1;j <= nbNs;j++)
|
||||
if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
|
||||
break;
|
||||
if (j <= nbNs)
|
||||
xmlErrAttributeDup(ctxt, NULL, attname);
|
||||
else
|
||||
if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
|
||||
skip_default_ns:
|
||||
if ((attvalue != NULL) && (alloc != 0)) {
|
||||
xmlFree(attvalue);
|
||||
attvalue = NULL;
|
||||
}
|
||||
if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
|
||||
break;
|
||||
if (!IS_BLANK_CH(RAW)) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
||||
"attributes construct error\n");
|
||||
break;
|
||||
}
|
||||
SKIP_BLANKS;
|
||||
if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
|
||||
goto base_changed;
|
||||
continue;
|
||||
}
|
||||
if (aprefix == ctxt->str_xmlns) {
|
||||
const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
|
||||
xmlURIPtr uri;
|
||||
if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
|
||||
const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
|
||||
xmlURIPtr uri;
|
||||
|
||||
if (attname == ctxt->str_xml) {
|
||||
if (URL != ctxt->str_xml_ns) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace prefix mapped to wrong URI\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
/*
|
||||
* Do not keep a namespace definition node
|
||||
*/
|
||||
goto skip_ns;
|
||||
}
|
||||
if (URL == NULL) {
|
||||
xmlErrMemory(ctxt, "dictionary allocation failure");
|
||||
if ((attvalue != NULL) && (alloc != 0))
|
||||
xmlFree(attvalue);
|
||||
return(NULL);
|
||||
}
|
||||
if (*URL != 0) {
|
||||
uri = xmlParseURI((const char *) URL);
|
||||
if (uri == NULL) {
|
||||
xmlNsErr(ctxt, XML_WAR_NS_URI,
|
||||
"xmlns: '%s' is not a valid URI\n",
|
||||
URL, NULL, NULL);
|
||||
} else {
|
||||
if (uri->scheme == NULL) {
|
||||
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
|
||||
"xmlns: URI %s is not absolute\n",
|
||||
URL, NULL, NULL);
|
||||
}
|
||||
xmlFreeURI(uri);
|
||||
}
|
||||
if (URL == ctxt->str_xml_ns) {
|
||||
if (attname != ctxt->str_xml) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace URI mapped to wrong prefix\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
goto skip_ns;
|
||||
}
|
||||
if (attname == ctxt->str_xmlns) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"redefinition of the xmlns prefix is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto skip_ns;
|
||||
}
|
||||
if ((len == 29) &&
|
||||
(xmlStrEqual(URL,
|
||||
BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"reuse of the xmlns namespace name is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto skip_ns;
|
||||
}
|
||||
if ((URL == NULL) || (URL[0] == 0)) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xmlns:%s: Empty XML namespace is not allowed\n",
|
||||
attname, NULL, NULL);
|
||||
goto skip_ns;
|
||||
} else {
|
||||
uri = xmlParseURI((const char *) URL);
|
||||
if (uri == NULL) {
|
||||
xmlNsErr(ctxt, XML_WAR_NS_URI,
|
||||
"xmlns:%s: '%s' is not a valid URI\n",
|
||||
attname, URL, NULL);
|
||||
} else {
|
||||
if ((ctxt->pedantic) && (uri->scheme == NULL)) {
|
||||
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
|
||||
"xmlns:%s: URI %s is not absolute\n",
|
||||
attname, URL, NULL);
|
||||
}
|
||||
xmlFreeURI(uri);
|
||||
}
|
||||
}
|
||||
if (attname != ctxt->str_xml) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace URI cannot be the default namespace\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
goto next_attr;
|
||||
}
|
||||
if ((len == 29) &&
|
||||
(xmlStrEqual(URL,
|
||||
BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"reuse of the xmlns namespace name is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto next_attr;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* check that it's not a defined namespace
|
||||
*/
|
||||
for (j = 1;j <= nbNs;j++)
|
||||
if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
|
||||
break;
|
||||
if (j <= nbNs)
|
||||
xmlErrAttributeDup(ctxt, NULL, attname);
|
||||
else
|
||||
if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
|
||||
|
||||
/*
|
||||
* check that it's not a defined namespace
|
||||
*/
|
||||
for (j = 1;j <= nbNs;j++)
|
||||
if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
|
||||
break;
|
||||
if (j <= nbNs)
|
||||
xmlErrAttributeDup(ctxt, aprefix, attname);
|
||||
else
|
||||
if (nsPush(ctxt, attname, URL) > 0) nbNs++;
|
||||
skip_ns:
|
||||
if ((attvalue != NULL) && (alloc != 0)) {
|
||||
xmlFree(attvalue);
|
||||
attvalue = NULL;
|
||||
}
|
||||
if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
|
||||
break;
|
||||
if (!IS_BLANK_CH(RAW)) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
||||
"attributes construct error\n");
|
||||
break;
|
||||
}
|
||||
SKIP_BLANKS;
|
||||
if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
|
||||
goto base_changed;
|
||||
continue;
|
||||
}
|
||||
} else if (aprefix == ctxt->str_xmlns) {
|
||||
const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
|
||||
xmlURIPtr uri;
|
||||
|
||||
/*
|
||||
* Add the pair to atts
|
||||
*/
|
||||
if ((atts == NULL) || (nbatts + 5 > maxatts)) {
|
||||
if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
|
||||
if (attvalue[len] == 0)
|
||||
xmlFree(attvalue);
|
||||
goto failed;
|
||||
}
|
||||
maxatts = ctxt->maxatts;
|
||||
atts = ctxt->atts;
|
||||
}
|
||||
ctxt->attallocs[nratts++] = alloc;
|
||||
atts[nbatts++] = attname;
|
||||
atts[nbatts++] = aprefix;
|
||||
atts[nbatts++] = NULL; /* the URI will be fetched later */
|
||||
atts[nbatts++] = attvalue;
|
||||
attvalue += len;
|
||||
atts[nbatts++] = attvalue;
|
||||
/*
|
||||
* tag if some deallocation is needed
|
||||
*/
|
||||
if (alloc != 0) attval = 1;
|
||||
} else {
|
||||
if ((attvalue != NULL) && (attvalue[len] == 0))
|
||||
xmlFree(attvalue);
|
||||
}
|
||||
if (attname == ctxt->str_xml) {
|
||||
if (URL != ctxt->str_xml_ns) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace prefix mapped to wrong URI\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
/*
|
||||
* Do not keep a namespace definition node
|
||||
*/
|
||||
goto next_attr;
|
||||
}
|
||||
if (URL == ctxt->str_xml_ns) {
|
||||
if (attname != ctxt->str_xml) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xml namespace URI mapped to wrong prefix\n",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
goto next_attr;
|
||||
}
|
||||
if (attname == ctxt->str_xmlns) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"redefinition of the xmlns prefix is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto next_attr;
|
||||
}
|
||||
if ((len == 29) &&
|
||||
(xmlStrEqual(URL,
|
||||
BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"reuse of the xmlns namespace name is forbidden\n",
|
||||
NULL, NULL, NULL);
|
||||
goto next_attr;
|
||||
}
|
||||
if ((URL == NULL) || (URL[0] == 0)) {
|
||||
xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
|
||||
"xmlns:%s: Empty XML namespace is not allowed\n",
|
||||
attname, NULL, NULL);
|
||||
goto next_attr;
|
||||
} else {
|
||||
uri = xmlParseURI((const char *) URL);
|
||||
if (uri == NULL) {
|
||||
xmlNsErr(ctxt, XML_WAR_NS_URI,
|
||||
"xmlns:%s: '%s' is not a valid URI\n",
|
||||
attname, URL, NULL);
|
||||
} else {
|
||||
if ((ctxt->pedantic) && (uri->scheme == NULL)) {
|
||||
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
|
||||
"xmlns:%s: URI %s is not absolute\n",
|
||||
attname, URL, NULL);
|
||||
}
|
||||
xmlFreeURI(uri);
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
/*
|
||||
* check that it's not a defined namespace
|
||||
*/
|
||||
for (j = 1;j <= nbNs;j++)
|
||||
if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
|
||||
break;
|
||||
if (j <= nbNs)
|
||||
xmlErrAttributeDup(ctxt, aprefix, attname);
|
||||
else
|
||||
if (nsPush(ctxt, attname, URL) > 0) nbNs++;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Add the pair to atts
|
||||
*/
|
||||
if ((atts == NULL) || (nbatts + 5 > maxatts)) {
|
||||
if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
|
||||
goto next_attr;
|
||||
}
|
||||
maxatts = ctxt->maxatts;
|
||||
atts = ctxt->atts;
|
||||
}
|
||||
ctxt->attallocs[nratts++] = alloc;
|
||||
atts[nbatts++] = attname;
|
||||
atts[nbatts++] = aprefix;
|
||||
atts[nbatts++] = NULL; /* the URI will be fetched later */
|
||||
atts[nbatts++] = attvalue;
|
||||
attvalue += len;
|
||||
atts[nbatts++] = attvalue;
|
||||
/*
|
||||
* tag if some deallocation is needed
|
||||
*/
|
||||
if (alloc != 0) attval = 1;
|
||||
attvalue = NULL; /* moved into atts */
|
||||
}
|
||||
|
||||
next_attr:
|
||||
if ((attvalue != NULL) && (alloc != 0)) {
|
||||
xmlFree(attvalue);
|
||||
attvalue = NULL;
|
||||
}
|
||||
|
||||
GROW
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
|
Loading…
x
Reference in New Issue
Block a user