diff --git a/entities.c b/entities.c index aec51441..e8a07212 100644 --- a/entities.c +++ b/entities.c @@ -68,48 +68,6 @@ static xmlEntity xmlEntityApos = { NULL, NULL, NULL, NULL, 0, 0, 0 }; -/** - * xmlEntitiesErrMemory: - * @extra: extra information - * - * Handle an out of memory condition - */ -static void -xmlEntitiesErrMemory(const char *extra) -{ - __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra); -} - -/** - * xmlEntitiesErr: - * @code: the error code - * @msg: the message - * - * Raise an error. - */ -static void LIBXML_ATTR_FORMAT(2,0) -xmlEntitiesErr(xmlParserErrors code, const char *msg) -{ - __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL); -} - -/** - * xmlEntitiesWarn: - * @code: the error code - * @msg: the message - * - * Raise a warning. - */ -static void LIBXML_ATTR_FORMAT(2,0) -xmlEntitiesWarn(xmlParserErrors code, const char *msg, const xmlChar *str1) -{ - __xmlRaiseError(NULL, NULL, NULL, - NULL, NULL, XML_FROM_TREE, code, - XML_ERR_WARNING, NULL, 0, - (const char *)str1, NULL, NULL, 0, 0, - msg, (const char *)str1, NULL); -} - /* * xmlFreeEntity : clean-up an entity record. */ @@ -150,37 +108,43 @@ xmlFreeEntity(xmlEntityPtr entity) * internal routine doing the entity node structures allocations */ static xmlEntityPtr -xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type, +xmlCreateEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntityPtr ret; ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); - if (ret == NULL) { - xmlEntitiesErrMemory("xmlCreateEntity: malloc failed"); + if (ret == NULL) return(NULL); - } memset(ret, 0, sizeof(xmlEntity)); + ret->doc = doc; ret->type = XML_ENTITY_DECL; /* * fill the structure. */ ret->etype = (xmlEntityType) type; - if (dict == NULL) { + if ((doc == NULL) || (doc->dict == NULL)) ret->name = xmlStrdup(name); - if (ExternalID != NULL) - ret->ExternalID = xmlStrdup(ExternalID); - if (SystemID != NULL) - ret->SystemID = xmlStrdup(SystemID); - } else { - ret->name = xmlDictLookup(dict, name, -1); - ret->ExternalID = xmlStrdup(ExternalID); - ret->SystemID = xmlStrdup(SystemID); + else + ret->name = xmlDictLookup(doc->dict, name, -1); + if (ret->name == NULL) + goto error; + if (ExternalID != NULL) { + ret->ExternalID = xmlStrdup(ExternalID); + if (ret->ExternalID == NULL) + goto error; + } + if (SystemID != NULL) { + ret->SystemID = xmlStrdup(SystemID); + if (ret->SystemID == NULL) + goto error; } if (content != NULL) { ret->length = xmlStrlen(content); ret->content = xmlStrndup(content, ret->length); + if (ret->content == NULL) + goto error; } else { ret->length = 0; ret->content = NULL; @@ -191,25 +155,49 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type, ret->owner = 0; return(ret); + +error: + xmlFreeEntity(ret); + return(NULL); } -/* - * xmlAddEntity : register a new entity for an entities table. +/** + * xmlAddEntity: + * @doc: the document + * @extSubset: add to the external or internal subset + * @name: the entity name + * @type: the entity type XML_xxx_yyy_ENTITY + * @ExternalID: the entity external ID if available + * @SystemID: the entity system ID if available + * @content: the entity content + * @out: pointer to resulting entity (optional) + * + * Register a new entity for this document. + * + * Returns an xmlParserErrors error code. */ -static xmlEntityPtr -xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, +int +xmlAddEntity(xmlDocPtr doc, int extSubset, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, - const xmlChar *content) { + const xmlChar *content, xmlEntityPtr *out) { + xmlDtdPtr dtd; xmlDictPtr dict = NULL; xmlEntitiesTablePtr table = NULL; xmlEntityPtr ret, predef; + int res; - if (name == NULL) - return(NULL); + if (out != NULL) + *out = NULL; + if ((doc == NULL) || (name == NULL)) + return(XML_ERR_ARGUMENT); + dict = doc->dict; + + if (extSubset) + dtd = doc->extSubset; + else + dtd = doc->intSubset; if (dtd == NULL) - return(NULL); - if (dtd->doc != NULL) - dict = dtd->doc->dict; + return(XML_DTD_NO_DTD); switch (type) { case XML_INTERNAL_GENERAL_ENTITY: @@ -246,41 +234,59 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, } } } - if (!valid) { - xmlEntitiesWarn(XML_ERR_ENTITY_PROCESSING, - "xmlAddEntity: invalid redeclaration of predefined" - " entity '%s'", name); - return(NULL); - } + if (!valid) + return(XML_ERR_REDECL_PREDEF_ENTITY); } - if (dtd->entities == NULL) + if (dtd->entities == NULL) { dtd->entities = xmlHashCreateDict(0, dict); + if (dtd->entities == NULL) + return(XML_ERR_NO_MEMORY); + } table = dtd->entities; break; case XML_INTERNAL_PARAMETER_ENTITY: case XML_EXTERNAL_PARAMETER_ENTITY: - if (dtd->pentities == NULL) + if (dtd->pentities == NULL) { dtd->pentities = xmlHashCreateDict(0, dict); + if (dtd->pentities == NULL) + return(XML_ERR_NO_MEMORY); + } table = dtd->pentities; break; case XML_INTERNAL_PREDEFINED_ENTITY: - return(NULL); + return(XML_ERR_ARGUMENT); } - if (table == NULL) - return(NULL); - ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content); + ret = xmlCreateEntity(dtd->doc, name, type, ExternalID, SystemID, content); if (ret == NULL) - return(NULL); - ret->doc = dtd->doc; + return(XML_ERR_NO_MEMORY); - if (xmlHashAddEntry(table, name, ret)) { + res = xmlHashAdd(table, name, ret); + if (res < 0) { + xmlFreeEntity(ret); + return(XML_ERR_NO_MEMORY); + } else if (res == 0) { /* * entity was already defined at another level. */ xmlFreeEntity(ret); - return(NULL); + return(XML_WAR_ENTITY_REDEFINED); } - return(ret); + + /* + * Link it to the DTD + */ + ret->parent = dtd; + ret->doc = dtd->doc; + if (dtd->last == NULL) { + dtd->children = dtd->last = (xmlNodePtr) ret; + } else { + dtd->last->next = (xmlNodePtr) ret; + ret->prev = dtd->last; + dtd->last = (xmlNodePtr) ret; + } + + *out = ret; + return(0); } /** @@ -337,34 +343,8 @@ xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntityPtr ret; - xmlDtdPtr dtd; - if (doc == NULL) { - xmlEntitiesErr(XML_DTD_NO_DOC, - "xmlAddDtdEntity: document is NULL"); - return(NULL); - } - if (doc->extSubset == NULL) { - xmlEntitiesErr(XML_DTD_NO_DTD, - "xmlAddDtdEntity: document without external subset"); - return(NULL); - } - dtd = doc->extSubset; - ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); - if (ret == NULL) return(NULL); - - /* - * Link it to the DTD - */ - ret->parent = dtd; - ret->doc = dtd->doc; - if (dtd->last == NULL) { - dtd->children = dtd->last = (xmlNodePtr) ret; - } else { - dtd->last->next = (xmlNodePtr) ret; - ret->prev = dtd->last; - dtd->last = (xmlNodePtr) ret; - } + xmlAddEntity(doc, 1, name, type, ExternalID, SystemID, content, &ret); return(ret); } @@ -386,34 +366,8 @@ xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntityPtr ret; - xmlDtdPtr dtd; - if (doc == NULL) { - xmlEntitiesErr(XML_DTD_NO_DOC, - "xmlAddDocEntity: document is NULL"); - return(NULL); - } - if (doc->intSubset == NULL) { - xmlEntitiesErr(XML_DTD_NO_DTD, - "xmlAddDocEntity: document without internal subset"); - return(NULL); - } - dtd = doc->intSubset; - ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); - if (ret == NULL) return(NULL); - - /* - * Link it to the DTD - */ - ret->parent = dtd; - ret->doc = dtd->doc; - if (dtd->last == NULL) { - dtd->children = dtd->last = (xmlNodePtr) ret; - } else { - dtd->last->next = (xmlNodePtr) ret; - ret->prev = dtd->last; - dtd->last = (xmlNodePtr) ret; - } + xmlAddEntity(doc, 0, name, type, ExternalID, SystemID, content, &ret); return(ret); } @@ -438,21 +392,10 @@ xmlEntityPtr xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { - xmlEntityPtr ret; - xmlDictPtr dict; - if ((doc != NULL) && (doc->intSubset != NULL)) { return(xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content)); } - if (doc != NULL) - dict = doc->dict; - else - dict = NULL; - ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content); - if (ret == NULL) - return(NULL); - ret->doc = doc; - return(ret); + return(xmlCreateEntity(doc, name, type, ExternalID, SystemID, content)); } /** @@ -604,10 +547,8 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) { */ buffer_size = 1000; buffer = (xmlChar *) xmlMalloc(buffer_size); - if (buffer == NULL) { - xmlEntitiesErrMemory("xmlEncodeEntities: malloc failed"); + if (buffer == NULL) return(NULL); - } out = buffer; while (*cur != '\0') { @@ -707,47 +648,12 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) { * cur[3] is 10xxxxxx if cur[0] is 1111xxxx * cur[0] is not 11111xxx */ - char buf[11], *ptr; - int val = 0, l = 1; + char buf[13], *ptr; + int val, l; - if (((cur[0] & 0xC0) != 0xC0) || - ((cur[1] & 0xC0) != 0x80) || - (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) || - (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) || - (((cur[0] & 0xF8) == 0xF8))) { - xmlEntitiesErr(XML_CHECK_NOT_UTF8, - "xmlEncodeEntities: input not UTF-8"); - snprintf(buf, sizeof(buf), "&#%d;", *cur); - buf[sizeof(buf) - 1] = 0; - ptr = buf; - while (*ptr != 0) *out++ = *ptr++; - cur++; - continue; - } else if (*cur < 0xE0) { - val = (cur[0]) & 0x1F; - val <<= 6; - val |= (cur[1]) & 0x3F; - l = 2; - } else if (*cur < 0xF0) { - val = (cur[0]) & 0x0F; - val <<= 6; - val |= (cur[1]) & 0x3F; - val <<= 6; - val |= (cur[2]) & 0x3F; - l = 3; - } else if (*cur < 0xF8) { - val = (cur[0]) & 0x07; - val <<= 6; - val |= (cur[1]) & 0x3F; - val <<= 6; - val |= (cur[2]) & 0x3F; - val <<= 6; - val |= (cur[3]) & 0x3F; - l = 4; - } - if ((l == 1) || (!IS_CHAR(val))) { - xmlEntitiesErr(XML_ERR_INVALID_CHAR, - "xmlEncodeEntities: char out of range\n"); + l = 4; + val = xmlGetUTF8Char(cur, &l); + if ((val < 0) || (!IS_CHAR(val))) { snprintf(buf, sizeof(buf), "&#%d;", *cur); buf[sizeof(buf) - 1] = 0; ptr = buf; @@ -779,7 +685,6 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) { return(buffer); mem_error: - xmlEntitiesErrMemory("xmlEncodeEntities: realloc failed"); xmlFree(buffer); return(NULL); } @@ -840,10 +745,8 @@ xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input) */ buffer_size = 1000; buffer = (xmlChar *) xmlMalloc(buffer_size); - if (buffer == NULL) { - xmlEntitiesErrMemory("xmlEncodeSpecialChars: malloc failed"); + if (buffer == NULL) return(NULL); - } out = buffer; while (*cur != '\0') { @@ -899,7 +802,6 @@ xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input) return(buffer); mem_error: - xmlEntitiesErrMemory("xmlEncodeSpecialChars: realloc failed"); xmlFree(buffer); return(NULL); } @@ -956,27 +858,47 @@ xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { xmlEntityPtr cur; cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); - if (cur == NULL) { - xmlEntitiesErrMemory("xmlCopyEntity:: malloc failed"); + if (cur == NULL) return(NULL); - } memset(cur, 0, sizeof(xmlEntity)); cur->type = XML_ENTITY_DECL; cur->etype = ent->etype; - if (ent->name != NULL) + if (ent->name != NULL) { cur->name = xmlStrdup(ent->name); - if (ent->ExternalID != NULL) + if (cur->name == NULL) + goto error; + } + if (ent->ExternalID != NULL) { cur->ExternalID = xmlStrdup(ent->ExternalID); - if (ent->SystemID != NULL) + if (cur->ExternalID == NULL) + goto error; + } + if (ent->SystemID != NULL) { cur->SystemID = xmlStrdup(ent->SystemID); - if (ent->content != NULL) + if (cur->SystemID == NULL) + goto error; + } + if (ent->content != NULL) { cur->content = xmlStrdup(ent->content); - if (ent->orig != NULL) + if (cur->content == NULL) + goto error; + } + if (ent->orig != NULL) { cur->orig = xmlStrdup(ent->orig); - if (ent->URI != NULL) + if (cur->orig == NULL) + goto error; + } + if (ent->URI != NULL) { cur->URI = xmlStrdup(ent->URI); + if (cur->URI == NULL) + goto error; + } return(cur); + +error: + xmlFreeEntity(cur); + return(NULL); } /** @@ -989,7 +911,7 @@ xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { */ xmlEntitiesTablePtr xmlCopyEntitiesTable(xmlEntitiesTablePtr table) { - return(xmlHashCopy(table, xmlCopyEntity)); + return(xmlHashCopySafe(table, xmlCopyEntity, xmlFreeEntityWrapper)); } #endif /* LIBXML_TREE_ENABLED */ @@ -1116,8 +1038,7 @@ xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) { xmlBufferWriteChar(buf, ">\n"); break; default: - xmlEntitiesErr(XML_DTD_UNKNOWN_ENTITY, - "xmlDumpEntitiesDecl: internal: unknown type entity type"); + break; } } diff --git a/include/libxml/entities.h b/include/libxml/entities.h index 615ead4d..dd9c05a4 100644 --- a/include/libxml/entities.h +++ b/include/libxml/entities.h @@ -87,6 +87,15 @@ XMLPUBFUN xmlEntityPtr const xmlChar *content); XMLPUBFUN void xmlFreeEntity (xmlEntityPtr entity); +XMLPUBFUN int + xmlAddEntity (xmlDocPtr doc, + int extSubset, + const xmlChar *name, + int type, + const xmlChar *ExternalID, + const xmlChar *SystemID, + const xmlChar *content, + xmlEntityPtr *out); XMLPUBFUN xmlEntityPtr xmlAddDocEntity (xmlDocPtr doc, const xmlChar *name, diff --git a/result/errors/ent_redecl.xml.ent b/result/errors/ent_redecl.xml.ent deleted file mode 100644 index 31908b05..00000000 --- a/result/errors/ent_redecl.xml.ent +++ /dev/null @@ -1 +0,0 @@ -warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt' diff --git a/result/errors/ent_redecl.xml.err b/result/errors/ent_redecl.xml.err deleted file mode 100644 index 31908b05..00000000 --- a/result/errors/ent_redecl.xml.err +++ /dev/null @@ -1 +0,0 @@ -warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt' diff --git a/result/errors/ent_redecl.xml.str b/result/errors/ent_redecl.xml.str deleted file mode 100644 index 31908b05..00000000 --- a/result/errors/ent_redecl.xml.str +++ /dev/null @@ -1 +0,0 @@ -warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt'