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