xref: /aosp_15_r20/external/cronet/third_party/libxml/src/entities.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker  * entities.c : implementation for the XML entities handling
3*6777b538SAndroid Build Coastguard Worker  *
4*6777b538SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
5*6777b538SAndroid Build Coastguard Worker  *
6*6777b538SAndroid Build Coastguard Worker  * [email protected]
7*6777b538SAndroid Build Coastguard Worker  */
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker /* To avoid EBCDIC trouble when parsing on zOS */
10*6777b538SAndroid Build Coastguard Worker #if defined(__MVS__)
11*6777b538SAndroid Build Coastguard Worker #pragma convert("ISO8859-1")
12*6777b538SAndroid Build Coastguard Worker #endif
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #define IN_LIBXML
15*6777b538SAndroid Build Coastguard Worker #include "libxml.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include <string.h>
18*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
21*6777b538SAndroid Build Coastguard Worker #include <libxml/hash.h>
22*6777b538SAndroid Build Coastguard Worker #include <libxml/entities.h>
23*6777b538SAndroid Build Coastguard Worker #include <libxml/parser.h>
24*6777b538SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
25*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
26*6777b538SAndroid Build Coastguard Worker #include <libxml/dict.h>
27*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlsave.h>
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #include "private/entities.h"
30*6777b538SAndroid Build Coastguard Worker #include "private/error.h"
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker /*
33*6777b538SAndroid Build Coastguard Worker  * The XML predefined entities.
34*6777b538SAndroid Build Coastguard Worker  */
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker static xmlEntity xmlEntityLt = {
37*6777b538SAndroid Build Coastguard Worker     NULL, XML_ENTITY_DECL, BAD_CAST "lt",
38*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, NULL, NULL,
39*6777b538SAndroid Build Coastguard Worker     BAD_CAST "<", BAD_CAST "<", 1,
40*6777b538SAndroid Build Coastguard Worker     XML_INTERNAL_PREDEFINED_ENTITY,
41*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, 0, 0, 0
42*6777b538SAndroid Build Coastguard Worker };
43*6777b538SAndroid Build Coastguard Worker static xmlEntity xmlEntityGt = {
44*6777b538SAndroid Build Coastguard Worker     NULL, XML_ENTITY_DECL, BAD_CAST "gt",
45*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, NULL, NULL,
46*6777b538SAndroid Build Coastguard Worker     BAD_CAST ">", BAD_CAST ">", 1,
47*6777b538SAndroid Build Coastguard Worker     XML_INTERNAL_PREDEFINED_ENTITY,
48*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, 0, 0, 0
49*6777b538SAndroid Build Coastguard Worker };
50*6777b538SAndroid Build Coastguard Worker static xmlEntity xmlEntityAmp = {
51*6777b538SAndroid Build Coastguard Worker     NULL, XML_ENTITY_DECL, BAD_CAST "amp",
52*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, NULL, NULL,
53*6777b538SAndroid Build Coastguard Worker     BAD_CAST "&", BAD_CAST "&", 1,
54*6777b538SAndroid Build Coastguard Worker     XML_INTERNAL_PREDEFINED_ENTITY,
55*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, 0, 0, 0
56*6777b538SAndroid Build Coastguard Worker };
57*6777b538SAndroid Build Coastguard Worker static xmlEntity xmlEntityQuot = {
58*6777b538SAndroid Build Coastguard Worker     NULL, XML_ENTITY_DECL, BAD_CAST "quot",
59*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, NULL, NULL,
60*6777b538SAndroid Build Coastguard Worker     BAD_CAST "\"", BAD_CAST "\"", 1,
61*6777b538SAndroid Build Coastguard Worker     XML_INTERNAL_PREDEFINED_ENTITY,
62*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, 0, 0, 0
63*6777b538SAndroid Build Coastguard Worker };
64*6777b538SAndroid Build Coastguard Worker static xmlEntity xmlEntityApos = {
65*6777b538SAndroid Build Coastguard Worker     NULL, XML_ENTITY_DECL, BAD_CAST "apos",
66*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, NULL, NULL,
67*6777b538SAndroid Build Coastguard Worker     BAD_CAST "'", BAD_CAST "'", 1,
68*6777b538SAndroid Build Coastguard Worker     XML_INTERNAL_PREDEFINED_ENTITY,
69*6777b538SAndroid Build Coastguard Worker     NULL, NULL, NULL, NULL, 0, 0, 0
70*6777b538SAndroid Build Coastguard Worker };
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker /*
73*6777b538SAndroid Build Coastguard Worker  * xmlFreeEntity : clean-up an entity record.
74*6777b538SAndroid Build Coastguard Worker  */
75*6777b538SAndroid Build Coastguard Worker void
xmlFreeEntity(xmlEntityPtr entity)76*6777b538SAndroid Build Coastguard Worker xmlFreeEntity(xmlEntityPtr entity)
77*6777b538SAndroid Build Coastguard Worker {
78*6777b538SAndroid Build Coastguard Worker     xmlDictPtr dict = NULL;
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker     if (entity == NULL)
81*6777b538SAndroid Build Coastguard Worker         return;
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker     if (entity->doc != NULL)
84*6777b538SAndroid Build Coastguard Worker         dict = entity->doc->dict;
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker     if ((entity->children) &&
88*6777b538SAndroid Build Coastguard Worker         (entity == (xmlEntityPtr) entity->children->parent))
89*6777b538SAndroid Build Coastguard Worker         xmlFreeNodeList(entity->children);
90*6777b538SAndroid Build Coastguard Worker     if ((entity->name != NULL) &&
91*6777b538SAndroid Build Coastguard Worker         ((dict == NULL) || (!xmlDictOwns(dict, entity->name))))
92*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->name);
93*6777b538SAndroid Build Coastguard Worker     if (entity->ExternalID != NULL)
94*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->ExternalID);
95*6777b538SAndroid Build Coastguard Worker     if (entity->SystemID != NULL)
96*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->SystemID);
97*6777b538SAndroid Build Coastguard Worker     if (entity->URI != NULL)
98*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->URI);
99*6777b538SAndroid Build Coastguard Worker     if (entity->content != NULL)
100*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->content);
101*6777b538SAndroid Build Coastguard Worker     if (entity->orig != NULL)
102*6777b538SAndroid Build Coastguard Worker         xmlFree((char *) entity->orig);
103*6777b538SAndroid Build Coastguard Worker     xmlFree(entity);
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker /*
107*6777b538SAndroid Build Coastguard Worker  * xmlCreateEntity:
108*6777b538SAndroid Build Coastguard Worker  *
109*6777b538SAndroid Build Coastguard Worker  * internal routine doing the entity node structures allocations
110*6777b538SAndroid Build Coastguard Worker  */
111*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr
xmlCreateEntity(xmlDocPtr doc,const xmlChar * name,int type,const xmlChar * ExternalID,const xmlChar * SystemID,const xmlChar * content)112*6777b538SAndroid Build Coastguard Worker xmlCreateEntity(xmlDocPtr doc, const xmlChar *name, int type,
113*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *ExternalID, const xmlChar *SystemID,
114*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *content) {
115*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ret;
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker     ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
118*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
119*6777b538SAndroid Build Coastguard Worker 	return(NULL);
120*6777b538SAndroid Build Coastguard Worker     memset(ret, 0, sizeof(xmlEntity));
121*6777b538SAndroid Build Coastguard Worker     ret->doc = doc;
122*6777b538SAndroid Build Coastguard Worker     ret->type = XML_ENTITY_DECL;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker     /*
125*6777b538SAndroid Build Coastguard Worker      * fill the structure.
126*6777b538SAndroid Build Coastguard Worker      */
127*6777b538SAndroid Build Coastguard Worker     ret->etype = (xmlEntityType) type;
128*6777b538SAndroid Build Coastguard Worker     if ((doc == NULL) || (doc->dict == NULL))
129*6777b538SAndroid Build Coastguard Worker 	ret->name = xmlStrdup(name);
130*6777b538SAndroid Build Coastguard Worker     else
131*6777b538SAndroid Build Coastguard Worker         ret->name = xmlDictLookup(doc->dict, name, -1);
132*6777b538SAndroid Build Coastguard Worker     if (ret->name == NULL)
133*6777b538SAndroid Build Coastguard Worker         goto error;
134*6777b538SAndroid Build Coastguard Worker     if (ExternalID != NULL) {
135*6777b538SAndroid Build Coastguard Worker         ret->ExternalID = xmlStrdup(ExternalID);
136*6777b538SAndroid Build Coastguard Worker         if (ret->ExternalID == NULL)
137*6777b538SAndroid Build Coastguard Worker             goto error;
138*6777b538SAndroid Build Coastguard Worker     }
139*6777b538SAndroid Build Coastguard Worker     if (SystemID != NULL) {
140*6777b538SAndroid Build Coastguard Worker         ret->SystemID = xmlStrdup(SystemID);
141*6777b538SAndroid Build Coastguard Worker         if (ret->SystemID == NULL)
142*6777b538SAndroid Build Coastguard Worker             goto error;
143*6777b538SAndroid Build Coastguard Worker     }
144*6777b538SAndroid Build Coastguard Worker     if (content != NULL) {
145*6777b538SAndroid Build Coastguard Worker         ret->length = xmlStrlen(content);
146*6777b538SAndroid Build Coastguard Worker 	ret->content = xmlStrndup(content, ret->length);
147*6777b538SAndroid Build Coastguard Worker         if (ret->content == NULL)
148*6777b538SAndroid Build Coastguard Worker             goto error;
149*6777b538SAndroid Build Coastguard Worker      } else {
150*6777b538SAndroid Build Coastguard Worker         ret->length = 0;
151*6777b538SAndroid Build Coastguard Worker         ret->content = NULL;
152*6777b538SAndroid Build Coastguard Worker     }
153*6777b538SAndroid Build Coastguard Worker     ret->URI = NULL; /* to be computed by the layer knowing
154*6777b538SAndroid Build Coastguard Worker 			the defining entity */
155*6777b538SAndroid Build Coastguard Worker     ret->orig = NULL;
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker     return(ret);
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker error:
160*6777b538SAndroid Build Coastguard Worker     xmlFreeEntity(ret);
161*6777b538SAndroid Build Coastguard Worker     return(NULL);
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker 
164*6777b538SAndroid Build Coastguard Worker /**
165*6777b538SAndroid Build Coastguard Worker  * xmlAddEntity:
166*6777b538SAndroid Build Coastguard Worker  * @doc:  the document
167*6777b538SAndroid Build Coastguard Worker  * @extSubset:  add to the external or internal subset
168*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
169*6777b538SAndroid Build Coastguard Worker  * @type:  the entity type XML_xxx_yyy_ENTITY
170*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the entity external ID if available
171*6777b538SAndroid Build Coastguard Worker  * @SystemID:  the entity system ID if available
172*6777b538SAndroid Build Coastguard Worker  * @content:  the entity content
173*6777b538SAndroid Build Coastguard Worker  * @out:  pointer to resulting entity (optional)
174*6777b538SAndroid Build Coastguard Worker  *
175*6777b538SAndroid Build Coastguard Worker  * Register a new entity for this document.
176*6777b538SAndroid Build Coastguard Worker  *
177*6777b538SAndroid Build Coastguard Worker  * Returns an xmlParserErrors error code.
178*6777b538SAndroid Build Coastguard Worker  */
179*6777b538SAndroid Build Coastguard Worker int
xmlAddEntity(xmlDocPtr doc,int extSubset,const xmlChar * name,int type,const xmlChar * ExternalID,const xmlChar * SystemID,const xmlChar * content,xmlEntityPtr * out)180*6777b538SAndroid Build Coastguard Worker xmlAddEntity(xmlDocPtr doc, int extSubset, const xmlChar *name, int type,
181*6777b538SAndroid Build Coastguard Worker 	  const xmlChar *ExternalID, const xmlChar *SystemID,
182*6777b538SAndroid Build Coastguard Worker 	  const xmlChar *content, xmlEntityPtr *out) {
183*6777b538SAndroid Build Coastguard Worker     xmlDtdPtr dtd;
184*6777b538SAndroid Build Coastguard Worker     xmlDictPtr dict = NULL;
185*6777b538SAndroid Build Coastguard Worker     xmlEntitiesTablePtr table = NULL;
186*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ret, predef;
187*6777b538SAndroid Build Coastguard Worker     int res;
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker     if (out != NULL)
190*6777b538SAndroid Build Coastguard Worker         *out = NULL;
191*6777b538SAndroid Build Coastguard Worker     if ((doc == NULL) || (name == NULL))
192*6777b538SAndroid Build Coastguard Worker 	return(XML_ERR_ARGUMENT);
193*6777b538SAndroid Build Coastguard Worker     dict = doc->dict;
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker     if (extSubset)
196*6777b538SAndroid Build Coastguard Worker         dtd = doc->extSubset;
197*6777b538SAndroid Build Coastguard Worker     else
198*6777b538SAndroid Build Coastguard Worker         dtd = doc->intSubset;
199*6777b538SAndroid Build Coastguard Worker     if (dtd == NULL)
200*6777b538SAndroid Build Coastguard Worker         return(XML_DTD_NO_DTD);
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker     switch (type) {
203*6777b538SAndroid Build Coastguard Worker         case XML_INTERNAL_GENERAL_ENTITY:
204*6777b538SAndroid Build Coastguard Worker         case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
205*6777b538SAndroid Build Coastguard Worker         case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
206*6777b538SAndroid Build Coastguard Worker             predef = xmlGetPredefinedEntity(name);
207*6777b538SAndroid Build Coastguard Worker             if (predef != NULL) {
208*6777b538SAndroid Build Coastguard Worker                 int valid = 0;
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker                 /* 4.6 Predefined Entities */
211*6777b538SAndroid Build Coastguard Worker                 if ((type == XML_INTERNAL_GENERAL_ENTITY) &&
212*6777b538SAndroid Build Coastguard Worker                     (content != NULL)) {
213*6777b538SAndroid Build Coastguard Worker                     int c = predef->content[0];
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker                     if (((content[0] == c) && (content[1] == 0)) &&
216*6777b538SAndroid Build Coastguard Worker                         ((c == '>') || (c == '\'') || (c == '"'))) {
217*6777b538SAndroid Build Coastguard Worker                         valid = 1;
218*6777b538SAndroid Build Coastguard Worker                     } else if ((content[0] == '&') && (content[1] == '#')) {
219*6777b538SAndroid Build Coastguard Worker                         if (content[2] == 'x') {
220*6777b538SAndroid Build Coastguard Worker                             xmlChar *hex = BAD_CAST "0123456789ABCDEF";
221*6777b538SAndroid Build Coastguard Worker                             xmlChar ref[] = "00;";
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker                             ref[0] = hex[c / 16 % 16];
224*6777b538SAndroid Build Coastguard Worker                             ref[1] = hex[c % 16];
225*6777b538SAndroid Build Coastguard Worker                             if (xmlStrcasecmp(&content[3], ref) == 0)
226*6777b538SAndroid Build Coastguard Worker                                 valid = 1;
227*6777b538SAndroid Build Coastguard Worker                         } else {
228*6777b538SAndroid Build Coastguard Worker                             xmlChar ref[] = "00;";
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker                             ref[0] = '0' + c / 10 % 10;
231*6777b538SAndroid Build Coastguard Worker                             ref[1] = '0' + c % 10;
232*6777b538SAndroid Build Coastguard Worker                             if (xmlStrEqual(&content[2], ref))
233*6777b538SAndroid Build Coastguard Worker                                 valid = 1;
234*6777b538SAndroid Build Coastguard Worker                         }
235*6777b538SAndroid Build Coastguard Worker                     }
236*6777b538SAndroid Build Coastguard Worker                 }
237*6777b538SAndroid Build Coastguard Worker                 if (!valid)
238*6777b538SAndroid Build Coastguard Worker                     return(XML_ERR_REDECL_PREDEF_ENTITY);
239*6777b538SAndroid Build Coastguard Worker             }
240*6777b538SAndroid Build Coastguard Worker 	    if (dtd->entities == NULL) {
241*6777b538SAndroid Build Coastguard Worker 		dtd->entities = xmlHashCreateDict(0, dict);
242*6777b538SAndroid Build Coastguard Worker                 if (dtd->entities == NULL)
243*6777b538SAndroid Build Coastguard Worker                     return(XML_ERR_NO_MEMORY);
244*6777b538SAndroid Build Coastguard Worker             }
245*6777b538SAndroid Build Coastguard Worker 	    table = dtd->entities;
246*6777b538SAndroid Build Coastguard Worker 	    break;
247*6777b538SAndroid Build Coastguard Worker         case XML_INTERNAL_PARAMETER_ENTITY:
248*6777b538SAndroid Build Coastguard Worker         case XML_EXTERNAL_PARAMETER_ENTITY:
249*6777b538SAndroid Build Coastguard Worker 	    if (dtd->pentities == NULL) {
250*6777b538SAndroid Build Coastguard Worker 		dtd->pentities = xmlHashCreateDict(0, dict);
251*6777b538SAndroid Build Coastguard Worker                 if (dtd->pentities == NULL)
252*6777b538SAndroid Build Coastguard Worker                     return(XML_ERR_NO_MEMORY);
253*6777b538SAndroid Build Coastguard Worker             }
254*6777b538SAndroid Build Coastguard Worker 	    table = dtd->pentities;
255*6777b538SAndroid Build Coastguard Worker 	    break;
256*6777b538SAndroid Build Coastguard Worker         case XML_INTERNAL_PREDEFINED_ENTITY:
257*6777b538SAndroid Build Coastguard Worker 	    return(XML_ERR_ARGUMENT);
258*6777b538SAndroid Build Coastguard Worker     }
259*6777b538SAndroid Build Coastguard Worker     ret = xmlCreateEntity(dtd->doc, name, type, ExternalID, SystemID, content);
260*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
261*6777b538SAndroid Build Coastguard Worker         return(XML_ERR_NO_MEMORY);
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker     res = xmlHashAdd(table, name, ret);
264*6777b538SAndroid Build Coastguard Worker     if (res < 0) {
265*6777b538SAndroid Build Coastguard Worker         xmlFreeEntity(ret);
266*6777b538SAndroid Build Coastguard Worker         return(XML_ERR_NO_MEMORY);
267*6777b538SAndroid Build Coastguard Worker     } else if (res == 0) {
268*6777b538SAndroid Build Coastguard Worker 	/*
269*6777b538SAndroid Build Coastguard Worker 	 * entity was already defined at another level.
270*6777b538SAndroid Build Coastguard Worker 	 */
271*6777b538SAndroid Build Coastguard Worker         xmlFreeEntity(ret);
272*6777b538SAndroid Build Coastguard Worker 	return(XML_WAR_ENTITY_REDEFINED);
273*6777b538SAndroid Build Coastguard Worker     }
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker     /*
276*6777b538SAndroid Build Coastguard Worker      * Link it to the DTD
277*6777b538SAndroid Build Coastguard Worker      */
278*6777b538SAndroid Build Coastguard Worker     ret->parent = dtd;
279*6777b538SAndroid Build Coastguard Worker     ret->doc = dtd->doc;
280*6777b538SAndroid Build Coastguard Worker     if (dtd->last == NULL) {
281*6777b538SAndroid Build Coastguard Worker 	dtd->children = dtd->last = (xmlNodePtr) ret;
282*6777b538SAndroid Build Coastguard Worker     } else {
283*6777b538SAndroid Build Coastguard Worker 	dtd->last->next = (xmlNodePtr) ret;
284*6777b538SAndroid Build Coastguard Worker 	ret->prev = dtd->last;
285*6777b538SAndroid Build Coastguard Worker 	dtd->last = (xmlNodePtr) ret;
286*6777b538SAndroid Build Coastguard Worker     }
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker     *out = ret;
289*6777b538SAndroid Build Coastguard Worker     return(0);
290*6777b538SAndroid Build Coastguard Worker }
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker /**
293*6777b538SAndroid Build Coastguard Worker  * xmlGetPredefinedEntity:
294*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
295*6777b538SAndroid Build Coastguard Worker  *
296*6777b538SAndroid Build Coastguard Worker  * Check whether this name is an predefined entity.
297*6777b538SAndroid Build Coastguard Worker  *
298*6777b538SAndroid Build Coastguard Worker  * Returns NULL if not, otherwise the entity
299*6777b538SAndroid Build Coastguard Worker  */
300*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlGetPredefinedEntity(const xmlChar * name)301*6777b538SAndroid Build Coastguard Worker xmlGetPredefinedEntity(const xmlChar *name) {
302*6777b538SAndroid Build Coastguard Worker     if (name == NULL) return(NULL);
303*6777b538SAndroid Build Coastguard Worker     switch (name[0]) {
304*6777b538SAndroid Build Coastguard Worker         case 'l':
305*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(name, BAD_CAST "lt"))
306*6777b538SAndroid Build Coastguard Worker 	        return(&xmlEntityLt);
307*6777b538SAndroid Build Coastguard Worker 	    break;
308*6777b538SAndroid Build Coastguard Worker         case 'g':
309*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(name, BAD_CAST "gt"))
310*6777b538SAndroid Build Coastguard Worker 	        return(&xmlEntityGt);
311*6777b538SAndroid Build Coastguard Worker 	    break;
312*6777b538SAndroid Build Coastguard Worker         case 'a':
313*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(name, BAD_CAST "amp"))
314*6777b538SAndroid Build Coastguard Worker 	        return(&xmlEntityAmp);
315*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(name, BAD_CAST "apos"))
316*6777b538SAndroid Build Coastguard Worker 	        return(&xmlEntityApos);
317*6777b538SAndroid Build Coastguard Worker 	    break;
318*6777b538SAndroid Build Coastguard Worker         case 'q':
319*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(name, BAD_CAST "quot"))
320*6777b538SAndroid Build Coastguard Worker 	        return(&xmlEntityQuot);
321*6777b538SAndroid Build Coastguard Worker 	    break;
322*6777b538SAndroid Build Coastguard Worker 	default:
323*6777b538SAndroid Build Coastguard Worker 	    break;
324*6777b538SAndroid Build Coastguard Worker     }
325*6777b538SAndroid Build Coastguard Worker     return(NULL);
326*6777b538SAndroid Build Coastguard Worker }
327*6777b538SAndroid Build Coastguard Worker 
328*6777b538SAndroid Build Coastguard Worker /**
329*6777b538SAndroid Build Coastguard Worker  * xmlAddDtdEntity:
330*6777b538SAndroid Build Coastguard Worker  * @doc:  the document
331*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
332*6777b538SAndroid Build Coastguard Worker  * @type:  the entity type XML_xxx_yyy_ENTITY
333*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the entity external ID if available
334*6777b538SAndroid Build Coastguard Worker  * @SystemID:  the entity system ID if available
335*6777b538SAndroid Build Coastguard Worker  * @content:  the entity content
336*6777b538SAndroid Build Coastguard Worker  *
337*6777b538SAndroid Build Coastguard Worker  * Register a new entity for this document DTD external subset.
338*6777b538SAndroid Build Coastguard Worker  *
339*6777b538SAndroid Build Coastguard Worker  * Returns a pointer to the entity or NULL in case of error
340*6777b538SAndroid Build Coastguard Worker  */
341*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlAddDtdEntity(xmlDocPtr doc,const xmlChar * name,int type,const xmlChar * ExternalID,const xmlChar * SystemID,const xmlChar * content)342*6777b538SAndroid Build Coastguard Worker xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
343*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *ExternalID, const xmlChar *SystemID,
344*6777b538SAndroid Build Coastguard Worker 		const xmlChar *content) {
345*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ret;
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker     xmlAddEntity(doc, 1, name, type, ExternalID, SystemID, content, &ret);
348*6777b538SAndroid Build Coastguard Worker     return(ret);
349*6777b538SAndroid Build Coastguard Worker }
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker /**
352*6777b538SAndroid Build Coastguard Worker  * xmlAddDocEntity:
353*6777b538SAndroid Build Coastguard Worker  * @doc:  the document
354*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
355*6777b538SAndroid Build Coastguard Worker  * @type:  the entity type XML_xxx_yyy_ENTITY
356*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the entity external ID if available
357*6777b538SAndroid Build Coastguard Worker  * @SystemID:  the entity system ID if available
358*6777b538SAndroid Build Coastguard Worker  * @content:  the entity content
359*6777b538SAndroid Build Coastguard Worker  *
360*6777b538SAndroid Build Coastguard Worker  * Register a new entity for this document.
361*6777b538SAndroid Build Coastguard Worker  *
362*6777b538SAndroid Build Coastguard Worker  * Returns a pointer to the entity or NULL in case of error
363*6777b538SAndroid Build Coastguard Worker  */
364*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlAddDocEntity(xmlDocPtr doc,const xmlChar * name,int type,const xmlChar * ExternalID,const xmlChar * SystemID,const xmlChar * content)365*6777b538SAndroid Build Coastguard Worker xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
366*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *ExternalID, const xmlChar *SystemID,
367*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *content) {
368*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ret;
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker     xmlAddEntity(doc, 0, name, type, ExternalID, SystemID, content, &ret);
371*6777b538SAndroid Build Coastguard Worker     return(ret);
372*6777b538SAndroid Build Coastguard Worker }
373*6777b538SAndroid Build Coastguard Worker 
374*6777b538SAndroid Build Coastguard Worker /**
375*6777b538SAndroid Build Coastguard Worker  * xmlNewEntity:
376*6777b538SAndroid Build Coastguard Worker  * @doc:  the document
377*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
378*6777b538SAndroid Build Coastguard Worker  * @type:  the entity type XML_xxx_yyy_ENTITY
379*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the entity external ID if available
380*6777b538SAndroid Build Coastguard Worker  * @SystemID:  the entity system ID if available
381*6777b538SAndroid Build Coastguard Worker  * @content:  the entity content
382*6777b538SAndroid Build Coastguard Worker  *
383*6777b538SAndroid Build Coastguard Worker  * Create a new entity, this differs from xmlAddDocEntity() that if
384*6777b538SAndroid Build Coastguard Worker  * the document is NULL or has no internal subset defined, then an
385*6777b538SAndroid Build Coastguard Worker  * unlinked entity structure will be returned, it is then the responsibility
386*6777b538SAndroid Build Coastguard Worker  * of the caller to link it to the document later or free it when not needed
387*6777b538SAndroid Build Coastguard Worker  * anymore.
388*6777b538SAndroid Build Coastguard Worker  *
389*6777b538SAndroid Build Coastguard Worker  * Returns a pointer to the entity or NULL in case of error
390*6777b538SAndroid Build Coastguard Worker  */
391*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlNewEntity(xmlDocPtr doc,const xmlChar * name,int type,const xmlChar * ExternalID,const xmlChar * SystemID,const xmlChar * content)392*6777b538SAndroid Build Coastguard Worker xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type,
393*6777b538SAndroid Build Coastguard Worker 	     const xmlChar *ExternalID, const xmlChar *SystemID,
394*6777b538SAndroid Build Coastguard Worker 	     const xmlChar *content) {
395*6777b538SAndroid Build Coastguard Worker     if ((doc != NULL) && (doc->intSubset != NULL)) {
396*6777b538SAndroid Build Coastguard Worker 	return(xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content));
397*6777b538SAndroid Build Coastguard Worker     }
398*6777b538SAndroid Build Coastguard Worker     return(xmlCreateEntity(doc, name, type, ExternalID, SystemID, content));
399*6777b538SAndroid Build Coastguard Worker }
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker /**
402*6777b538SAndroid Build Coastguard Worker  * xmlGetEntityFromTable:
403*6777b538SAndroid Build Coastguard Worker  * @table:  an entity table
404*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
405*6777b538SAndroid Build Coastguard Worker  * @parameter:  look for parameter entities
406*6777b538SAndroid Build Coastguard Worker  *
407*6777b538SAndroid Build Coastguard Worker  * Do an entity lookup in the table.
408*6777b538SAndroid Build Coastguard Worker  * returns the corresponding parameter entity, if found.
409*6777b538SAndroid Build Coastguard Worker  *
410*6777b538SAndroid Build Coastguard Worker  * Returns A pointer to the entity structure or NULL if not found.
411*6777b538SAndroid Build Coastguard Worker  */
412*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr
xmlGetEntityFromTable(xmlEntitiesTablePtr table,const xmlChar * name)413*6777b538SAndroid Build Coastguard Worker xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
414*6777b538SAndroid Build Coastguard Worker     return((xmlEntityPtr) xmlHashLookup(table, name));
415*6777b538SAndroid Build Coastguard Worker }
416*6777b538SAndroid Build Coastguard Worker 
417*6777b538SAndroid Build Coastguard Worker /**
418*6777b538SAndroid Build Coastguard Worker  * xmlGetParameterEntity:
419*6777b538SAndroid Build Coastguard Worker  * @doc:  the document referencing the entity
420*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
421*6777b538SAndroid Build Coastguard Worker  *
422*6777b538SAndroid Build Coastguard Worker  * Do an entity lookup in the internal and external subsets and
423*6777b538SAndroid Build Coastguard Worker  * returns the corresponding parameter entity, if found.
424*6777b538SAndroid Build Coastguard Worker  *
425*6777b538SAndroid Build Coastguard Worker  * Returns A pointer to the entity structure or NULL if not found.
426*6777b538SAndroid Build Coastguard Worker  */
427*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlGetParameterEntity(xmlDocPtr doc,const xmlChar * name)428*6777b538SAndroid Build Coastguard Worker xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
429*6777b538SAndroid Build Coastguard Worker     xmlEntitiesTablePtr table;
430*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ret;
431*6777b538SAndroid Build Coastguard Worker 
432*6777b538SAndroid Build Coastguard Worker     if (doc == NULL)
433*6777b538SAndroid Build Coastguard Worker 	return(NULL);
434*6777b538SAndroid Build Coastguard Worker     if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
435*6777b538SAndroid Build Coastguard Worker 	table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
436*6777b538SAndroid Build Coastguard Worker 	ret = xmlGetEntityFromTable(table, name);
437*6777b538SAndroid Build Coastguard Worker 	if (ret != NULL)
438*6777b538SAndroid Build Coastguard Worker 	    return(ret);
439*6777b538SAndroid Build Coastguard Worker     }
440*6777b538SAndroid Build Coastguard Worker     if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
441*6777b538SAndroid Build Coastguard Worker 	table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
442*6777b538SAndroid Build Coastguard Worker 	return(xmlGetEntityFromTable(table, name));
443*6777b538SAndroid Build Coastguard Worker     }
444*6777b538SAndroid Build Coastguard Worker     return(NULL);
445*6777b538SAndroid Build Coastguard Worker }
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker /**
448*6777b538SAndroid Build Coastguard Worker  * xmlGetDtdEntity:
449*6777b538SAndroid Build Coastguard Worker  * @doc:  the document referencing the entity
450*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
451*6777b538SAndroid Build Coastguard Worker  *
452*6777b538SAndroid Build Coastguard Worker  * Do an entity lookup in the DTD entity hash table and
453*6777b538SAndroid Build Coastguard Worker  * returns the corresponding entity, if found.
454*6777b538SAndroid Build Coastguard Worker  * Note: the first argument is the document node, not the DTD node.
455*6777b538SAndroid Build Coastguard Worker  *
456*6777b538SAndroid Build Coastguard Worker  * Returns A pointer to the entity structure or NULL if not found.
457*6777b538SAndroid Build Coastguard Worker  */
458*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlGetDtdEntity(xmlDocPtr doc,const xmlChar * name)459*6777b538SAndroid Build Coastguard Worker xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
460*6777b538SAndroid Build Coastguard Worker     xmlEntitiesTablePtr table;
461*6777b538SAndroid Build Coastguard Worker 
462*6777b538SAndroid Build Coastguard Worker     if (doc == NULL)
463*6777b538SAndroid Build Coastguard Worker 	return(NULL);
464*6777b538SAndroid Build Coastguard Worker     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
465*6777b538SAndroid Build Coastguard Worker 	table = (xmlEntitiesTablePtr) doc->extSubset->entities;
466*6777b538SAndroid Build Coastguard Worker 	return(xmlGetEntityFromTable(table, name));
467*6777b538SAndroid Build Coastguard Worker     }
468*6777b538SAndroid Build Coastguard Worker     return(NULL);
469*6777b538SAndroid Build Coastguard Worker }
470*6777b538SAndroid Build Coastguard Worker 
471*6777b538SAndroid Build Coastguard Worker /**
472*6777b538SAndroid Build Coastguard Worker  * xmlGetDocEntity:
473*6777b538SAndroid Build Coastguard Worker  * @doc:  the document referencing the entity
474*6777b538SAndroid Build Coastguard Worker  * @name:  the entity name
475*6777b538SAndroid Build Coastguard Worker  *
476*6777b538SAndroid Build Coastguard Worker  * Do an entity lookup in the document entity hash table and
477*6777b538SAndroid Build Coastguard Worker  * returns the corresponding entity, otherwise a lookup is done
478*6777b538SAndroid Build Coastguard Worker  * in the predefined entities too.
479*6777b538SAndroid Build Coastguard Worker  *
480*6777b538SAndroid Build Coastguard Worker  * Returns A pointer to the entity structure or NULL if not found.
481*6777b538SAndroid Build Coastguard Worker  */
482*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlGetDocEntity(const xmlDoc * doc,const xmlChar * name)483*6777b538SAndroid Build Coastguard Worker xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name) {
484*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr cur;
485*6777b538SAndroid Build Coastguard Worker     xmlEntitiesTablePtr table;
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker     if (doc != NULL) {
488*6777b538SAndroid Build Coastguard Worker 	if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
489*6777b538SAndroid Build Coastguard Worker 	    table = (xmlEntitiesTablePtr) doc->intSubset->entities;
490*6777b538SAndroid Build Coastguard Worker 	    cur = xmlGetEntityFromTable(table, name);
491*6777b538SAndroid Build Coastguard Worker 	    if (cur != NULL)
492*6777b538SAndroid Build Coastguard Worker 		return(cur);
493*6777b538SAndroid Build Coastguard Worker 	}
494*6777b538SAndroid Build Coastguard Worker 	if (doc->standalone != 1) {
495*6777b538SAndroid Build Coastguard Worker 	    if ((doc->extSubset != NULL) &&
496*6777b538SAndroid Build Coastguard Worker 		(doc->extSubset->entities != NULL)) {
497*6777b538SAndroid Build Coastguard Worker 		table = (xmlEntitiesTablePtr) doc->extSubset->entities;
498*6777b538SAndroid Build Coastguard Worker 		cur = xmlGetEntityFromTable(table, name);
499*6777b538SAndroid Build Coastguard Worker 		if (cur != NULL)
500*6777b538SAndroid Build Coastguard Worker 		    return(cur);
501*6777b538SAndroid Build Coastguard Worker 	    }
502*6777b538SAndroid Build Coastguard Worker 	}
503*6777b538SAndroid Build Coastguard Worker     }
504*6777b538SAndroid Build Coastguard Worker     return(xmlGetPredefinedEntity(name));
505*6777b538SAndroid Build Coastguard Worker }
506*6777b538SAndroid Build Coastguard Worker 
507*6777b538SAndroid Build Coastguard Worker /*
508*6777b538SAndroid Build Coastguard Worker  * Macro used to grow the current buffer.
509*6777b538SAndroid Build Coastguard Worker  */
510*6777b538SAndroid Build Coastguard Worker #define growBufferReentrant() {						\
511*6777b538SAndroid Build Coastguard Worker     xmlChar *tmp;                                                       \
512*6777b538SAndroid Build Coastguard Worker     size_t new_size = buffer_size * 2;                                  \
513*6777b538SAndroid Build Coastguard Worker     if (new_size < buffer_size) goto mem_error;                         \
514*6777b538SAndroid Build Coastguard Worker     tmp = (xmlChar *) xmlRealloc(buffer, new_size);	                \
515*6777b538SAndroid Build Coastguard Worker     if (tmp == NULL) goto mem_error;                                    \
516*6777b538SAndroid Build Coastguard Worker     buffer = tmp;							\
517*6777b538SAndroid Build Coastguard Worker     buffer_size = new_size;						\
518*6777b538SAndroid Build Coastguard Worker }
519*6777b538SAndroid Build Coastguard Worker 
520*6777b538SAndroid Build Coastguard Worker /**
521*6777b538SAndroid Build Coastguard Worker  * xmlEncodeEntitiesInternal:
522*6777b538SAndroid Build Coastguard Worker  * @doc:  the document containing the string
523*6777b538SAndroid Build Coastguard Worker  * @input:  A string to convert to XML.
524*6777b538SAndroid Build Coastguard Worker  * @attr: are we handling an attribute value
525*6777b538SAndroid Build Coastguard Worker  *
526*6777b538SAndroid Build Coastguard Worker  * Do a global encoding of a string, replacing the predefined entities
527*6777b538SAndroid Build Coastguard Worker  * and non ASCII values with their entities and CharRef counterparts.
528*6777b538SAndroid Build Coastguard Worker  * Contrary to xmlEncodeEntities, this routine is reentrant, and result
529*6777b538SAndroid Build Coastguard Worker  * must be deallocated.
530*6777b538SAndroid Build Coastguard Worker  *
531*6777b538SAndroid Build Coastguard Worker  * Returns A newly allocated string with the substitution done.
532*6777b538SAndroid Build Coastguard Worker  */
533*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlEncodeEntitiesInternal(xmlDocPtr doc,const xmlChar * input,int attr)534*6777b538SAndroid Build Coastguard Worker xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
535*6777b538SAndroid Build Coastguard Worker     const xmlChar *cur = input;
536*6777b538SAndroid Build Coastguard Worker     xmlChar *buffer = NULL;
537*6777b538SAndroid Build Coastguard Worker     xmlChar *out = NULL;
538*6777b538SAndroid Build Coastguard Worker     size_t buffer_size = 0;
539*6777b538SAndroid Build Coastguard Worker     int html = 0;
540*6777b538SAndroid Build Coastguard Worker 
541*6777b538SAndroid Build Coastguard Worker     if (input == NULL) return(NULL);
542*6777b538SAndroid Build Coastguard Worker     if (doc != NULL)
543*6777b538SAndroid Build Coastguard Worker         html = (doc->type == XML_HTML_DOCUMENT_NODE);
544*6777b538SAndroid Build Coastguard Worker 
545*6777b538SAndroid Build Coastguard Worker     /*
546*6777b538SAndroid Build Coastguard Worker      * allocate an translation buffer.
547*6777b538SAndroid Build Coastguard Worker      */
548*6777b538SAndroid Build Coastguard Worker     buffer_size = 1000;
549*6777b538SAndroid Build Coastguard Worker     buffer = (xmlChar *) xmlMalloc(buffer_size);
550*6777b538SAndroid Build Coastguard Worker     if (buffer == NULL)
551*6777b538SAndroid Build Coastguard Worker 	return(NULL);
552*6777b538SAndroid Build Coastguard Worker     out = buffer;
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker     while (*cur != '\0') {
555*6777b538SAndroid Build Coastguard Worker         size_t indx = out - buffer;
556*6777b538SAndroid Build Coastguard Worker         if (indx + 100 > buffer_size) {
557*6777b538SAndroid Build Coastguard Worker 
558*6777b538SAndroid Build Coastguard Worker 	    growBufferReentrant();
559*6777b538SAndroid Build Coastguard Worker 	    out = &buffer[indx];
560*6777b538SAndroid Build Coastguard Worker 	}
561*6777b538SAndroid Build Coastguard Worker 
562*6777b538SAndroid Build Coastguard Worker 	/*
563*6777b538SAndroid Build Coastguard Worker 	 * By default one have to encode at least '<', '>', '"' and '&' !
564*6777b538SAndroid Build Coastguard Worker 	 */
565*6777b538SAndroid Build Coastguard Worker 	if (*cur == '<') {
566*6777b538SAndroid Build Coastguard Worker 	    const xmlChar *end;
567*6777b538SAndroid Build Coastguard Worker 
568*6777b538SAndroid Build Coastguard Worker 	    /*
569*6777b538SAndroid Build Coastguard Worker 	     * Special handling of server side include in HTML attributes
570*6777b538SAndroid Build Coastguard Worker 	     */
571*6777b538SAndroid Build Coastguard Worker 	    if (html && attr &&
572*6777b538SAndroid Build Coastguard Worker 	        (cur[1] == '!') && (cur[2] == '-') && (cur[3] == '-') &&
573*6777b538SAndroid Build Coastguard Worker 	        ((end = xmlStrstr(cur, BAD_CAST "-->")) != NULL)) {
574*6777b538SAndroid Build Coastguard Worker 	        while (cur != end) {
575*6777b538SAndroid Build Coastguard Worker 		    *out++ = *cur++;
576*6777b538SAndroid Build Coastguard Worker 		    indx = out - buffer;
577*6777b538SAndroid Build Coastguard Worker 		    if (indx + 100 > buffer_size) {
578*6777b538SAndroid Build Coastguard Worker 			growBufferReentrant();
579*6777b538SAndroid Build Coastguard Worker 			out = &buffer[indx];
580*6777b538SAndroid Build Coastguard Worker 		    }
581*6777b538SAndroid Build Coastguard Worker 		}
582*6777b538SAndroid Build Coastguard Worker 		*out++ = *cur++;
583*6777b538SAndroid Build Coastguard Worker 		*out++ = *cur++;
584*6777b538SAndroid Build Coastguard Worker 		*out++ = *cur++;
585*6777b538SAndroid Build Coastguard Worker 		continue;
586*6777b538SAndroid Build Coastguard Worker 	    }
587*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
588*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'l';
589*6777b538SAndroid Build Coastguard Worker 	    *out++ = 't';
590*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
591*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '>') {
592*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
593*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'g';
594*6777b538SAndroid Build Coastguard Worker 	    *out++ = 't';
595*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
596*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '&') {
597*6777b538SAndroid Build Coastguard Worker 	    /*
598*6777b538SAndroid Build Coastguard Worker 	     * Special handling of &{...} construct from HTML 4, see
599*6777b538SAndroid Build Coastguard Worker 	     * http://www.w3.org/TR/html401/appendix/notes.html#h-B.7.1
600*6777b538SAndroid Build Coastguard Worker 	     */
601*6777b538SAndroid Build Coastguard Worker 	    if (html && attr && (cur[1] == '{') &&
602*6777b538SAndroid Build Coastguard Worker 	        (strchr((const char *) cur, '}'))) {
603*6777b538SAndroid Build Coastguard Worker 	        while (*cur != '}') {
604*6777b538SAndroid Build Coastguard Worker 		    *out++ = *cur++;
605*6777b538SAndroid Build Coastguard Worker 		    indx = out - buffer;
606*6777b538SAndroid Build Coastguard Worker 		    if (indx + 100 > buffer_size) {
607*6777b538SAndroid Build Coastguard Worker 			growBufferReentrant();
608*6777b538SAndroid Build Coastguard Worker 			out = &buffer[indx];
609*6777b538SAndroid Build Coastguard Worker 		    }
610*6777b538SAndroid Build Coastguard Worker 		}
611*6777b538SAndroid Build Coastguard Worker 		*out++ = *cur++;
612*6777b538SAndroid Build Coastguard Worker 		continue;
613*6777b538SAndroid Build Coastguard Worker 	    }
614*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
615*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'a';
616*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'm';
617*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'p';
618*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
619*6777b538SAndroid Build Coastguard Worker 	} else if (((*cur >= 0x20) && (*cur < 0x80)) ||
620*6777b538SAndroid Build Coastguard Worker 	    (*cur == '\n') || (*cur == '\t') || ((html) && (*cur == '\r'))) {
621*6777b538SAndroid Build Coastguard Worker 	    /*
622*6777b538SAndroid Build Coastguard Worker 	     * default case, just copy !
623*6777b538SAndroid Build Coastguard Worker 	     */
624*6777b538SAndroid Build Coastguard Worker 	    *out++ = *cur;
625*6777b538SAndroid Build Coastguard Worker 	} else if (*cur >= 0x80) {
626*6777b538SAndroid Build Coastguard Worker 	    if (((doc != NULL) && (doc->encoding != NULL)) || (html)) {
627*6777b538SAndroid Build Coastguard Worker 		/*
628*6777b538SAndroid Build Coastguard Worker 		 * Bjørn Reese <[email protected]> provided the patch
629*6777b538SAndroid Build Coastguard Worker 	        xmlChar xc;
630*6777b538SAndroid Build Coastguard Worker 	        xc = (*cur & 0x3F) << 6;
631*6777b538SAndroid Build Coastguard Worker 	        if (cur[1] != 0) {
632*6777b538SAndroid Build Coastguard Worker 		    xc += *(++cur) & 0x3F;
633*6777b538SAndroid Build Coastguard Worker 		    *out++ = xc;
634*6777b538SAndroid Build Coastguard Worker 	        } else
635*6777b538SAndroid Build Coastguard Worker 		 */
636*6777b538SAndroid Build Coastguard Worker 		*out++ = *cur;
637*6777b538SAndroid Build Coastguard Worker 	    } else {
638*6777b538SAndroid Build Coastguard Worker 		/*
639*6777b538SAndroid Build Coastguard Worker 		 * We assume we have UTF-8 input.
640*6777b538SAndroid Build Coastguard Worker 		 * It must match either:
641*6777b538SAndroid Build Coastguard Worker 		 *   110xxxxx 10xxxxxx
642*6777b538SAndroid Build Coastguard Worker 		 *   1110xxxx 10xxxxxx 10xxxxxx
643*6777b538SAndroid Build Coastguard Worker 		 *   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
644*6777b538SAndroid Build Coastguard Worker 		 * That is:
645*6777b538SAndroid Build Coastguard Worker 		 *   cur[0] is 11xxxxxx
646*6777b538SAndroid Build Coastguard Worker 		 *   cur[1] is 10xxxxxx
647*6777b538SAndroid Build Coastguard Worker 		 *   cur[2] is 10xxxxxx if cur[0] is 111xxxxx
648*6777b538SAndroid Build Coastguard Worker 		 *   cur[3] is 10xxxxxx if cur[0] is 1111xxxx
649*6777b538SAndroid Build Coastguard Worker 		 *   cur[0] is not 11111xxx
650*6777b538SAndroid Build Coastguard Worker 		 */
651*6777b538SAndroid Build Coastguard Worker 		char buf[13], *ptr;
652*6777b538SAndroid Build Coastguard Worker 		int val, l;
653*6777b538SAndroid Build Coastguard Worker 
654*6777b538SAndroid Build Coastguard Worker                 l = 4;
655*6777b538SAndroid Build Coastguard Worker                 val = xmlGetUTF8Char(cur, &l);
656*6777b538SAndroid Build Coastguard Worker                 if (val < 0) {
657*6777b538SAndroid Build Coastguard Worker #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
658*6777b538SAndroid Build Coastguard Worker                     fprintf(stderr, "xmlEncodeEntitiesInternal: "
659*6777b538SAndroid Build Coastguard Worker                             "invalid UTF-8\n");
660*6777b538SAndroid Build Coastguard Worker                     abort();
661*6777b538SAndroid Build Coastguard Worker #endif
662*6777b538SAndroid Build Coastguard Worker                     val = 0xFFFD;
663*6777b538SAndroid Build Coastguard Worker                     cur++;
664*6777b538SAndroid Build Coastguard Worker                 } else {
665*6777b538SAndroid Build Coastguard Worker                     if (!IS_CHAR(val))
666*6777b538SAndroid Build Coastguard Worker                         val = 0xFFFD;
667*6777b538SAndroid Build Coastguard Worker                     cur += l;
668*6777b538SAndroid Build Coastguard Worker 		}
669*6777b538SAndroid Build Coastguard Worker 		/*
670*6777b538SAndroid Build Coastguard Worker 		 * We could do multiple things here. Just save as a char ref
671*6777b538SAndroid Build Coastguard Worker 		 */
672*6777b538SAndroid Build Coastguard Worker 		snprintf(buf, sizeof(buf), "&#x%X;", val);
673*6777b538SAndroid Build Coastguard Worker 		buf[sizeof(buf) - 1] = 0;
674*6777b538SAndroid Build Coastguard Worker 		ptr = buf;
675*6777b538SAndroid Build Coastguard Worker 		while (*ptr != 0) *out++ = *ptr++;
676*6777b538SAndroid Build Coastguard Worker 		continue;
677*6777b538SAndroid Build Coastguard Worker 	    }
678*6777b538SAndroid Build Coastguard Worker 	} else if (IS_BYTE_CHAR(*cur)) {
679*6777b538SAndroid Build Coastguard Worker 	    char buf[11], *ptr;
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker 	    snprintf(buf, sizeof(buf), "&#%d;", *cur);
682*6777b538SAndroid Build Coastguard Worker 	    buf[sizeof(buf) - 1] = 0;
683*6777b538SAndroid Build Coastguard Worker             ptr = buf;
684*6777b538SAndroid Build Coastguard Worker 	    while (*ptr != 0) *out++ = *ptr++;
685*6777b538SAndroid Build Coastguard Worker 	}
686*6777b538SAndroid Build Coastguard Worker 	cur++;
687*6777b538SAndroid Build Coastguard Worker     }
688*6777b538SAndroid Build Coastguard Worker     *out = 0;
689*6777b538SAndroid Build Coastguard Worker     return(buffer);
690*6777b538SAndroid Build Coastguard Worker 
691*6777b538SAndroid Build Coastguard Worker mem_error:
692*6777b538SAndroid Build Coastguard Worker     xmlFree(buffer);
693*6777b538SAndroid Build Coastguard Worker     return(NULL);
694*6777b538SAndroid Build Coastguard Worker }
695*6777b538SAndroid Build Coastguard Worker 
696*6777b538SAndroid Build Coastguard Worker /**
697*6777b538SAndroid Build Coastguard Worker  * xmlEncodeAttributeEntities:
698*6777b538SAndroid Build Coastguard Worker  * @doc:  the document containing the string
699*6777b538SAndroid Build Coastguard Worker  * @input:  A string to convert to XML.
700*6777b538SAndroid Build Coastguard Worker  *
701*6777b538SAndroid Build Coastguard Worker  * Do a global encoding of a string, replacing the predefined entities
702*6777b538SAndroid Build Coastguard Worker  * and non ASCII values with their entities and CharRef counterparts for
703*6777b538SAndroid Build Coastguard Worker  * attribute values.
704*6777b538SAndroid Build Coastguard Worker  *
705*6777b538SAndroid Build Coastguard Worker  * Returns A newly allocated string with the substitution done.
706*6777b538SAndroid Build Coastguard Worker  */
707*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlEncodeAttributeEntities(xmlDocPtr doc,const xmlChar * input)708*6777b538SAndroid Build Coastguard Worker xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input) {
709*6777b538SAndroid Build Coastguard Worker     return xmlEncodeEntitiesInternal(doc, input, 1);
710*6777b538SAndroid Build Coastguard Worker }
711*6777b538SAndroid Build Coastguard Worker 
712*6777b538SAndroid Build Coastguard Worker /**
713*6777b538SAndroid Build Coastguard Worker  * xmlEncodeEntitiesReentrant:
714*6777b538SAndroid Build Coastguard Worker  * @doc:  the document containing the string
715*6777b538SAndroid Build Coastguard Worker  * @input:  A string to convert to XML.
716*6777b538SAndroid Build Coastguard Worker  *
717*6777b538SAndroid Build Coastguard Worker  * Do a global encoding of a string, replacing the predefined entities
718*6777b538SAndroid Build Coastguard Worker  * and non ASCII values with their entities and CharRef counterparts.
719*6777b538SAndroid Build Coastguard Worker  * Contrary to xmlEncodeEntities, this routine is reentrant, and result
720*6777b538SAndroid Build Coastguard Worker  * must be deallocated.
721*6777b538SAndroid Build Coastguard Worker  *
722*6777b538SAndroid Build Coastguard Worker  * Returns A newly allocated string with the substitution done.
723*6777b538SAndroid Build Coastguard Worker  */
724*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlEncodeEntitiesReentrant(xmlDocPtr doc,const xmlChar * input)725*6777b538SAndroid Build Coastguard Worker xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
726*6777b538SAndroid Build Coastguard Worker     return xmlEncodeEntitiesInternal(doc, input, 0);
727*6777b538SAndroid Build Coastguard Worker }
728*6777b538SAndroid Build Coastguard Worker 
729*6777b538SAndroid Build Coastguard Worker /**
730*6777b538SAndroid Build Coastguard Worker  * xmlEncodeSpecialChars:
731*6777b538SAndroid Build Coastguard Worker  * @doc:  the document containing the string
732*6777b538SAndroid Build Coastguard Worker  * @input:  A string to convert to XML.
733*6777b538SAndroid Build Coastguard Worker  *
734*6777b538SAndroid Build Coastguard Worker  * Do a global encoding of a string, replacing the predefined entities
735*6777b538SAndroid Build Coastguard Worker  * this routine is reentrant, and result must be deallocated.
736*6777b538SAndroid Build Coastguard Worker  *
737*6777b538SAndroid Build Coastguard Worker  * Returns A newly allocated string with the substitution done.
738*6777b538SAndroid Build Coastguard Worker  */
739*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlEncodeSpecialChars(const xmlDoc * doc ATTRIBUTE_UNUSED,const xmlChar * input)740*6777b538SAndroid Build Coastguard Worker xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input) {
741*6777b538SAndroid Build Coastguard Worker     const xmlChar *cur = input;
742*6777b538SAndroid Build Coastguard Worker     xmlChar *buffer = NULL;
743*6777b538SAndroid Build Coastguard Worker     xmlChar *out = NULL;
744*6777b538SAndroid Build Coastguard Worker     size_t buffer_size = 0;
745*6777b538SAndroid Build Coastguard Worker     if (input == NULL) return(NULL);
746*6777b538SAndroid Build Coastguard Worker 
747*6777b538SAndroid Build Coastguard Worker     /*
748*6777b538SAndroid Build Coastguard Worker      * allocate an translation buffer.
749*6777b538SAndroid Build Coastguard Worker      */
750*6777b538SAndroid Build Coastguard Worker     buffer_size = 1000;
751*6777b538SAndroid Build Coastguard Worker     buffer = (xmlChar *) xmlMalloc(buffer_size);
752*6777b538SAndroid Build Coastguard Worker     if (buffer == NULL)
753*6777b538SAndroid Build Coastguard Worker 	return(NULL);
754*6777b538SAndroid Build Coastguard Worker     out = buffer;
755*6777b538SAndroid Build Coastguard Worker 
756*6777b538SAndroid Build Coastguard Worker     while (*cur != '\0') {
757*6777b538SAndroid Build Coastguard Worker         size_t indx = out - buffer;
758*6777b538SAndroid Build Coastguard Worker         if (indx + 10 > buffer_size) {
759*6777b538SAndroid Build Coastguard Worker 
760*6777b538SAndroid Build Coastguard Worker 	    growBufferReentrant();
761*6777b538SAndroid Build Coastguard Worker 	    out = &buffer[indx];
762*6777b538SAndroid Build Coastguard Worker 	}
763*6777b538SAndroid Build Coastguard Worker 
764*6777b538SAndroid Build Coastguard Worker 	/*
765*6777b538SAndroid Build Coastguard Worker 	 * By default one have to encode at least '<', '>', '"' and '&' !
766*6777b538SAndroid Build Coastguard Worker 	 */
767*6777b538SAndroid Build Coastguard Worker 	if (*cur == '<') {
768*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
769*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'l';
770*6777b538SAndroid Build Coastguard Worker 	    *out++ = 't';
771*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
772*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '>') {
773*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
774*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'g';
775*6777b538SAndroid Build Coastguard Worker 	    *out++ = 't';
776*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
777*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '&') {
778*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
779*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'a';
780*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'm';
781*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'p';
782*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
783*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '"') {
784*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
785*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'q';
786*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'u';
787*6777b538SAndroid Build Coastguard Worker 	    *out++ = 'o';
788*6777b538SAndroid Build Coastguard Worker 	    *out++ = 't';
789*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
790*6777b538SAndroid Build Coastguard Worker 	} else if (*cur == '\r') {
791*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
792*6777b538SAndroid Build Coastguard Worker 	    *out++ = '#';
793*6777b538SAndroid Build Coastguard Worker 	    *out++ = '1';
794*6777b538SAndroid Build Coastguard Worker 	    *out++ = '3';
795*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
796*6777b538SAndroid Build Coastguard Worker 	} else {
797*6777b538SAndroid Build Coastguard Worker 	    /*
798*6777b538SAndroid Build Coastguard Worker 	     * Works because on UTF-8, all extended sequences cannot
799*6777b538SAndroid Build Coastguard Worker 	     * result in bytes in the ASCII range.
800*6777b538SAndroid Build Coastguard Worker 	     */
801*6777b538SAndroid Build Coastguard Worker 	    *out++ = *cur;
802*6777b538SAndroid Build Coastguard Worker 	}
803*6777b538SAndroid Build Coastguard Worker 	cur++;
804*6777b538SAndroid Build Coastguard Worker     }
805*6777b538SAndroid Build Coastguard Worker     *out = 0;
806*6777b538SAndroid Build Coastguard Worker     return(buffer);
807*6777b538SAndroid Build Coastguard Worker 
808*6777b538SAndroid Build Coastguard Worker mem_error:
809*6777b538SAndroid Build Coastguard Worker     xmlFree(buffer);
810*6777b538SAndroid Build Coastguard Worker     return(NULL);
811*6777b538SAndroid Build Coastguard Worker }
812*6777b538SAndroid Build Coastguard Worker 
813*6777b538SAndroid Build Coastguard Worker /**
814*6777b538SAndroid Build Coastguard Worker  * xmlCreateEntitiesTable:
815*6777b538SAndroid Build Coastguard Worker  *
816*6777b538SAndroid Build Coastguard Worker  * create and initialize an empty entities hash table.
817*6777b538SAndroid Build Coastguard Worker  * This really doesn't make sense and should be deprecated
818*6777b538SAndroid Build Coastguard Worker  *
819*6777b538SAndroid Build Coastguard Worker  * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
820*6777b538SAndroid Build Coastguard Worker  */
821*6777b538SAndroid Build Coastguard Worker xmlEntitiesTablePtr
xmlCreateEntitiesTable(void)822*6777b538SAndroid Build Coastguard Worker xmlCreateEntitiesTable(void) {
823*6777b538SAndroid Build Coastguard Worker     return((xmlEntitiesTablePtr) xmlHashCreate(0));
824*6777b538SAndroid Build Coastguard Worker }
825*6777b538SAndroid Build Coastguard Worker 
826*6777b538SAndroid Build Coastguard Worker /**
827*6777b538SAndroid Build Coastguard Worker  * xmlFreeEntityWrapper:
828*6777b538SAndroid Build Coastguard Worker  * @entity:  An entity
829*6777b538SAndroid Build Coastguard Worker  * @name:  its name
830*6777b538SAndroid Build Coastguard Worker  *
831*6777b538SAndroid Build Coastguard Worker  * Deallocate the memory used by an entities in the hash table.
832*6777b538SAndroid Build Coastguard Worker  */
833*6777b538SAndroid Build Coastguard Worker static void
xmlFreeEntityWrapper(void * entity,const xmlChar * name ATTRIBUTE_UNUSED)834*6777b538SAndroid Build Coastguard Worker xmlFreeEntityWrapper(void *entity, const xmlChar *name ATTRIBUTE_UNUSED) {
835*6777b538SAndroid Build Coastguard Worker     if (entity != NULL)
836*6777b538SAndroid Build Coastguard Worker 	xmlFreeEntity((xmlEntityPtr) entity);
837*6777b538SAndroid Build Coastguard Worker }
838*6777b538SAndroid Build Coastguard Worker 
839*6777b538SAndroid Build Coastguard Worker /**
840*6777b538SAndroid Build Coastguard Worker  * xmlFreeEntitiesTable:
841*6777b538SAndroid Build Coastguard Worker  * @table:  An entity table
842*6777b538SAndroid Build Coastguard Worker  *
843*6777b538SAndroid Build Coastguard Worker  * Deallocate the memory used by an entities hash table.
844*6777b538SAndroid Build Coastguard Worker  */
845*6777b538SAndroid Build Coastguard Worker void
xmlFreeEntitiesTable(xmlEntitiesTablePtr table)846*6777b538SAndroid Build Coastguard Worker xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
847*6777b538SAndroid Build Coastguard Worker     xmlHashFree(table, xmlFreeEntityWrapper);
848*6777b538SAndroid Build Coastguard Worker }
849*6777b538SAndroid Build Coastguard Worker 
850*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_TREE_ENABLED
851*6777b538SAndroid Build Coastguard Worker /**
852*6777b538SAndroid Build Coastguard Worker  * xmlCopyEntity:
853*6777b538SAndroid Build Coastguard Worker  * @ent:  An entity
854*6777b538SAndroid Build Coastguard Worker  *
855*6777b538SAndroid Build Coastguard Worker  * Build a copy of an entity
856*6777b538SAndroid Build Coastguard Worker  *
857*6777b538SAndroid Build Coastguard Worker  * Returns the new xmlEntitiesPtr or NULL in case of error.
858*6777b538SAndroid Build Coastguard Worker  */
859*6777b538SAndroid Build Coastguard Worker static void *
xmlCopyEntity(void * payload,const xmlChar * name ATTRIBUTE_UNUSED)860*6777b538SAndroid Build Coastguard Worker xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
861*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr ent = (xmlEntityPtr) payload;
862*6777b538SAndroid Build Coastguard Worker     xmlEntityPtr cur;
863*6777b538SAndroid Build Coastguard Worker 
864*6777b538SAndroid Build Coastguard Worker     cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
865*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
866*6777b538SAndroid Build Coastguard Worker 	return(NULL);
867*6777b538SAndroid Build Coastguard Worker     memset(cur, 0, sizeof(xmlEntity));
868*6777b538SAndroid Build Coastguard Worker     cur->type = XML_ENTITY_DECL;
869*6777b538SAndroid Build Coastguard Worker 
870*6777b538SAndroid Build Coastguard Worker     cur->etype = ent->etype;
871*6777b538SAndroid Build Coastguard Worker     if (ent->name != NULL) {
872*6777b538SAndroid Build Coastguard Worker 	cur->name = xmlStrdup(ent->name);
873*6777b538SAndroid Build Coastguard Worker         if (cur->name == NULL)
874*6777b538SAndroid Build Coastguard Worker             goto error;
875*6777b538SAndroid Build Coastguard Worker     }
876*6777b538SAndroid Build Coastguard Worker     if (ent->ExternalID != NULL) {
877*6777b538SAndroid Build Coastguard Worker 	cur->ExternalID = xmlStrdup(ent->ExternalID);
878*6777b538SAndroid Build Coastguard Worker         if (cur->ExternalID == NULL)
879*6777b538SAndroid Build Coastguard Worker             goto error;
880*6777b538SAndroid Build Coastguard Worker     }
881*6777b538SAndroid Build Coastguard Worker     if (ent->SystemID != NULL) {
882*6777b538SAndroid Build Coastguard Worker 	cur->SystemID = xmlStrdup(ent->SystemID);
883*6777b538SAndroid Build Coastguard Worker         if (cur->SystemID == NULL)
884*6777b538SAndroid Build Coastguard Worker             goto error;
885*6777b538SAndroid Build Coastguard Worker     }
886*6777b538SAndroid Build Coastguard Worker     if (ent->content != NULL) {
887*6777b538SAndroid Build Coastguard Worker 	cur->content = xmlStrdup(ent->content);
888*6777b538SAndroid Build Coastguard Worker         if (cur->content == NULL)
889*6777b538SAndroid Build Coastguard Worker             goto error;
890*6777b538SAndroid Build Coastguard Worker     }
891*6777b538SAndroid Build Coastguard Worker     if (ent->orig != NULL) {
892*6777b538SAndroid Build Coastguard Worker 	cur->orig = xmlStrdup(ent->orig);
893*6777b538SAndroid Build Coastguard Worker         if (cur->orig == NULL)
894*6777b538SAndroid Build Coastguard Worker             goto error;
895*6777b538SAndroid Build Coastguard Worker     }
896*6777b538SAndroid Build Coastguard Worker     if (ent->URI != NULL) {
897*6777b538SAndroid Build Coastguard Worker 	cur->URI = xmlStrdup(ent->URI);
898*6777b538SAndroid Build Coastguard Worker         if (cur->URI == NULL)
899*6777b538SAndroid Build Coastguard Worker             goto error;
900*6777b538SAndroid Build Coastguard Worker     }
901*6777b538SAndroid Build Coastguard Worker     return(cur);
902*6777b538SAndroid Build Coastguard Worker 
903*6777b538SAndroid Build Coastguard Worker error:
904*6777b538SAndroid Build Coastguard Worker     xmlFreeEntity(cur);
905*6777b538SAndroid Build Coastguard Worker     return(NULL);
906*6777b538SAndroid Build Coastguard Worker }
907*6777b538SAndroid Build Coastguard Worker 
908*6777b538SAndroid Build Coastguard Worker /**
909*6777b538SAndroid Build Coastguard Worker  * xmlCopyEntitiesTable:
910*6777b538SAndroid Build Coastguard Worker  * @table:  An entity table
911*6777b538SAndroid Build Coastguard Worker  *
912*6777b538SAndroid Build Coastguard Worker  * Build a copy of an entity table.
913*6777b538SAndroid Build Coastguard Worker  *
914*6777b538SAndroid Build Coastguard Worker  * Returns the new xmlEntitiesTablePtr or NULL in case of error.
915*6777b538SAndroid Build Coastguard Worker  */
916*6777b538SAndroid Build Coastguard Worker xmlEntitiesTablePtr
xmlCopyEntitiesTable(xmlEntitiesTablePtr table)917*6777b538SAndroid Build Coastguard Worker xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
918*6777b538SAndroid Build Coastguard Worker     return(xmlHashCopySafe(table, xmlCopyEntity, xmlFreeEntityWrapper));
919*6777b538SAndroid Build Coastguard Worker }
920*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_TREE_ENABLED */
921*6777b538SAndroid Build Coastguard Worker 
922*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
923*6777b538SAndroid Build Coastguard Worker 
924*6777b538SAndroid Build Coastguard Worker /**
925*6777b538SAndroid Build Coastguard Worker  * xmlDumpEntityDecl:
926*6777b538SAndroid Build Coastguard Worker  * @buf:  An XML buffer.
927*6777b538SAndroid Build Coastguard Worker  * @ent:  An entity table
928*6777b538SAndroid Build Coastguard Worker  *
929*6777b538SAndroid Build Coastguard Worker  * This will dump the content of the entity table as an XML DTD definition
930*6777b538SAndroid Build Coastguard Worker  */
931*6777b538SAndroid Build Coastguard Worker void
xmlDumpEntityDecl(xmlBufferPtr buf,xmlEntityPtr ent)932*6777b538SAndroid Build Coastguard Worker xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
933*6777b538SAndroid Build Coastguard Worker     xmlSaveCtxtPtr save;
934*6777b538SAndroid Build Coastguard Worker 
935*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (ent == NULL))
936*6777b538SAndroid Build Coastguard Worker         return;
937*6777b538SAndroid Build Coastguard Worker 
938*6777b538SAndroid Build Coastguard Worker     save = xmlSaveToBuffer(buf, NULL, 0);
939*6777b538SAndroid Build Coastguard Worker     xmlSaveTree(save, (xmlNodePtr) ent);
940*6777b538SAndroid Build Coastguard Worker     xmlSaveClose(save);
941*6777b538SAndroid Build Coastguard Worker }
942*6777b538SAndroid Build Coastguard Worker 
943*6777b538SAndroid Build Coastguard Worker /**
944*6777b538SAndroid Build Coastguard Worker  * xmlDumpEntityDeclScan:
945*6777b538SAndroid Build Coastguard Worker  * @ent:  An entity table
946*6777b538SAndroid Build Coastguard Worker  * @buf:  An XML buffer.
947*6777b538SAndroid Build Coastguard Worker  *
948*6777b538SAndroid Build Coastguard Worker  * When using the hash table scan function, arguments need to be reversed
949*6777b538SAndroid Build Coastguard Worker  */
950*6777b538SAndroid Build Coastguard Worker static void
xmlDumpEntityDeclScan(void * ent,void * buf,const xmlChar * name ATTRIBUTE_UNUSED)951*6777b538SAndroid Build Coastguard Worker xmlDumpEntityDeclScan(void *ent, void *buf,
952*6777b538SAndroid Build Coastguard Worker                       const xmlChar *name ATTRIBUTE_UNUSED) {
953*6777b538SAndroid Build Coastguard Worker     xmlDumpEntityDecl((xmlBufferPtr) buf, (xmlEntityPtr) ent);
954*6777b538SAndroid Build Coastguard Worker }
955*6777b538SAndroid Build Coastguard Worker 
956*6777b538SAndroid Build Coastguard Worker /**
957*6777b538SAndroid Build Coastguard Worker  * xmlDumpEntitiesTable:
958*6777b538SAndroid Build Coastguard Worker  * @buf:  An XML buffer.
959*6777b538SAndroid Build Coastguard Worker  * @table:  An entity table
960*6777b538SAndroid Build Coastguard Worker  *
961*6777b538SAndroid Build Coastguard Worker  * This will dump the content of the entity table as an XML DTD definition
962*6777b538SAndroid Build Coastguard Worker  */
963*6777b538SAndroid Build Coastguard Worker void
xmlDumpEntitiesTable(xmlBufferPtr buf,xmlEntitiesTablePtr table)964*6777b538SAndroid Build Coastguard Worker xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
965*6777b538SAndroid Build Coastguard Worker     xmlHashScan(table, xmlDumpEntityDeclScan, buf);
966*6777b538SAndroid Build Coastguard Worker }
967*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
968