pocxxeci 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pocxxeci might be problematic. Click here for more details.
- package/LICENSE +19 -0
- package/Makefile +18 -0
- package/README.md +52 -0
- package/binding.gyp +81 -0
- package/index.d.ts +273 -0
- package/index.js +45 -0
- package/lib/bindings.js +1 -0
- package/lib/document.js +122 -0
- package/lib/element.js +82 -0
- package/lib/sax_parser.js +38 -0
- package/package.json +70 -0
- package/src/html_document.cc +7 -0
- package/src/html_document.h +18 -0
- package/src/libxmljs.cc +252 -0
- package/src/libxmljs.h +53 -0
- package/src/xml_attribute.cc +173 -0
- package/src/xml_attribute.h +40 -0
- package/src/xml_comment.cc +117 -0
- package/src/xml_comment.h +30 -0
- package/src/xml_document.cc +810 -0
- package/src/xml_document.h +67 -0
- package/src/xml_element.cc +565 -0
- package/src/xml_element.h +61 -0
- package/src/xml_namespace.cc +158 -0
- package/src/xml_namespace.h +39 -0
- package/src/xml_node.cc +761 -0
- package/src/xml_node.h +73 -0
- package/src/xml_pi.cc +161 -0
- package/src/xml_pi.h +34 -0
- package/src/xml_sax_parser.cc +424 -0
- package/src/xml_sax_parser.h +73 -0
- package/src/xml_syntax_error.cc +66 -0
- package/src/xml_syntax_error.h +25 -0
- package/src/xml_text.cc +320 -0
- package/src/xml_text.h +48 -0
- package/src/xml_textwriter.cc +315 -0
- package/src/xml_textwriter.h +62 -0
- package/src/xml_xpath_context.cc +70 -0
- package/src/xml_xpath_context.h +23 -0
- package/vendor/libxml/Copyright +23 -0
- package/vendor/libxml/DOCBparser.c +305 -0
- package/vendor/libxml/HTMLparser.c +7287 -0
- package/vendor/libxml/HTMLtree.c +1200 -0
- package/vendor/libxml/Makefile +2983 -0
- package/vendor/libxml/SAX.c +180 -0
- package/vendor/libxml/SAX2.c +3036 -0
- package/vendor/libxml/buf.c +1351 -0
- package/vendor/libxml/buf.h +72 -0
- package/vendor/libxml/c14n.c +2234 -0
- package/vendor/libxml/catalog.c +3828 -0
- package/vendor/libxml/chvalid.c +336 -0
- package/vendor/libxml/config.h +294 -0
- package/vendor/libxml/config.h.gch +0 -0
- package/vendor/libxml/debugXML.c +3423 -0
- package/vendor/libxml/dict.c +1298 -0
- package/vendor/libxml/elfgcchack.h +17818 -0
- package/vendor/libxml/enc.h +32 -0
- package/vendor/libxml/encoding.c +3975 -0
- package/vendor/libxml/entities.c +1163 -0
- package/vendor/libxml/error.c +998 -0
- package/vendor/libxml/globals.c +1126 -0
- package/vendor/libxml/hash.c +1146 -0
- package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
- package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
- package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
- package/vendor/libxml/include/libxml/Makefile +725 -0
- package/vendor/libxml/include/libxml/Makefile.am +54 -0
- package/vendor/libxml/include/libxml/Makefile.in +725 -0
- package/vendor/libxml/include/libxml/SAX.h +173 -0
- package/vendor/libxml/include/libxml/SAX2.h +178 -0
- package/vendor/libxml/include/libxml/c14n.h +128 -0
- package/vendor/libxml/include/libxml/catalog.h +182 -0
- package/vendor/libxml/include/libxml/chvalid.h +230 -0
- package/vendor/libxml/include/libxml/debugXML.h +217 -0
- package/vendor/libxml/include/libxml/dict.h +79 -0
- package/vendor/libxml/include/libxml/encoding.h +245 -0
- package/vendor/libxml/include/libxml/entities.h +151 -0
- package/vendor/libxml/include/libxml/globals.h +508 -0
- package/vendor/libxml/include/libxml/hash.h +236 -0
- package/vendor/libxml/include/libxml/list.h +137 -0
- package/vendor/libxml/include/libxml/nanoftp.h +163 -0
- package/vendor/libxml/include/libxml/nanohttp.h +81 -0
- package/vendor/libxml/include/libxml/parser.h +1243 -0
- package/vendor/libxml/include/libxml/parserInternals.h +644 -0
- package/vendor/libxml/include/libxml/pattern.h +100 -0
- package/vendor/libxml/include/libxml/relaxng.h +217 -0
- package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
- package/vendor/libxml/include/libxml/schematron.h +142 -0
- package/vendor/libxml/include/libxml/threads.h +89 -0
- package/vendor/libxml/include/libxml/tree.h +1311 -0
- package/vendor/libxml/include/libxml/uri.h +94 -0
- package/vendor/libxml/include/libxml/valid.h +458 -0
- package/vendor/libxml/include/libxml/xinclude.h +129 -0
- package/vendor/libxml/include/libxml/xlink.h +189 -0
- package/vendor/libxml/include/libxml/xmlIO.h +368 -0
- package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
- package/vendor/libxml/include/libxml/xmlerror.h +945 -0
- package/vendor/libxml/include/libxml/xmlexports.h +77 -0
- package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
- package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
- package/vendor/libxml/include/libxml/xmlreader.h +428 -0
- package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
- package/vendor/libxml/include/libxml/xmlsave.h +88 -0
- package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
- package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
- package/vendor/libxml/include/libxml/xmlstring.h +140 -0
- package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
- package/vendor/libxml/include/libxml/xmlversion.h +484 -0
- package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
- package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
- package/vendor/libxml/include/libxml/xpath.h +564 -0
- package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
- package/vendor/libxml/include/libxml/xpointer.h +114 -0
- package/vendor/libxml/include/win32config.h +122 -0
- package/vendor/libxml/include/wsockcompat.h +54 -0
- package/vendor/libxml/legacy.c +1343 -0
- package/vendor/libxml/libxml.h +134 -0
- package/vendor/libxml/list.c +779 -0
- package/vendor/libxml/nanoftp.c +2118 -0
- package/vendor/libxml/nanohttp.c +1899 -0
- package/vendor/libxml/parser.c +15553 -0
- package/vendor/libxml/parserInternals.c +2164 -0
- package/vendor/libxml/pattern.c +2621 -0
- package/vendor/libxml/relaxng.c +11101 -0
- package/vendor/libxml/rngparser.c +1595 -0
- package/vendor/libxml/runsuite.c +1157 -0
- package/vendor/libxml/save.h +36 -0
- package/vendor/libxml/schematron.c +1787 -0
- package/vendor/libxml/threads.c +1049 -0
- package/vendor/libxml/timsort.h +601 -0
- package/vendor/libxml/tree.c +10183 -0
- package/vendor/libxml/trio.c +6895 -0
- package/vendor/libxml/trio.h +230 -0
- package/vendor/libxml/triodef.h +228 -0
- package/vendor/libxml/trionan.c +914 -0
- package/vendor/libxml/trionan.h +84 -0
- package/vendor/libxml/triop.h +150 -0
- package/vendor/libxml/triostr.c +2112 -0
- package/vendor/libxml/triostr.h +144 -0
- package/vendor/libxml/uri.c +2561 -0
- package/vendor/libxml/valid.c +7138 -0
- package/vendor/libxml/xinclude.c +2657 -0
- package/vendor/libxml/xlink.c +183 -0
- package/vendor/libxml/xmlIO.c +4135 -0
- package/vendor/libxml/xmlcatalog.c +624 -0
- package/vendor/libxml/xmllint.c +3796 -0
- package/vendor/libxml/xmlmemory.c +1163 -0
- package/vendor/libxml/xmlmodule.c +468 -0
- package/vendor/libxml/xmlreader.c +6033 -0
- package/vendor/libxml/xmlregexp.c +8271 -0
- package/vendor/libxml/xmlsave.c +2735 -0
- package/vendor/libxml/xmlschemas.c +29173 -0
- package/vendor/libxml/xmlschemastypes.c +6276 -0
- package/vendor/libxml/xmlstring.c +1050 -0
- package/vendor/libxml/xmlunicode.c +3179 -0
- package/vendor/libxml/xmlwriter.c +4738 -0
- package/vendor/libxml/xpath.c +14734 -0
- package/vendor/libxml/xpointer.c +2969 -0
- package/vendor/libxml/xzlib.c +815 -0
- package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1351 @@
|
|
1
|
+
/*
|
2
|
+
* buf.c: memory buffers for libxml2
|
3
|
+
*
|
4
|
+
* new buffer structures and entry points to simplify the maintenance
|
5
|
+
* of libxml2 and ensure we keep good control over memory allocations
|
6
|
+
* and stay 64 bits clean.
|
7
|
+
* The new entry point use the xmlBufPtr opaque structure and
|
8
|
+
* xmlBuf...() counterparts to the old xmlBuf...() functions
|
9
|
+
*
|
10
|
+
* See Copyright for the status of this software.
|
11
|
+
*
|
12
|
+
* daniel@veillard.com
|
13
|
+
*/
|
14
|
+
|
15
|
+
#define IN_LIBXML
|
16
|
+
#include "libxml.h"
|
17
|
+
|
18
|
+
#include <string.h> /* for memset() only ! */
|
19
|
+
#include <limits.h>
|
20
|
+
#ifdef HAVE_CTYPE_H
|
21
|
+
#include <ctype.h>
|
22
|
+
#endif
|
23
|
+
#ifdef HAVE_STDLIB_H
|
24
|
+
#include <stdlib.h>
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#include <libxml/tree.h>
|
28
|
+
#include <libxml/globals.h>
|
29
|
+
#include <libxml/tree.h>
|
30
|
+
#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
|
31
|
+
#include "buf.h"
|
32
|
+
|
33
|
+
#define WITH_BUFFER_COMPAT
|
34
|
+
|
35
|
+
/**
|
36
|
+
* xmlBuf:
|
37
|
+
*
|
38
|
+
* A buffer structure. The base of the structure is somehow compatible
|
39
|
+
* with struct _xmlBuffer to limit risks on application which accessed
|
40
|
+
* directly the input->buf->buffer structures.
|
41
|
+
*/
|
42
|
+
|
43
|
+
struct _xmlBuf {
|
44
|
+
xmlChar *content; /* The buffer content UTF8 */
|
45
|
+
unsigned int compat_use; /* for binary compatibility */
|
46
|
+
unsigned int compat_size; /* for binary compatibility */
|
47
|
+
xmlBufferAllocationScheme alloc; /* The realloc method */
|
48
|
+
xmlChar *contentIO; /* in IO mode we may have a different base */
|
49
|
+
size_t use; /* The buffer size used */
|
50
|
+
size_t size; /* The buffer size */
|
51
|
+
xmlBufferPtr buffer; /* wrapper for an old buffer */
|
52
|
+
int error; /* an error code if a failure occurred */
|
53
|
+
};
|
54
|
+
|
55
|
+
#ifdef WITH_BUFFER_COMPAT
|
56
|
+
/*
|
57
|
+
* Macro for compatibility with xmlBuffer to be used after an xmlBuf
|
58
|
+
* is updated. This makes sure the compat fields are updated too.
|
59
|
+
*/
|
60
|
+
#define UPDATE_COMPAT(buf) \
|
61
|
+
if (buf->size < INT_MAX) buf->compat_size = buf->size; \
|
62
|
+
else buf->compat_size = INT_MAX; \
|
63
|
+
if (buf->use < INT_MAX) buf->compat_use = buf->use; \
|
64
|
+
else buf->compat_use = INT_MAX;
|
65
|
+
|
66
|
+
/*
|
67
|
+
* Macro for compatibility with xmlBuffer to be used in all the xmlBuf
|
68
|
+
* entry points, it checks that the compat fields have not been modified
|
69
|
+
* by direct call to xmlBuffer function from code compiled before 2.9.0 .
|
70
|
+
*/
|
71
|
+
#define CHECK_COMPAT(buf) \
|
72
|
+
if (buf->size != (size_t) buf->compat_size) \
|
73
|
+
if (buf->compat_size < INT_MAX) \
|
74
|
+
buf->size = buf->compat_size; \
|
75
|
+
if (buf->use != (size_t) buf->compat_use) \
|
76
|
+
if (buf->compat_use < INT_MAX) \
|
77
|
+
buf->use = buf->compat_use;
|
78
|
+
|
79
|
+
#else /* ! WITH_BUFFER_COMPAT */
|
80
|
+
#define UPDATE_COMPAT(buf)
|
81
|
+
#define CHECK_COMPAT(buf)
|
82
|
+
#endif /* WITH_BUFFER_COMPAT */
|
83
|
+
|
84
|
+
/**
|
85
|
+
* xmlBufMemoryError:
|
86
|
+
* @extra: extra information
|
87
|
+
*
|
88
|
+
* Handle an out of memory condition
|
89
|
+
* To be improved...
|
90
|
+
*/
|
91
|
+
static void
|
92
|
+
xmlBufMemoryError(xmlBufPtr buf, const char *extra)
|
93
|
+
{
|
94
|
+
__xmlSimpleError(XML_FROM_BUFFER, XML_ERR_NO_MEMORY, NULL, NULL, extra);
|
95
|
+
if ((buf) && (buf->error == 0))
|
96
|
+
buf->error = XML_ERR_NO_MEMORY;
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* xmlBufOverflowError:
|
101
|
+
* @extra: extra information
|
102
|
+
*
|
103
|
+
* Handle a buffer overflow error
|
104
|
+
* To be improved...
|
105
|
+
*/
|
106
|
+
static void
|
107
|
+
xmlBufOverflowError(xmlBufPtr buf, const char *extra)
|
108
|
+
{
|
109
|
+
__xmlSimpleError(XML_FROM_BUFFER, XML_BUF_OVERFLOW, NULL, NULL, extra);
|
110
|
+
if ((buf) && (buf->error == 0))
|
111
|
+
buf->error = XML_BUF_OVERFLOW;
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
/**
|
116
|
+
* xmlBufCreate:
|
117
|
+
*
|
118
|
+
* routine to create an XML buffer.
|
119
|
+
* returns the new structure.
|
120
|
+
*/
|
121
|
+
xmlBufPtr
|
122
|
+
xmlBufCreate(void) {
|
123
|
+
xmlBufPtr ret;
|
124
|
+
|
125
|
+
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
|
126
|
+
if (ret == NULL) {
|
127
|
+
xmlBufMemoryError(NULL, "creating buffer");
|
128
|
+
return(NULL);
|
129
|
+
}
|
130
|
+
ret->compat_use = 0;
|
131
|
+
ret->use = 0;
|
132
|
+
ret->error = 0;
|
133
|
+
ret->buffer = NULL;
|
134
|
+
ret->size = xmlDefaultBufferSize;
|
135
|
+
ret->compat_size = xmlDefaultBufferSize;
|
136
|
+
ret->alloc = xmlBufferAllocScheme;
|
137
|
+
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
|
138
|
+
if (ret->content == NULL) {
|
139
|
+
xmlBufMemoryError(ret, "creating buffer");
|
140
|
+
xmlFree(ret);
|
141
|
+
return(NULL);
|
142
|
+
}
|
143
|
+
ret->content[0] = 0;
|
144
|
+
ret->contentIO = NULL;
|
145
|
+
return(ret);
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* xmlBufCreateSize:
|
150
|
+
* @size: initial size of buffer
|
151
|
+
*
|
152
|
+
* routine to create an XML buffer.
|
153
|
+
* returns the new structure.
|
154
|
+
*/
|
155
|
+
xmlBufPtr
|
156
|
+
xmlBufCreateSize(size_t size) {
|
157
|
+
xmlBufPtr ret;
|
158
|
+
|
159
|
+
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
|
160
|
+
if (ret == NULL) {
|
161
|
+
xmlBufMemoryError(NULL, "creating buffer");
|
162
|
+
return(NULL);
|
163
|
+
}
|
164
|
+
ret->compat_use = 0;
|
165
|
+
ret->use = 0;
|
166
|
+
ret->error = 0;
|
167
|
+
ret->buffer = NULL;
|
168
|
+
ret->alloc = xmlBufferAllocScheme;
|
169
|
+
ret->size = (size ? size+2 : 0); /* +1 for ending null */
|
170
|
+
ret->compat_size = (int) ret->size;
|
171
|
+
if (ret->size){
|
172
|
+
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
|
173
|
+
if (ret->content == NULL) {
|
174
|
+
xmlBufMemoryError(ret, "creating buffer");
|
175
|
+
xmlFree(ret);
|
176
|
+
return(NULL);
|
177
|
+
}
|
178
|
+
ret->content[0] = 0;
|
179
|
+
} else
|
180
|
+
ret->content = NULL;
|
181
|
+
ret->contentIO = NULL;
|
182
|
+
return(ret);
|
183
|
+
}
|
184
|
+
|
185
|
+
/**
|
186
|
+
* xmlBufDetach:
|
187
|
+
* @buf: the buffer
|
188
|
+
*
|
189
|
+
* Remove the string contained in a buffer and give it back to the
|
190
|
+
* caller. The buffer is reset to an empty content.
|
191
|
+
* This doesn't work with immutable buffers as they can't be reset.
|
192
|
+
*
|
193
|
+
* Returns the previous string contained by the buffer.
|
194
|
+
*/
|
195
|
+
xmlChar *
|
196
|
+
xmlBufDetach(xmlBufPtr buf) {
|
197
|
+
xmlChar *ret;
|
198
|
+
|
199
|
+
if (buf == NULL)
|
200
|
+
return(NULL);
|
201
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
|
202
|
+
return(NULL);
|
203
|
+
if (buf->buffer != NULL)
|
204
|
+
return(NULL);
|
205
|
+
if (buf->error)
|
206
|
+
return(NULL);
|
207
|
+
|
208
|
+
ret = buf->content;
|
209
|
+
buf->content = NULL;
|
210
|
+
buf->size = 0;
|
211
|
+
buf->use = 0;
|
212
|
+
buf->compat_use = 0;
|
213
|
+
buf->compat_size = 0;
|
214
|
+
|
215
|
+
return ret;
|
216
|
+
}
|
217
|
+
|
218
|
+
|
219
|
+
/**
|
220
|
+
* xmlBufCreateStatic:
|
221
|
+
* @mem: the memory area
|
222
|
+
* @size: the size in byte
|
223
|
+
*
|
224
|
+
* routine to create an XML buffer from an immutable memory area.
|
225
|
+
* The area won't be modified nor copied, and is expected to be
|
226
|
+
* present until the end of the buffer lifetime.
|
227
|
+
*
|
228
|
+
* returns the new structure.
|
229
|
+
*/
|
230
|
+
xmlBufPtr
|
231
|
+
xmlBufCreateStatic(void *mem, size_t size) {
|
232
|
+
xmlBufPtr ret;
|
233
|
+
|
234
|
+
if (mem == NULL)
|
235
|
+
return(NULL);
|
236
|
+
|
237
|
+
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
|
238
|
+
if (ret == NULL) {
|
239
|
+
xmlBufMemoryError(NULL, "creating buffer");
|
240
|
+
return(NULL);
|
241
|
+
}
|
242
|
+
if (size < INT_MAX) {
|
243
|
+
ret->compat_use = size;
|
244
|
+
ret->compat_size = size;
|
245
|
+
} else {
|
246
|
+
ret->compat_use = INT_MAX;
|
247
|
+
ret->compat_size = INT_MAX;
|
248
|
+
}
|
249
|
+
ret->use = size;
|
250
|
+
ret->size = size;
|
251
|
+
ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE;
|
252
|
+
ret->content = (xmlChar *) mem;
|
253
|
+
ret->error = 0;
|
254
|
+
ret->buffer = NULL;
|
255
|
+
return(ret);
|
256
|
+
}
|
257
|
+
|
258
|
+
/**
|
259
|
+
* xmlBufGetAllocationScheme:
|
260
|
+
* @buf: the buffer
|
261
|
+
*
|
262
|
+
* Get the buffer allocation scheme
|
263
|
+
*
|
264
|
+
* Returns the scheme or -1 in case of error
|
265
|
+
*/
|
266
|
+
int
|
267
|
+
xmlBufGetAllocationScheme(xmlBufPtr buf) {
|
268
|
+
if (buf == NULL) {
|
269
|
+
#ifdef DEBUG_BUFFER
|
270
|
+
xmlGenericError(xmlGenericErrorContext,
|
271
|
+
"xmlBufGetAllocationScheme: buf == NULL\n");
|
272
|
+
#endif
|
273
|
+
return(-1);
|
274
|
+
}
|
275
|
+
return(buf->alloc);
|
276
|
+
}
|
277
|
+
|
278
|
+
/**
|
279
|
+
* xmlBufSetAllocationScheme:
|
280
|
+
* @buf: the buffer to tune
|
281
|
+
* @scheme: allocation scheme to use
|
282
|
+
*
|
283
|
+
* Sets the allocation scheme for this buffer
|
284
|
+
*
|
285
|
+
* returns 0 in case of success and -1 in case of failure
|
286
|
+
*/
|
287
|
+
int
|
288
|
+
xmlBufSetAllocationScheme(xmlBufPtr buf,
|
289
|
+
xmlBufferAllocationScheme scheme) {
|
290
|
+
if ((buf == NULL) || (buf->error != 0)) {
|
291
|
+
#ifdef DEBUG_BUFFER
|
292
|
+
xmlGenericError(xmlGenericErrorContext,
|
293
|
+
"xmlBufSetAllocationScheme: buf == NULL or in error\n");
|
294
|
+
#endif
|
295
|
+
return(-1);
|
296
|
+
}
|
297
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
|
298
|
+
(buf->alloc == XML_BUFFER_ALLOC_IO))
|
299
|
+
return(-1);
|
300
|
+
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
|
301
|
+
(scheme == XML_BUFFER_ALLOC_EXACT) ||
|
302
|
+
(scheme == XML_BUFFER_ALLOC_HYBRID) ||
|
303
|
+
(scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
|
304
|
+
(scheme == XML_BUFFER_ALLOC_BOUNDED)) {
|
305
|
+
buf->alloc = scheme;
|
306
|
+
if (buf->buffer)
|
307
|
+
buf->buffer->alloc = scheme;
|
308
|
+
return(0);
|
309
|
+
}
|
310
|
+
/*
|
311
|
+
* Switching a buffer ALLOC_IO has the side effect of initializing
|
312
|
+
* the contentIO field with the current content
|
313
|
+
*/
|
314
|
+
if (scheme == XML_BUFFER_ALLOC_IO) {
|
315
|
+
buf->alloc = XML_BUFFER_ALLOC_IO;
|
316
|
+
buf->contentIO = buf->content;
|
317
|
+
}
|
318
|
+
return(-1);
|
319
|
+
}
|
320
|
+
|
321
|
+
/**
|
322
|
+
* xmlBufFree:
|
323
|
+
* @buf: the buffer to free
|
324
|
+
*
|
325
|
+
* Frees an XML buffer. It frees both the content and the structure which
|
326
|
+
* encapsulate it.
|
327
|
+
*/
|
328
|
+
void
|
329
|
+
xmlBufFree(xmlBufPtr buf) {
|
330
|
+
if (buf == NULL) {
|
331
|
+
#ifdef DEBUG_BUFFER
|
332
|
+
xmlGenericError(xmlGenericErrorContext,
|
333
|
+
"xmlBufFree: buf == NULL\n");
|
334
|
+
#endif
|
335
|
+
return;
|
336
|
+
}
|
337
|
+
|
338
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
|
339
|
+
(buf->contentIO != NULL)) {
|
340
|
+
xmlFree(buf->contentIO);
|
341
|
+
} else if ((buf->content != NULL) &&
|
342
|
+
(buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)) {
|
343
|
+
xmlFree(buf->content);
|
344
|
+
}
|
345
|
+
xmlFree(buf);
|
346
|
+
}
|
347
|
+
|
348
|
+
/**
|
349
|
+
* xmlBufEmpty:
|
350
|
+
* @buf: the buffer
|
351
|
+
*
|
352
|
+
* empty a buffer.
|
353
|
+
*/
|
354
|
+
void
|
355
|
+
xmlBufEmpty(xmlBufPtr buf) {
|
356
|
+
if ((buf == NULL) || (buf->error != 0)) return;
|
357
|
+
if (buf->content == NULL) return;
|
358
|
+
CHECK_COMPAT(buf)
|
359
|
+
buf->use = 0;
|
360
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) {
|
361
|
+
buf->content = BAD_CAST "";
|
362
|
+
} else if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
|
363
|
+
(buf->contentIO != NULL)) {
|
364
|
+
size_t start_buf = buf->content - buf->contentIO;
|
365
|
+
|
366
|
+
buf->size += start_buf;
|
367
|
+
buf->content = buf->contentIO;
|
368
|
+
buf->content[0] = 0;
|
369
|
+
} else {
|
370
|
+
buf->content[0] = 0;
|
371
|
+
}
|
372
|
+
UPDATE_COMPAT(buf)
|
373
|
+
}
|
374
|
+
|
375
|
+
/**
|
376
|
+
* xmlBufShrink:
|
377
|
+
* @buf: the buffer to dump
|
378
|
+
* @len: the number of xmlChar to remove
|
379
|
+
*
|
380
|
+
* Remove the beginning of an XML buffer.
|
381
|
+
* NOTE that this routine behaviour differs from xmlBufferShrink()
|
382
|
+
* as it will return 0 on error instead of -1 due to size_t being
|
383
|
+
* used as the return type.
|
384
|
+
*
|
385
|
+
* Returns the number of byte removed or 0 in case of failure
|
386
|
+
*/
|
387
|
+
size_t
|
388
|
+
xmlBufShrink(xmlBufPtr buf, size_t len) {
|
389
|
+
if ((buf == NULL) || (buf->error != 0)) return(0);
|
390
|
+
CHECK_COMPAT(buf)
|
391
|
+
if (len == 0) return(0);
|
392
|
+
if (len > buf->use) return(0);
|
393
|
+
|
394
|
+
buf->use -= len;
|
395
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
|
396
|
+
((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
|
397
|
+
/*
|
398
|
+
* we just move the content pointer, but also make sure
|
399
|
+
* the perceived buffer size has shrunk accordingly
|
400
|
+
*/
|
401
|
+
buf->content += len;
|
402
|
+
buf->size -= len;
|
403
|
+
|
404
|
+
/*
|
405
|
+
* sometimes though it maybe be better to really shrink
|
406
|
+
* on IO buffers
|
407
|
+
*/
|
408
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
|
409
|
+
size_t start_buf = buf->content - buf->contentIO;
|
410
|
+
if (start_buf >= buf->size) {
|
411
|
+
memmove(buf->contentIO, &buf->content[0], buf->use);
|
412
|
+
buf->content = buf->contentIO;
|
413
|
+
buf->content[buf->use] = 0;
|
414
|
+
buf->size += start_buf;
|
415
|
+
}
|
416
|
+
}
|
417
|
+
} else {
|
418
|
+
memmove(buf->content, &buf->content[len], buf->use);
|
419
|
+
buf->content[buf->use] = 0;
|
420
|
+
}
|
421
|
+
UPDATE_COMPAT(buf)
|
422
|
+
return(len);
|
423
|
+
}
|
424
|
+
|
425
|
+
/**
|
426
|
+
* xmlBufGrowInternal:
|
427
|
+
* @buf: the buffer
|
428
|
+
* @len: the minimum free size to allocate
|
429
|
+
*
|
430
|
+
* Grow the available space of an XML buffer, @len is the target value
|
431
|
+
* Error checking should be done on buf->error since using the return
|
432
|
+
* value doesn't work that well
|
433
|
+
*
|
434
|
+
* Returns 0 in case of error or the length made available otherwise
|
435
|
+
*/
|
436
|
+
static size_t
|
437
|
+
xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
|
438
|
+
size_t size;
|
439
|
+
xmlChar *newbuf;
|
440
|
+
|
441
|
+
if ((buf == NULL) || (buf->error != 0)) return(0);
|
442
|
+
CHECK_COMPAT(buf)
|
443
|
+
|
444
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
|
445
|
+
if (buf->use + len < buf->size)
|
446
|
+
return(buf->size - buf->use);
|
447
|
+
|
448
|
+
/*
|
449
|
+
* Windows has a BIG problem on realloc timing, so we try to double
|
450
|
+
* the buffer size (if that's enough) (bug 146697)
|
451
|
+
* Apparently BSD too, and it's probably best for linux too
|
452
|
+
* On an embedded system this may be something to change
|
453
|
+
*/
|
454
|
+
#if 1
|
455
|
+
if (buf->size > (size_t) len)
|
456
|
+
size = buf->size * 2;
|
457
|
+
else
|
458
|
+
size = buf->use + len + 100;
|
459
|
+
#else
|
460
|
+
size = buf->use + len + 100;
|
461
|
+
#endif
|
462
|
+
|
463
|
+
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
464
|
+
/*
|
465
|
+
* Used to provide parsing limits
|
466
|
+
*/
|
467
|
+
if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
|
468
|
+
(buf->size >= XML_MAX_TEXT_LENGTH)) {
|
469
|
+
xmlBufMemoryError(buf, "buffer error: text too long\n");
|
470
|
+
return(0);
|
471
|
+
}
|
472
|
+
if (size >= XML_MAX_TEXT_LENGTH)
|
473
|
+
size = XML_MAX_TEXT_LENGTH;
|
474
|
+
}
|
475
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
|
476
|
+
size_t start_buf = buf->content - buf->contentIO;
|
477
|
+
|
478
|
+
newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
|
479
|
+
if (newbuf == NULL) {
|
480
|
+
xmlBufMemoryError(buf, "growing buffer");
|
481
|
+
return(0);
|
482
|
+
}
|
483
|
+
buf->contentIO = newbuf;
|
484
|
+
buf->content = newbuf + start_buf;
|
485
|
+
} else {
|
486
|
+
newbuf = (xmlChar *) xmlRealloc(buf->content, size);
|
487
|
+
if (newbuf == NULL) {
|
488
|
+
xmlBufMemoryError(buf, "growing buffer");
|
489
|
+
return(0);
|
490
|
+
}
|
491
|
+
buf->content = newbuf;
|
492
|
+
}
|
493
|
+
buf->size = size;
|
494
|
+
UPDATE_COMPAT(buf)
|
495
|
+
return(buf->size - buf->use);
|
496
|
+
}
|
497
|
+
|
498
|
+
/**
|
499
|
+
* xmlBufGrow:
|
500
|
+
* @buf: the buffer
|
501
|
+
* @len: the minimum free size to allocate
|
502
|
+
*
|
503
|
+
* Grow the available space of an XML buffer, @len is the target value
|
504
|
+
* This is been kept compatible with xmlBufferGrow() as much as possible
|
505
|
+
*
|
506
|
+
* Returns -1 in case of error or the length made available otherwise
|
507
|
+
*/
|
508
|
+
int
|
509
|
+
xmlBufGrow(xmlBufPtr buf, int len) {
|
510
|
+
size_t ret;
|
511
|
+
|
512
|
+
if ((buf == NULL) || (len < 0)) return(-1);
|
513
|
+
if (len == 0)
|
514
|
+
return(0);
|
515
|
+
ret = xmlBufGrowInternal(buf, len);
|
516
|
+
if (buf->error != 0)
|
517
|
+
return(-1);
|
518
|
+
return((int) ret);
|
519
|
+
}
|
520
|
+
|
521
|
+
/**
|
522
|
+
* xmlBufInflate:
|
523
|
+
* @buf: the buffer
|
524
|
+
* @len: the minimum extra free size to allocate
|
525
|
+
*
|
526
|
+
* Grow the available space of an XML buffer, adding at least @len bytes
|
527
|
+
*
|
528
|
+
* Returns 0 if successful or -1 in case of error
|
529
|
+
*/
|
530
|
+
int
|
531
|
+
xmlBufInflate(xmlBufPtr buf, size_t len) {
|
532
|
+
if (buf == NULL) return(-1);
|
533
|
+
xmlBufGrowInternal(buf, len + buf->size);
|
534
|
+
if (buf->error)
|
535
|
+
return(-1);
|
536
|
+
return(0);
|
537
|
+
}
|
538
|
+
|
539
|
+
/**
|
540
|
+
* xmlBufDump:
|
541
|
+
* @file: the file output
|
542
|
+
* @buf: the buffer to dump
|
543
|
+
*
|
544
|
+
* Dumps an XML buffer to a FILE *.
|
545
|
+
* Returns the number of #xmlChar written
|
546
|
+
*/
|
547
|
+
size_t
|
548
|
+
xmlBufDump(FILE *file, xmlBufPtr buf) {
|
549
|
+
size_t ret;
|
550
|
+
|
551
|
+
if ((buf == NULL) || (buf->error != 0)) {
|
552
|
+
#ifdef DEBUG_BUFFER
|
553
|
+
xmlGenericError(xmlGenericErrorContext,
|
554
|
+
"xmlBufDump: buf == NULL or in error\n");
|
555
|
+
#endif
|
556
|
+
return(0);
|
557
|
+
}
|
558
|
+
if (buf->content == NULL) {
|
559
|
+
#ifdef DEBUG_BUFFER
|
560
|
+
xmlGenericError(xmlGenericErrorContext,
|
561
|
+
"xmlBufDump: buf->content == NULL\n");
|
562
|
+
#endif
|
563
|
+
return(0);
|
564
|
+
}
|
565
|
+
CHECK_COMPAT(buf)
|
566
|
+
if (file == NULL)
|
567
|
+
file = stdout;
|
568
|
+
ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
|
569
|
+
return(ret);
|
570
|
+
}
|
571
|
+
|
572
|
+
/**
|
573
|
+
* xmlBufContent:
|
574
|
+
* @buf: the buffer
|
575
|
+
*
|
576
|
+
* Function to extract the content of a buffer
|
577
|
+
*
|
578
|
+
* Returns the internal content
|
579
|
+
*/
|
580
|
+
|
581
|
+
xmlChar *
|
582
|
+
xmlBufContent(const xmlBuf *buf)
|
583
|
+
{
|
584
|
+
if ((!buf) || (buf->error))
|
585
|
+
return NULL;
|
586
|
+
|
587
|
+
return(buf->content);
|
588
|
+
}
|
589
|
+
|
590
|
+
/**
|
591
|
+
* xmlBufEnd:
|
592
|
+
* @buf: the buffer
|
593
|
+
*
|
594
|
+
* Function to extract the end of the content of a buffer
|
595
|
+
*
|
596
|
+
* Returns the end of the internal content or NULL in case of error
|
597
|
+
*/
|
598
|
+
|
599
|
+
xmlChar *
|
600
|
+
xmlBufEnd(xmlBufPtr buf)
|
601
|
+
{
|
602
|
+
if ((!buf) || (buf->error))
|
603
|
+
return NULL;
|
604
|
+
CHECK_COMPAT(buf)
|
605
|
+
|
606
|
+
return(&buf->content[buf->use]);
|
607
|
+
}
|
608
|
+
|
609
|
+
/**
|
610
|
+
* xmlBufAddLen:
|
611
|
+
* @buf: the buffer
|
612
|
+
* @len: the size which were added at the end
|
613
|
+
*
|
614
|
+
* Sometime data may be added at the end of the buffer without
|
615
|
+
* using the xmlBuf APIs that is used to expand the used space
|
616
|
+
* and set the zero terminating at the end of the buffer
|
617
|
+
*
|
618
|
+
* Returns -1 in case of error and 0 otherwise
|
619
|
+
*/
|
620
|
+
int
|
621
|
+
xmlBufAddLen(xmlBufPtr buf, size_t len) {
|
622
|
+
if ((buf == NULL) || (buf->error))
|
623
|
+
return(-1);
|
624
|
+
CHECK_COMPAT(buf)
|
625
|
+
if (len > (buf->size - buf->use))
|
626
|
+
return(-1);
|
627
|
+
buf->use += len;
|
628
|
+
UPDATE_COMPAT(buf)
|
629
|
+
if (buf->size > buf->use)
|
630
|
+
buf->content[buf->use] = 0;
|
631
|
+
else
|
632
|
+
return(-1);
|
633
|
+
return(0);
|
634
|
+
}
|
635
|
+
|
636
|
+
/**
|
637
|
+
* xmlBufErase:
|
638
|
+
* @buf: the buffer
|
639
|
+
* @len: the size to erase at the end
|
640
|
+
*
|
641
|
+
* Sometime data need to be erased at the end of the buffer
|
642
|
+
*
|
643
|
+
* Returns -1 in case of error and 0 otherwise
|
644
|
+
*/
|
645
|
+
int
|
646
|
+
xmlBufErase(xmlBufPtr buf, size_t len) {
|
647
|
+
if ((buf == NULL) || (buf->error))
|
648
|
+
return(-1);
|
649
|
+
CHECK_COMPAT(buf)
|
650
|
+
if (len > buf->use)
|
651
|
+
return(-1);
|
652
|
+
buf->use -= len;
|
653
|
+
buf->content[buf->use] = 0;
|
654
|
+
UPDATE_COMPAT(buf)
|
655
|
+
return(0);
|
656
|
+
}
|
657
|
+
|
658
|
+
/**
|
659
|
+
* xmlBufLength:
|
660
|
+
* @buf: the buffer
|
661
|
+
*
|
662
|
+
* Function to get the length of a buffer
|
663
|
+
*
|
664
|
+
* Returns the length of data in the internal content
|
665
|
+
*/
|
666
|
+
|
667
|
+
size_t
|
668
|
+
xmlBufLength(const xmlBufPtr buf)
|
669
|
+
{
|
670
|
+
if ((!buf) || (buf->error))
|
671
|
+
return 0;
|
672
|
+
CHECK_COMPAT(buf)
|
673
|
+
|
674
|
+
return(buf->use);
|
675
|
+
}
|
676
|
+
|
677
|
+
/**
|
678
|
+
* xmlBufUse:
|
679
|
+
* @buf: the buffer
|
680
|
+
*
|
681
|
+
* Function to get the length of a buffer
|
682
|
+
*
|
683
|
+
* Returns the length of data in the internal content
|
684
|
+
*/
|
685
|
+
|
686
|
+
size_t
|
687
|
+
xmlBufUse(const xmlBufPtr buf)
|
688
|
+
{
|
689
|
+
if ((!buf) || (buf->error))
|
690
|
+
return 0;
|
691
|
+
CHECK_COMPAT(buf)
|
692
|
+
|
693
|
+
return(buf->use);
|
694
|
+
}
|
695
|
+
|
696
|
+
/**
|
697
|
+
* xmlBufAvail:
|
698
|
+
* @buf: the buffer
|
699
|
+
*
|
700
|
+
* Function to find how much free space is allocated but not
|
701
|
+
* used in the buffer. It does not account for the terminating zero
|
702
|
+
* usually needed
|
703
|
+
*
|
704
|
+
* Returns the amount or 0 if none or an error occurred
|
705
|
+
*/
|
706
|
+
|
707
|
+
size_t
|
708
|
+
xmlBufAvail(const xmlBufPtr buf)
|
709
|
+
{
|
710
|
+
if ((!buf) || (buf->error))
|
711
|
+
return 0;
|
712
|
+
CHECK_COMPAT(buf)
|
713
|
+
|
714
|
+
return(buf->size - buf->use);
|
715
|
+
}
|
716
|
+
|
717
|
+
/**
|
718
|
+
* xmlBufIsEmpty:
|
719
|
+
* @buf: the buffer
|
720
|
+
*
|
721
|
+
* Tell if a buffer is empty
|
722
|
+
*
|
723
|
+
* Returns 0 if no, 1 if yes and -1 in case of error
|
724
|
+
*/
|
725
|
+
int
|
726
|
+
xmlBufIsEmpty(const xmlBufPtr buf)
|
727
|
+
{
|
728
|
+
if ((!buf) || (buf->error))
|
729
|
+
return(-1);
|
730
|
+
CHECK_COMPAT(buf)
|
731
|
+
|
732
|
+
return(buf->use == 0);
|
733
|
+
}
|
734
|
+
|
735
|
+
/**
|
736
|
+
* xmlBufResize:
|
737
|
+
* @buf: the buffer to resize
|
738
|
+
* @size: the desired size
|
739
|
+
*
|
740
|
+
* Resize a buffer to accommodate minimum size of @size.
|
741
|
+
*
|
742
|
+
* Returns 0 in case of problems, 1 otherwise
|
743
|
+
*/
|
744
|
+
int
|
745
|
+
xmlBufResize(xmlBufPtr buf, size_t size)
|
746
|
+
{
|
747
|
+
unsigned int newSize;
|
748
|
+
xmlChar* rebuf = NULL;
|
749
|
+
size_t start_buf;
|
750
|
+
|
751
|
+
if ((buf == NULL) || (buf->error))
|
752
|
+
return(0);
|
753
|
+
CHECK_COMPAT(buf)
|
754
|
+
|
755
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
|
756
|
+
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
757
|
+
/*
|
758
|
+
* Used to provide parsing limits
|
759
|
+
*/
|
760
|
+
if (size >= XML_MAX_TEXT_LENGTH) {
|
761
|
+
xmlBufMemoryError(buf, "buffer error: text too long\n");
|
762
|
+
return(0);
|
763
|
+
}
|
764
|
+
}
|
765
|
+
|
766
|
+
/* Don't resize if we don't have to */
|
767
|
+
if (size < buf->size)
|
768
|
+
return 1;
|
769
|
+
|
770
|
+
/* figure out new size */
|
771
|
+
switch (buf->alloc){
|
772
|
+
case XML_BUFFER_ALLOC_IO:
|
773
|
+
case XML_BUFFER_ALLOC_DOUBLEIT:
|
774
|
+
/*take care of empty case*/
|
775
|
+
newSize = (buf->size ? buf->size*2 : size + 10);
|
776
|
+
while (size > newSize) {
|
777
|
+
if (newSize > UINT_MAX / 2) {
|
778
|
+
xmlBufMemoryError(buf, "growing buffer");
|
779
|
+
return 0;
|
780
|
+
}
|
781
|
+
newSize *= 2;
|
782
|
+
}
|
783
|
+
break;
|
784
|
+
case XML_BUFFER_ALLOC_EXACT:
|
785
|
+
newSize = size+10;
|
786
|
+
break;
|
787
|
+
case XML_BUFFER_ALLOC_HYBRID:
|
788
|
+
if (buf->use < BASE_BUFFER_SIZE)
|
789
|
+
newSize = size;
|
790
|
+
else {
|
791
|
+
newSize = buf->size * 2;
|
792
|
+
while (size > newSize) {
|
793
|
+
if (newSize > UINT_MAX / 2) {
|
794
|
+
xmlBufMemoryError(buf, "growing buffer");
|
795
|
+
return 0;
|
796
|
+
}
|
797
|
+
newSize *= 2;
|
798
|
+
}
|
799
|
+
}
|
800
|
+
break;
|
801
|
+
|
802
|
+
default:
|
803
|
+
newSize = size+10;
|
804
|
+
break;
|
805
|
+
}
|
806
|
+
|
807
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
|
808
|
+
start_buf = buf->content - buf->contentIO;
|
809
|
+
|
810
|
+
if (start_buf > newSize) {
|
811
|
+
/* move data back to start */
|
812
|
+
memmove(buf->contentIO, buf->content, buf->use);
|
813
|
+
buf->content = buf->contentIO;
|
814
|
+
buf->content[buf->use] = 0;
|
815
|
+
buf->size += start_buf;
|
816
|
+
} else {
|
817
|
+
rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
|
818
|
+
if (rebuf == NULL) {
|
819
|
+
xmlBufMemoryError(buf, "growing buffer");
|
820
|
+
return 0;
|
821
|
+
}
|
822
|
+
buf->contentIO = rebuf;
|
823
|
+
buf->content = rebuf + start_buf;
|
824
|
+
}
|
825
|
+
} else {
|
826
|
+
if (buf->content == NULL) {
|
827
|
+
rebuf = (xmlChar *) xmlMallocAtomic(newSize);
|
828
|
+
} else if (buf->size - buf->use < 100) {
|
829
|
+
rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
|
830
|
+
} else {
|
831
|
+
/*
|
832
|
+
* if we are reallocating a buffer far from being full, it's
|
833
|
+
* better to make a new allocation and copy only the used range
|
834
|
+
* and free the old one.
|
835
|
+
*/
|
836
|
+
rebuf = (xmlChar *) xmlMallocAtomic(newSize);
|
837
|
+
if (rebuf != NULL) {
|
838
|
+
memcpy(rebuf, buf->content, buf->use);
|
839
|
+
xmlFree(buf->content);
|
840
|
+
rebuf[buf->use] = 0;
|
841
|
+
}
|
842
|
+
}
|
843
|
+
if (rebuf == NULL) {
|
844
|
+
xmlBufMemoryError(buf, "growing buffer");
|
845
|
+
return 0;
|
846
|
+
}
|
847
|
+
buf->content = rebuf;
|
848
|
+
}
|
849
|
+
buf->size = newSize;
|
850
|
+
UPDATE_COMPAT(buf)
|
851
|
+
|
852
|
+
return 1;
|
853
|
+
}
|
854
|
+
|
855
|
+
/**
|
856
|
+
* xmlBufAdd:
|
857
|
+
* @buf: the buffer to dump
|
858
|
+
* @str: the #xmlChar string
|
859
|
+
* @len: the number of #xmlChar to add
|
860
|
+
*
|
861
|
+
* Add a string range to an XML buffer. if len == -1, the length of
|
862
|
+
* str is recomputed.
|
863
|
+
*
|
864
|
+
* Returns 0 successful, a positive error code number otherwise
|
865
|
+
* and -1 in case of internal or API error.
|
866
|
+
*/
|
867
|
+
int
|
868
|
+
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
|
869
|
+
unsigned int needSize;
|
870
|
+
|
871
|
+
if ((str == NULL) || (buf == NULL) || (buf->error))
|
872
|
+
return -1;
|
873
|
+
CHECK_COMPAT(buf)
|
874
|
+
|
875
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
876
|
+
if (len < -1) {
|
877
|
+
#ifdef DEBUG_BUFFER
|
878
|
+
xmlGenericError(xmlGenericErrorContext,
|
879
|
+
"xmlBufAdd: len < 0\n");
|
880
|
+
#endif
|
881
|
+
return -1;
|
882
|
+
}
|
883
|
+
if (len == 0) return 0;
|
884
|
+
|
885
|
+
if (len < 0)
|
886
|
+
len = xmlStrlen(str);
|
887
|
+
|
888
|
+
if (len < 0) return -1;
|
889
|
+
if (len == 0) return 0;
|
890
|
+
|
891
|
+
needSize = buf->use + len + 2;
|
892
|
+
if (needSize > buf->size){
|
893
|
+
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
894
|
+
/*
|
895
|
+
* Used to provide parsing limits
|
896
|
+
*/
|
897
|
+
if (needSize >= XML_MAX_TEXT_LENGTH) {
|
898
|
+
xmlBufMemoryError(buf, "buffer error: text too long\n");
|
899
|
+
return(-1);
|
900
|
+
}
|
901
|
+
}
|
902
|
+
if (!xmlBufResize(buf, needSize)){
|
903
|
+
xmlBufMemoryError(buf, "growing buffer");
|
904
|
+
return XML_ERR_NO_MEMORY;
|
905
|
+
}
|
906
|
+
}
|
907
|
+
|
908
|
+
memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
|
909
|
+
buf->use += len;
|
910
|
+
buf->content[buf->use] = 0;
|
911
|
+
UPDATE_COMPAT(buf)
|
912
|
+
return 0;
|
913
|
+
}
|
914
|
+
|
915
|
+
/**
|
916
|
+
* xmlBufAddHead:
|
917
|
+
* @buf: the buffer
|
918
|
+
* @str: the #xmlChar string
|
919
|
+
* @len: the number of #xmlChar to add
|
920
|
+
*
|
921
|
+
* Add a string range to the beginning of an XML buffer.
|
922
|
+
* if len == -1, the length of @str is recomputed.
|
923
|
+
*
|
924
|
+
* Returns 0 successful, a positive error code number otherwise
|
925
|
+
* and -1 in case of internal or API error.
|
926
|
+
*/
|
927
|
+
int
|
928
|
+
xmlBufAddHead(xmlBufPtr buf, const xmlChar *str, int len) {
|
929
|
+
unsigned int needSize;
|
930
|
+
|
931
|
+
if ((buf == NULL) || (buf->error))
|
932
|
+
return(-1);
|
933
|
+
CHECK_COMPAT(buf)
|
934
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
935
|
+
if (str == NULL) {
|
936
|
+
#ifdef DEBUG_BUFFER
|
937
|
+
xmlGenericError(xmlGenericErrorContext,
|
938
|
+
"xmlBufAddHead: str == NULL\n");
|
939
|
+
#endif
|
940
|
+
return -1;
|
941
|
+
}
|
942
|
+
if (len < -1) {
|
943
|
+
#ifdef DEBUG_BUFFER
|
944
|
+
xmlGenericError(xmlGenericErrorContext,
|
945
|
+
"xmlBufAddHead: len < 0\n");
|
946
|
+
#endif
|
947
|
+
return -1;
|
948
|
+
}
|
949
|
+
if (len == 0) return 0;
|
950
|
+
|
951
|
+
if (len < 0)
|
952
|
+
len = xmlStrlen(str);
|
953
|
+
|
954
|
+
if (len <= 0) return -1;
|
955
|
+
|
956
|
+
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
|
957
|
+
size_t start_buf = buf->content - buf->contentIO;
|
958
|
+
|
959
|
+
if (start_buf > (unsigned int) len) {
|
960
|
+
/*
|
961
|
+
* We can add it in the space previously shrunk
|
962
|
+
*/
|
963
|
+
buf->content -= len;
|
964
|
+
memmove(&buf->content[0], str, len);
|
965
|
+
buf->use += len;
|
966
|
+
buf->size += len;
|
967
|
+
UPDATE_COMPAT(buf)
|
968
|
+
return(0);
|
969
|
+
}
|
970
|
+
}
|
971
|
+
needSize = buf->use + len + 2;
|
972
|
+
if (needSize > buf->size){
|
973
|
+
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
974
|
+
/*
|
975
|
+
* Used to provide parsing limits
|
976
|
+
*/
|
977
|
+
if (needSize >= XML_MAX_TEXT_LENGTH) {
|
978
|
+
xmlBufMemoryError(buf, "buffer error: text too long\n");
|
979
|
+
return(-1);
|
980
|
+
}
|
981
|
+
}
|
982
|
+
if (!xmlBufResize(buf, needSize)){
|
983
|
+
xmlBufMemoryError(buf, "growing buffer");
|
984
|
+
return XML_ERR_NO_MEMORY;
|
985
|
+
}
|
986
|
+
}
|
987
|
+
|
988
|
+
memmove(&buf->content[len], &buf->content[0], buf->use);
|
989
|
+
memmove(&buf->content[0], str, len);
|
990
|
+
buf->use += len;
|
991
|
+
buf->content[buf->use] = 0;
|
992
|
+
UPDATE_COMPAT(buf)
|
993
|
+
return 0;
|
994
|
+
}
|
995
|
+
|
996
|
+
/**
|
997
|
+
* xmlBufCat:
|
998
|
+
* @buf: the buffer to add to
|
999
|
+
* @str: the #xmlChar string
|
1000
|
+
*
|
1001
|
+
* Append a zero terminated string to an XML buffer.
|
1002
|
+
*
|
1003
|
+
* Returns 0 successful, a positive error code number otherwise
|
1004
|
+
* and -1 in case of internal or API error.
|
1005
|
+
*/
|
1006
|
+
int
|
1007
|
+
xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
|
1008
|
+
if ((buf == NULL) || (buf->error))
|
1009
|
+
return(-1);
|
1010
|
+
CHECK_COMPAT(buf)
|
1011
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
1012
|
+
if (str == NULL) return -1;
|
1013
|
+
return xmlBufAdd(buf, str, -1);
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
/**
|
1017
|
+
* xmlBufCCat:
|
1018
|
+
* @buf: the buffer to dump
|
1019
|
+
* @str: the C char string
|
1020
|
+
*
|
1021
|
+
* Append a zero terminated C string to an XML buffer.
|
1022
|
+
*
|
1023
|
+
* Returns 0 successful, a positive error code number otherwise
|
1024
|
+
* and -1 in case of internal or API error.
|
1025
|
+
*/
|
1026
|
+
int
|
1027
|
+
xmlBufCCat(xmlBufPtr buf, const char *str) {
|
1028
|
+
const char *cur;
|
1029
|
+
|
1030
|
+
if ((buf == NULL) || (buf->error))
|
1031
|
+
return(-1);
|
1032
|
+
CHECK_COMPAT(buf)
|
1033
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
1034
|
+
if (str == NULL) {
|
1035
|
+
#ifdef DEBUG_BUFFER
|
1036
|
+
xmlGenericError(xmlGenericErrorContext,
|
1037
|
+
"xmlBufCCat: str == NULL\n");
|
1038
|
+
#endif
|
1039
|
+
return -1;
|
1040
|
+
}
|
1041
|
+
for (cur = str;*cur != 0;cur++) {
|
1042
|
+
if (buf->use + 10 >= buf->size) {
|
1043
|
+
if (!xmlBufResize(buf, buf->use+10)){
|
1044
|
+
xmlBufMemoryError(buf, "growing buffer");
|
1045
|
+
return XML_ERR_NO_MEMORY;
|
1046
|
+
}
|
1047
|
+
}
|
1048
|
+
buf->content[buf->use++] = *cur;
|
1049
|
+
}
|
1050
|
+
buf->content[buf->use] = 0;
|
1051
|
+
UPDATE_COMPAT(buf)
|
1052
|
+
return 0;
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
/**
|
1056
|
+
* xmlBufWriteCHAR:
|
1057
|
+
* @buf: the XML buffer
|
1058
|
+
* @string: the string to add
|
1059
|
+
*
|
1060
|
+
* routine which manages and grows an output buffer. This one adds
|
1061
|
+
* xmlChars at the end of the buffer.
|
1062
|
+
*
|
1063
|
+
* Returns 0 if successful, a positive error code number otherwise
|
1064
|
+
* and -1 in case of internal or API error.
|
1065
|
+
*/
|
1066
|
+
int
|
1067
|
+
xmlBufWriteCHAR(xmlBufPtr buf, const xmlChar *string) {
|
1068
|
+
if ((buf == NULL) || (buf->error))
|
1069
|
+
return(-1);
|
1070
|
+
CHECK_COMPAT(buf)
|
1071
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
|
1072
|
+
return(-1);
|
1073
|
+
return(xmlBufCat(buf, string));
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
/**
|
1077
|
+
* xmlBufWriteChar:
|
1078
|
+
* @buf: the XML buffer output
|
1079
|
+
* @string: the string to add
|
1080
|
+
*
|
1081
|
+
* routine which manage and grows an output buffer. This one add
|
1082
|
+
* C chars at the end of the array.
|
1083
|
+
*
|
1084
|
+
* Returns 0 if successful, a positive error code number otherwise
|
1085
|
+
* and -1 in case of internal or API error.
|
1086
|
+
*/
|
1087
|
+
int
|
1088
|
+
xmlBufWriteChar(xmlBufPtr buf, const char *string) {
|
1089
|
+
if ((buf == NULL) || (buf->error))
|
1090
|
+
return(-1);
|
1091
|
+
CHECK_COMPAT(buf)
|
1092
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
|
1093
|
+
return(-1);
|
1094
|
+
return(xmlBufCCat(buf, string));
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
|
1098
|
+
/**
|
1099
|
+
* xmlBufWriteQuotedString:
|
1100
|
+
* @buf: the XML buffer output
|
1101
|
+
* @string: the string to add
|
1102
|
+
*
|
1103
|
+
* routine which manage and grows an output buffer. This one writes
|
1104
|
+
* a quoted or double quoted #xmlChar string, checking first if it holds
|
1105
|
+
* quote or double-quotes internally
|
1106
|
+
*
|
1107
|
+
* Returns 0 if successful, a positive error code number otherwise
|
1108
|
+
* and -1 in case of internal or API error.
|
1109
|
+
*/
|
1110
|
+
int
|
1111
|
+
xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string) {
|
1112
|
+
const xmlChar *cur, *base;
|
1113
|
+
if ((buf == NULL) || (buf->error))
|
1114
|
+
return(-1);
|
1115
|
+
CHECK_COMPAT(buf)
|
1116
|
+
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
|
1117
|
+
return(-1);
|
1118
|
+
if (xmlStrchr(string, '\"')) {
|
1119
|
+
if (xmlStrchr(string, '\'')) {
|
1120
|
+
#ifdef DEBUG_BUFFER
|
1121
|
+
xmlGenericError(xmlGenericErrorContext,
|
1122
|
+
"xmlBufWriteQuotedString: string contains quote and double-quotes !\n");
|
1123
|
+
#endif
|
1124
|
+
xmlBufCCat(buf, "\"");
|
1125
|
+
base = cur = string;
|
1126
|
+
while(*cur != 0){
|
1127
|
+
if(*cur == '"'){
|
1128
|
+
if (base != cur)
|
1129
|
+
xmlBufAdd(buf, base, cur - base);
|
1130
|
+
xmlBufAdd(buf, BAD_CAST """, 6);
|
1131
|
+
cur++;
|
1132
|
+
base = cur;
|
1133
|
+
}
|
1134
|
+
else {
|
1135
|
+
cur++;
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
if (base != cur)
|
1139
|
+
xmlBufAdd(buf, base, cur - base);
|
1140
|
+
xmlBufCCat(buf, "\"");
|
1141
|
+
}
|
1142
|
+
else{
|
1143
|
+
xmlBufCCat(buf, "\'");
|
1144
|
+
xmlBufCat(buf, string);
|
1145
|
+
xmlBufCCat(buf, "\'");
|
1146
|
+
}
|
1147
|
+
} else {
|
1148
|
+
xmlBufCCat(buf, "\"");
|
1149
|
+
xmlBufCat(buf, string);
|
1150
|
+
xmlBufCCat(buf, "\"");
|
1151
|
+
}
|
1152
|
+
return(0);
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
/**
|
1156
|
+
* xmlBufFromBuffer:
|
1157
|
+
* @buffer: incoming old buffer to convert to a new one
|
1158
|
+
*
|
1159
|
+
* Helper routine to switch from the old buffer structures in use
|
1160
|
+
* in various APIs. It creates a wrapper xmlBufPtr which will be
|
1161
|
+
* used for internal processing until the xmlBufBackToBuffer() is
|
1162
|
+
* issued.
|
1163
|
+
*
|
1164
|
+
* Returns a new xmlBufPtr unless the call failed and NULL is returned
|
1165
|
+
*/
|
1166
|
+
xmlBufPtr
|
1167
|
+
xmlBufFromBuffer(xmlBufferPtr buffer) {
|
1168
|
+
xmlBufPtr ret;
|
1169
|
+
|
1170
|
+
if (buffer == NULL)
|
1171
|
+
return(NULL);
|
1172
|
+
|
1173
|
+
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
|
1174
|
+
if (ret == NULL) {
|
1175
|
+
xmlBufMemoryError(NULL, "creating buffer");
|
1176
|
+
return(NULL);
|
1177
|
+
}
|
1178
|
+
ret->use = buffer->use;
|
1179
|
+
ret->size = buffer->size;
|
1180
|
+
ret->compat_use = buffer->use;
|
1181
|
+
ret->compat_size = buffer->size;
|
1182
|
+
ret->error = 0;
|
1183
|
+
ret->buffer = buffer;
|
1184
|
+
ret->alloc = buffer->alloc;
|
1185
|
+
ret->content = buffer->content;
|
1186
|
+
ret->contentIO = buffer->contentIO;
|
1187
|
+
|
1188
|
+
return(ret);
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
/**
|
1192
|
+
* xmlBufBackToBuffer:
|
1193
|
+
* @buf: new buffer wrapping the old one
|
1194
|
+
*
|
1195
|
+
* Function to be called once internal processing had been done to
|
1196
|
+
* update back the buffer provided by the user. This can lead to
|
1197
|
+
* a failure in case the size accumulated in the xmlBuf is larger
|
1198
|
+
* than what an xmlBuffer can support on 64 bits (INT_MAX)
|
1199
|
+
* The xmlBufPtr @buf wrapper is deallocated by this call in any case.
|
1200
|
+
*
|
1201
|
+
* Returns the old xmlBufferPtr unless the call failed and NULL is returned
|
1202
|
+
*/
|
1203
|
+
xmlBufferPtr
|
1204
|
+
xmlBufBackToBuffer(xmlBufPtr buf) {
|
1205
|
+
xmlBufferPtr ret;
|
1206
|
+
|
1207
|
+
if (buf == NULL)
|
1208
|
+
return(NULL);
|
1209
|
+
CHECK_COMPAT(buf)
|
1210
|
+
if ((buf->error) || (buf->buffer == NULL)) {
|
1211
|
+
xmlBufFree(buf);
|
1212
|
+
return(NULL);
|
1213
|
+
}
|
1214
|
+
|
1215
|
+
ret = buf->buffer;
|
1216
|
+
/*
|
1217
|
+
* What to do in case of error in the buffer ???
|
1218
|
+
*/
|
1219
|
+
if (buf->use > INT_MAX) {
|
1220
|
+
/*
|
1221
|
+
* Worse case, we really allocated and used more than the
|
1222
|
+
* maximum allowed memory for an xmlBuffer on this architecture.
|
1223
|
+
* Keep the buffer but provide a truncated size value.
|
1224
|
+
*/
|
1225
|
+
xmlBufOverflowError(buf, "Used size too big for xmlBuffer");
|
1226
|
+
ret->use = INT_MAX;
|
1227
|
+
ret->size = INT_MAX;
|
1228
|
+
} else if (buf->size > INT_MAX) {
|
1229
|
+
/*
|
1230
|
+
* milder case, we allocated more than the maximum allowed memory
|
1231
|
+
* for an xmlBuffer on this architecture, but used less than the
|
1232
|
+
* limit.
|
1233
|
+
* Keep the buffer but provide a truncated size value.
|
1234
|
+
*/
|
1235
|
+
xmlBufOverflowError(buf, "Allocated size too big for xmlBuffer");
|
1236
|
+
ret->use = (int) buf->use;
|
1237
|
+
ret->size = INT_MAX;
|
1238
|
+
} else {
|
1239
|
+
ret->use = (int) buf->use;
|
1240
|
+
ret->size = (int) buf->size;
|
1241
|
+
}
|
1242
|
+
ret->alloc = buf->alloc;
|
1243
|
+
ret->content = buf->content;
|
1244
|
+
ret->contentIO = buf->contentIO;
|
1245
|
+
xmlFree(buf);
|
1246
|
+
return(ret);
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
/**
|
1250
|
+
* xmlBufMergeBuffer:
|
1251
|
+
* @buf: an xmlBufPtr
|
1252
|
+
* @buffer: the buffer to consume into @buf
|
1253
|
+
*
|
1254
|
+
* The content of @buffer is appended to @buf and @buffer is freed
|
1255
|
+
*
|
1256
|
+
* Returns -1 in case of error, 0 otherwise, in any case @buffer is freed
|
1257
|
+
*/
|
1258
|
+
int
|
1259
|
+
xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer) {
|
1260
|
+
int ret = 0;
|
1261
|
+
|
1262
|
+
if ((buf == NULL) || (buf->error)) {
|
1263
|
+
xmlBufferFree(buffer);
|
1264
|
+
return(-1);
|
1265
|
+
}
|
1266
|
+
CHECK_COMPAT(buf)
|
1267
|
+
if ((buffer != NULL) && (buffer->content != NULL) &&
|
1268
|
+
(buffer->use > 0)) {
|
1269
|
+
ret = xmlBufAdd(buf, buffer->content, buffer->use);
|
1270
|
+
}
|
1271
|
+
xmlBufferFree(buffer);
|
1272
|
+
return(ret);
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
/**
|
1276
|
+
* xmlBufResetInput:
|
1277
|
+
* @buf: an xmlBufPtr
|
1278
|
+
* @input: an xmlParserInputPtr
|
1279
|
+
*
|
1280
|
+
* Update the input to use the current set of pointers from the buffer.
|
1281
|
+
*
|
1282
|
+
* Returns -1 in case of error, 0 otherwise
|
1283
|
+
*/
|
1284
|
+
int
|
1285
|
+
xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
|
1286
|
+
if ((input == NULL) || (buf == NULL) || (buf->error))
|
1287
|
+
return(-1);
|
1288
|
+
CHECK_COMPAT(buf)
|
1289
|
+
input->base = input->cur = buf->content;
|
1290
|
+
input->end = &buf->content[buf->use];
|
1291
|
+
return(0);
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
/**
|
1295
|
+
* xmlBufGetInputBase:
|
1296
|
+
* @buf: an xmlBufPtr
|
1297
|
+
* @input: an xmlParserInputPtr
|
1298
|
+
*
|
1299
|
+
* Get the base of the @input relative to the beginning of the buffer
|
1300
|
+
*
|
1301
|
+
* Returns the size_t corresponding to the displacement
|
1302
|
+
*/
|
1303
|
+
size_t
|
1304
|
+
xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) {
|
1305
|
+
size_t base;
|
1306
|
+
|
1307
|
+
if ((input == NULL) || (buf == NULL) || (buf->error))
|
1308
|
+
return(-1);
|
1309
|
+
CHECK_COMPAT(buf)
|
1310
|
+
base = input->base - buf->content;
|
1311
|
+
/*
|
1312
|
+
* We could do some pointer arithmetic checks but that's probably
|
1313
|
+
* sufficient.
|
1314
|
+
*/
|
1315
|
+
if (base > buf->size) {
|
1316
|
+
xmlBufOverflowError(buf, "Input reference outside of the buffer");
|
1317
|
+
base = 0;
|
1318
|
+
}
|
1319
|
+
return(base);
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
/**
|
1323
|
+
* xmlBufSetInputBaseCur:
|
1324
|
+
* @buf: an xmlBufPtr
|
1325
|
+
* @input: an xmlParserInputPtr
|
1326
|
+
* @base: the base value relative to the beginning of the buffer
|
1327
|
+
* @cur: the cur value relative to the beginning of the buffer
|
1328
|
+
*
|
1329
|
+
* Update the input to use the base and cur relative to the buffer
|
1330
|
+
* after a possible reallocation of its content
|
1331
|
+
*
|
1332
|
+
* Returns -1 in case of error, 0 otherwise
|
1333
|
+
*/
|
1334
|
+
int
|
1335
|
+
xmlBufSetInputBaseCur(xmlBufPtr buf, xmlParserInputPtr input,
|
1336
|
+
size_t base, size_t cur) {
|
1337
|
+
if (input == NULL)
|
1338
|
+
return(-1);
|
1339
|
+
if ((buf == NULL) || (buf->error)) {
|
1340
|
+
input->base = input->cur = input->end = BAD_CAST "";
|
1341
|
+
return(-1);
|
1342
|
+
}
|
1343
|
+
CHECK_COMPAT(buf)
|
1344
|
+
input->base = &buf->content[base];
|
1345
|
+
input->cur = input->base + cur;
|
1346
|
+
input->end = &buf->content[buf->use];
|
1347
|
+
return(0);
|
1348
|
+
}
|
1349
|
+
|
1350
|
+
#define bottom_buf
|
1351
|
+
#include "elfgcchack.h"
|