mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-02-05 05:47:00 +03:00
valid: Rework xmlAddID
This commit is contained in:
parent
d57c57ed2f
commit
d0d6174e81
@ -255,11 +255,8 @@ XMLPUBFUN void
|
||||
|
||||
/* IDs */
|
||||
XMLPUBFUN int
|
||||
xmlAddIDSafe (xmlDocPtr doc,
|
||||
const xmlChar *value,
|
||||
xmlAttrPtr attr,
|
||||
int streaming,
|
||||
xmlIDPtr *id);
|
||||
xmlAddIDSafe (xmlAttrPtr attr,
|
||||
const xmlChar *value);
|
||||
XMLPUBFUN xmlIDPtr
|
||||
xmlAddID (xmlValidCtxtPtr ctxt,
|
||||
xmlDocPtr doc,
|
||||
|
9
tree.c
9
tree.c
@ -1817,7 +1817,7 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
|
||||
|
||||
if ((value != NULL) && (node != NULL) &&
|
||||
(xmlIsID(node->doc, node, cur) == 1) &&
|
||||
(xmlAddIDSafe(node->doc, value, cur, 0, NULL) < 0))
|
||||
(xmlAddIDSafe(cur, value) < 0))
|
||||
goto error;
|
||||
|
||||
/*
|
||||
@ -4018,7 +4018,7 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
|
||||
id = xmlNodeListGetString(cur->doc, cur->children, 1);
|
||||
if (id == NULL)
|
||||
goto error;
|
||||
res = xmlAddIDSafe(target->doc, id, ret, 0, NULL);
|
||||
res = xmlAddIDSafe(ret, id);
|
||||
xmlFree(id);
|
||||
if (res < 0)
|
||||
goto error;
|
||||
@ -6911,7 +6911,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
|
||||
}
|
||||
}
|
||||
if ((prop->atype == XML_ATTRIBUTE_ID) &&
|
||||
(xmlAddIDSafe(node->doc, value, prop, 0, NULL) < 0)) {
|
||||
(xmlAddIDSafe(prop, value) < 0)) {
|
||||
return(NULL);
|
||||
}
|
||||
return(prop);
|
||||
@ -9633,8 +9633,7 @@ end_ns_reference:
|
||||
|
||||
idVal = xmlNodeListGetString(cur->doc, cur->children, 1);
|
||||
if (idVal != NULL) {
|
||||
if (xmlAddIDSafe(destDoc, idVal, (xmlAttrPtr) cur, 0,
|
||||
NULL) < 0) {
|
||||
if (xmlAddIDSafe((xmlAttrPtr) cur, idVal) < 0) {
|
||||
/* TODO: error message. */
|
||||
xmlFree(idVal);
|
||||
goto internal_error;
|
||||
|
132
valid.c
132
valid.c
@ -2280,35 +2280,36 @@ xmlFreeID(xmlIDPtr id) {
|
||||
|
||||
|
||||
/**
|
||||
* xmlAddIDSafe:
|
||||
* @doc: pointer to the document
|
||||
* @value: the value name
|
||||
* xmlAddIDInternal:
|
||||
* @attr: the attribute holding the ID
|
||||
* @id: pointer to new xmlIdPtr (optional)
|
||||
* @value: the attribute (ID) value
|
||||
* @idPtr: pointer to resulting ID
|
||||
*
|
||||
* Register a new id declaration
|
||||
*
|
||||
* Returns 1 on success, 0 if the ID already exists, -1 if a memory
|
||||
* allocation fails.
|
||||
*/
|
||||
int
|
||||
xmlAddIDSafe(xmlDocPtr doc, const xmlChar *value, xmlAttrPtr attr,
|
||||
int streaming, xmlIDPtr *id) {
|
||||
xmlIDPtr ret;
|
||||
static int
|
||||
xmlAddIDInternal(xmlAttrPtr attr, const xmlChar *value, xmlIDPtr *idPtr) {
|
||||
xmlDocPtr doc;
|
||||
xmlIDPtr id;
|
||||
xmlIDTablePtr table;
|
||||
int ret;
|
||||
|
||||
if (id != NULL)
|
||||
*id = NULL;
|
||||
|
||||
if (doc == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
if ((value == NULL) || (value[0] == 0)) {
|
||||
if (idPtr != NULL)
|
||||
*idPtr = NULL;
|
||||
if ((value == NULL) || (value[0] == 0))
|
||||
return(0);
|
||||
}
|
||||
if (attr == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
if (attr == NULL)
|
||||
return(0);
|
||||
|
||||
doc = attr->doc;
|
||||
if (doc == NULL)
|
||||
return(0);
|
||||
|
||||
if (attr->id != NULL)
|
||||
xmlRemoveID(doc, attr);
|
||||
|
||||
/*
|
||||
* Create the ID table if needed.
|
||||
@ -2319,69 +2320,63 @@ xmlAddIDSafe(xmlDocPtr doc, const xmlChar *value, xmlAttrPtr attr,
|
||||
if (table == NULL)
|
||||
return(-1);
|
||||
} else {
|
||||
ret = xmlHashLookup(table, value);
|
||||
if (ret != NULL) {
|
||||
/*
|
||||
* Update the attribute unless we are parsing in streaming
|
||||
* mode. If the attribute is copied from an entity we want
|
||||
* the ID reference the copy.
|
||||
*/
|
||||
if (ret->attr != NULL) {
|
||||
ret->attr->id = NULL;
|
||||
ret->attr = attr;
|
||||
attr->id = ret;
|
||||
id = xmlHashLookup(table, value);
|
||||
if (id != NULL) {
|
||||
if (id->attr != NULL) {
|
||||
id->attr->id = NULL;
|
||||
id->attr->atype = 0;
|
||||
}
|
||||
ret->lineno = xmlGetLineNo(attr->parent);
|
||||
attr->atype = XML_ATTRIBUTE_ID;
|
||||
return(0);
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
|
||||
if (ret == NULL)
|
||||
id = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
|
||||
if (id == NULL)
|
||||
return(-1);
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
memset(id, 0, sizeof(*id));
|
||||
|
||||
/*
|
||||
* fill the structure.
|
||||
*/
|
||||
ret->doc = doc;
|
||||
ret->value = xmlStrdup(value);
|
||||
if (ret->value == NULL) {
|
||||
xmlFreeID(ret);
|
||||
id->doc = doc;
|
||||
id->value = xmlStrdup(value);
|
||||
if (id->value == NULL) {
|
||||
xmlFreeID(id);
|
||||
return(-1);
|
||||
}
|
||||
if (streaming) {
|
||||
/*
|
||||
* Operating in streaming mode, attr is gonna disappear
|
||||
*/
|
||||
if (doc->dict != NULL)
|
||||
ret->name = xmlDictLookup(doc->dict, attr->name, -1);
|
||||
else
|
||||
ret->name = xmlStrdup(attr->name);
|
||||
if (ret->name == NULL) {
|
||||
xmlFreeID(ret);
|
||||
return(-1);
|
||||
}
|
||||
ret->attr = NULL;
|
||||
} else {
|
||||
ret->attr = attr;
|
||||
ret->name = NULL;
|
||||
}
|
||||
ret->lineno = xmlGetLineNo(attr->parent);
|
||||
|
||||
if (xmlHashAddEntry(table, value, ret) < 0) {
|
||||
xmlFreeID(ret);
|
||||
if (xmlHashAddEntry(table, value, id) < 0) {
|
||||
xmlFreeID(id);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
attr->atype = XML_ATTRIBUTE_ID;
|
||||
if (!streaming)
|
||||
attr->id = ret;
|
||||
ret = 1;
|
||||
if (idPtr != NULL)
|
||||
*idPtr = id;
|
||||
|
||||
if (id != NULL)
|
||||
*id = ret;
|
||||
return(1);
|
||||
done:
|
||||
id->attr = attr;
|
||||
id->lineno = xmlGetLineNo(attr->parent);
|
||||
attr->atype = XML_ATTRIBUTE_ID;
|
||||
attr->id = id;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlAddIDSafe:
|
||||
* @attr: the attribute holding the ID
|
||||
* @value: the attribute (ID) value
|
||||
*
|
||||
* Register a new id declaration
|
||||
*
|
||||
* Returns 1 on success, 0 if the ID already exists, -1 if a memory
|
||||
* allocation fails.
|
||||
*/
|
||||
int
|
||||
xmlAddIDSafe(xmlAttrPtr attr, const xmlChar *value) {
|
||||
return(xmlAddIDInternal(attr, value, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2401,7 +2396,10 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
|
||||
xmlIDPtr id;
|
||||
int res;
|
||||
|
||||
res = xmlAddIDSafe(doc, value, attr, xmlIsStreaming(ctxt), &id);
|
||||
if ((attr == NULL) || (doc != attr->doc))
|
||||
return(NULL);
|
||||
|
||||
res = xmlAddIDInternal(attr, value, &id);
|
||||
if (res < 0) {
|
||||
xmlVErrMemory(ctxt);
|
||||
}
|
||||
|
12
xmlreader.c
12
xmlreader.c
@ -222,7 +222,17 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
||||
if (cur->children != NULL)
|
||||
xmlTextReaderFreeNodeList(reader, cur->children);
|
||||
|
||||
DICT_FREE(cur->name);
|
||||
if (cur->id != NULL) {
|
||||
/*
|
||||
* Operating in streaming mode, attr is gonna disappear
|
||||
*/
|
||||
cur->id->attr = NULL;
|
||||
cur->id->name = cur->name;
|
||||
cur->name = NULL;
|
||||
} else {
|
||||
DICT_FREE(cur->name);
|
||||
}
|
||||
|
||||
if ((reader != NULL) && (reader->ctxt != NULL) &&
|
||||
(reader->ctxt->freeAttrsNr < MAX_FREE_NODES)) {
|
||||
cur->next = reader->ctxt->freeAttrs;
|
||||
|
11
xmlschemas.c
11
xmlschemas.c
@ -5898,8 +5898,8 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
|
||||
* NOTE: the IDness might have already be declared in the DTD
|
||||
*/
|
||||
if (attr->atype != XML_ATTRIBUTE_ID) {
|
||||
xmlIDPtr res;
|
||||
xmlChar *strip;
|
||||
int res;
|
||||
|
||||
/*
|
||||
* TODO: Use xmlSchemaStrip here; it's not exported at this
|
||||
@ -5910,8 +5910,10 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
|
||||
xmlFree((xmlChar *) value);
|
||||
value = strip;
|
||||
}
|
||||
res = xmlAddID(NULL, attr->doc, value, attr);
|
||||
if (res == NULL) {
|
||||
res = xmlAddIDSafe(attr, value);
|
||||
if (res < 0) {
|
||||
xmlSchemaPErrMemory(ctxt);
|
||||
} else if (res == 0) {
|
||||
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
|
||||
xmlSchemaPSimpleTypeErr(ctxt,
|
||||
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
|
||||
@ -5919,8 +5921,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
|
||||
xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
|
||||
NULL, NULL, "Duplicate value '%s' of simple "
|
||||
"type 'xs:ID'", value, NULL);
|
||||
} else
|
||||
attr->atype = XML_ATTRIBUTE_ID;
|
||||
}
|
||||
}
|
||||
} else if (ret > 0) {
|
||||
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
|
||||
|
@ -2964,19 +2964,19 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
|
||||
* NOTE: the IDness might have already be declared in the DTD
|
||||
*/
|
||||
if (attr->atype != XML_ATTRIBUTE_ID) {
|
||||
xmlIDPtr res;
|
||||
xmlChar *strip;
|
||||
int res;
|
||||
|
||||
strip = xmlSchemaStrip(value);
|
||||
if (strip != NULL) {
|
||||
res = xmlAddID(NULL, node->doc, strip, attr);
|
||||
res = xmlAddIDSafe(attr, strip);
|
||||
xmlFree(strip);
|
||||
} else
|
||||
res = xmlAddID(NULL, node->doc, value, attr);
|
||||
if (res == NULL) {
|
||||
res = xmlAddIDSafe(attr, value);
|
||||
if (res < 0) {
|
||||
goto error;
|
||||
} else if (res == 0) {
|
||||
ret = 2;
|
||||
} else {
|
||||
attr->atype = XML_ATTRIBUTE_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user