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