pocjenkixx 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 pocjenkixx 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,2164 @@
|
|
1
|
+
/*
|
2
|
+
* parserInternals.c : Internal routines (and obsolete ones) needed for the
|
3
|
+
* XML and HTML parsers.
|
4
|
+
*
|
5
|
+
* See Copyright for the status of this software.
|
6
|
+
*
|
7
|
+
* daniel@veillard.com
|
8
|
+
*/
|
9
|
+
|
10
|
+
#define IN_LIBXML
|
11
|
+
#include "libxml.h"
|
12
|
+
|
13
|
+
#if defined(_WIN32) && !defined (__CYGWIN__)
|
14
|
+
#define XML_DIR_SEP '\\'
|
15
|
+
#else
|
16
|
+
#define XML_DIR_SEP '/'
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include <string.h>
|
20
|
+
#ifdef HAVE_CTYPE_H
|
21
|
+
#include <ctype.h>
|
22
|
+
#endif
|
23
|
+
#ifdef HAVE_STDLIB_H
|
24
|
+
#include <stdlib.h>
|
25
|
+
#endif
|
26
|
+
#ifdef HAVE_SYS_STAT_H
|
27
|
+
#include <sys/stat.h>
|
28
|
+
#endif
|
29
|
+
#ifdef HAVE_FCNTL_H
|
30
|
+
#include <fcntl.h>
|
31
|
+
#endif
|
32
|
+
#ifdef HAVE_UNISTD_H
|
33
|
+
#include <unistd.h>
|
34
|
+
#endif
|
35
|
+
#ifdef LIBXML_ZLIB_ENABLED
|
36
|
+
#include <zlib.h>
|
37
|
+
#endif
|
38
|
+
|
39
|
+
#include <libxml/xmlmemory.h>
|
40
|
+
#include <libxml/tree.h>
|
41
|
+
#include <libxml/parser.h>
|
42
|
+
#include <libxml/parserInternals.h>
|
43
|
+
#include <libxml/valid.h>
|
44
|
+
#include <libxml/entities.h>
|
45
|
+
#include <libxml/xmlerror.h>
|
46
|
+
#include <libxml/encoding.h>
|
47
|
+
#include <libxml/valid.h>
|
48
|
+
#include <libxml/xmlIO.h>
|
49
|
+
#include <libxml/uri.h>
|
50
|
+
#include <libxml/dict.h>
|
51
|
+
#include <libxml/SAX.h>
|
52
|
+
#ifdef LIBXML_CATALOG_ENABLED
|
53
|
+
#include <libxml/catalog.h>
|
54
|
+
#endif
|
55
|
+
#include <libxml/globals.h>
|
56
|
+
#include <libxml/chvalid.h>
|
57
|
+
|
58
|
+
#define CUR(ctxt) ctxt->input->cur
|
59
|
+
#define END(ctxt) ctxt->input->end
|
60
|
+
#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
|
61
|
+
|
62
|
+
#include "buf.h"
|
63
|
+
#include "enc.h"
|
64
|
+
|
65
|
+
/*
|
66
|
+
* Various global defaults for parsing
|
67
|
+
*/
|
68
|
+
|
69
|
+
/**
|
70
|
+
* xmlCheckVersion:
|
71
|
+
* @version: the include version number
|
72
|
+
*
|
73
|
+
* check the compiled lib version against the include one.
|
74
|
+
* This can warn or immediately kill the application
|
75
|
+
*/
|
76
|
+
void
|
77
|
+
xmlCheckVersion(int version) {
|
78
|
+
int myversion = (int) LIBXML_VERSION;
|
79
|
+
|
80
|
+
xmlInitParser();
|
81
|
+
|
82
|
+
if ((myversion / 10000) != (version / 10000)) {
|
83
|
+
xmlGenericError(xmlGenericErrorContext,
|
84
|
+
"Fatal: program compiled against libxml %d using libxml %d\n",
|
85
|
+
(version / 10000), (myversion / 10000));
|
86
|
+
fprintf(stderr,
|
87
|
+
"Fatal: program compiled against libxml %d using libxml %d\n",
|
88
|
+
(version / 10000), (myversion / 10000));
|
89
|
+
}
|
90
|
+
if ((myversion / 100) < (version / 100)) {
|
91
|
+
xmlGenericError(xmlGenericErrorContext,
|
92
|
+
"Warning: program compiled against libxml %d using older %d\n",
|
93
|
+
(version / 100), (myversion / 100));
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
/************************************************************************
|
99
|
+
* *
|
100
|
+
* Some factorized error routines *
|
101
|
+
* *
|
102
|
+
************************************************************************/
|
103
|
+
|
104
|
+
|
105
|
+
/**
|
106
|
+
* xmlErrMemory:
|
107
|
+
* @ctxt: an XML parser context
|
108
|
+
* @extra: extra information
|
109
|
+
*
|
110
|
+
* Handle a redefinition of attribute error
|
111
|
+
*/
|
112
|
+
void
|
113
|
+
xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
|
114
|
+
{
|
115
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
116
|
+
(ctxt->instate == XML_PARSER_EOF))
|
117
|
+
return;
|
118
|
+
if (ctxt != NULL) {
|
119
|
+
ctxt->errNo = XML_ERR_NO_MEMORY;
|
120
|
+
ctxt->instate = XML_PARSER_EOF;
|
121
|
+
ctxt->disableSAX = 1;
|
122
|
+
}
|
123
|
+
if (extra)
|
124
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
|
125
|
+
XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
|
126
|
+
NULL, NULL, 0, 0,
|
127
|
+
"Memory allocation failed : %s\n", extra);
|
128
|
+
else
|
129
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
|
130
|
+
XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
|
131
|
+
NULL, NULL, 0, 0, "Memory allocation failed\n");
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* __xmlErrEncoding:
|
136
|
+
* @ctxt: an XML parser context
|
137
|
+
* @xmlerr: the error number
|
138
|
+
* @msg: the error message
|
139
|
+
* @str1: an string info
|
140
|
+
* @str2: an string info
|
141
|
+
*
|
142
|
+
* Handle an encoding error
|
143
|
+
*/
|
144
|
+
void
|
145
|
+
__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
|
146
|
+
const char *msg, const xmlChar * str1, const xmlChar * str2)
|
147
|
+
{
|
148
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
149
|
+
(ctxt->instate == XML_PARSER_EOF))
|
150
|
+
return;
|
151
|
+
if (ctxt != NULL)
|
152
|
+
ctxt->errNo = xmlerr;
|
153
|
+
__xmlRaiseError(NULL, NULL, NULL,
|
154
|
+
ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
|
155
|
+
NULL, 0, (const char *) str1, (const char *) str2,
|
156
|
+
NULL, 0, 0, msg, str1, str2);
|
157
|
+
if (ctxt != NULL) {
|
158
|
+
ctxt->wellFormed = 0;
|
159
|
+
if (ctxt->recovery == 0)
|
160
|
+
ctxt->disableSAX = 1;
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* xmlErrInternal:
|
166
|
+
* @ctxt: an XML parser context
|
167
|
+
* @msg: the error message
|
168
|
+
* @str: error information
|
169
|
+
*
|
170
|
+
* Handle an internal error
|
171
|
+
*/
|
172
|
+
static void LIBXML_ATTR_FORMAT(2,0)
|
173
|
+
xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
|
174
|
+
{
|
175
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
176
|
+
(ctxt->instate == XML_PARSER_EOF))
|
177
|
+
return;
|
178
|
+
if (ctxt != NULL)
|
179
|
+
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
|
180
|
+
__xmlRaiseError(NULL, NULL, NULL,
|
181
|
+
ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
|
182
|
+
XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
|
183
|
+
0, 0, msg, str);
|
184
|
+
if (ctxt != NULL) {
|
185
|
+
ctxt->wellFormed = 0;
|
186
|
+
if (ctxt->recovery == 0)
|
187
|
+
ctxt->disableSAX = 1;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* xmlErrEncodingInt:
|
193
|
+
* @ctxt: an XML parser context
|
194
|
+
* @error: the error number
|
195
|
+
* @msg: the error message
|
196
|
+
* @val: an integer value
|
197
|
+
*
|
198
|
+
* n encoding error
|
199
|
+
*/
|
200
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
201
|
+
xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
202
|
+
const char *msg, int val)
|
203
|
+
{
|
204
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
205
|
+
(ctxt->instate == XML_PARSER_EOF))
|
206
|
+
return;
|
207
|
+
if (ctxt != NULL)
|
208
|
+
ctxt->errNo = error;
|
209
|
+
__xmlRaiseError(NULL, NULL, NULL,
|
210
|
+
ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
|
211
|
+
NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
|
212
|
+
if (ctxt != NULL) {
|
213
|
+
ctxt->wellFormed = 0;
|
214
|
+
if (ctxt->recovery == 0)
|
215
|
+
ctxt->disableSAX = 1;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* xmlIsLetter:
|
221
|
+
* @c: an unicode character (int)
|
222
|
+
*
|
223
|
+
* Check whether the character is allowed by the production
|
224
|
+
* [84] Letter ::= BaseChar | Ideographic
|
225
|
+
*
|
226
|
+
* Returns 0 if not, non-zero otherwise
|
227
|
+
*/
|
228
|
+
int
|
229
|
+
xmlIsLetter(int c) {
|
230
|
+
return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
|
231
|
+
}
|
232
|
+
|
233
|
+
/************************************************************************
|
234
|
+
* *
|
235
|
+
* Input handling functions for progressive parsing *
|
236
|
+
* *
|
237
|
+
************************************************************************/
|
238
|
+
|
239
|
+
/* #define DEBUG_INPUT */
|
240
|
+
/* #define DEBUG_STACK */
|
241
|
+
/* #define DEBUG_PUSH */
|
242
|
+
|
243
|
+
|
244
|
+
/* we need to keep enough input to show errors in context */
|
245
|
+
#define LINE_LEN 80
|
246
|
+
|
247
|
+
#ifdef DEBUG_INPUT
|
248
|
+
#define CHECK_BUFFER(in) check_buffer(in)
|
249
|
+
|
250
|
+
static
|
251
|
+
void check_buffer(xmlParserInputPtr in) {
|
252
|
+
if (in->base != xmlBufContent(in->buf->buffer)) {
|
253
|
+
xmlGenericError(xmlGenericErrorContext,
|
254
|
+
"xmlParserInput: base mismatch problem\n");
|
255
|
+
}
|
256
|
+
if (in->cur < in->base) {
|
257
|
+
xmlGenericError(xmlGenericErrorContext,
|
258
|
+
"xmlParserInput: cur < base problem\n");
|
259
|
+
}
|
260
|
+
if (in->cur > in->base + xmlBufUse(in->buf->buffer)) {
|
261
|
+
xmlGenericError(xmlGenericErrorContext,
|
262
|
+
"xmlParserInput: cur > base + use problem\n");
|
263
|
+
}
|
264
|
+
xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d\n",
|
265
|
+
(int) in, (int) xmlBufContent(in->buf->buffer), in->cur - in->base,
|
266
|
+
xmlBufUse(in->buf->buffer));
|
267
|
+
}
|
268
|
+
|
269
|
+
#else
|
270
|
+
#define CHECK_BUFFER(in)
|
271
|
+
#endif
|
272
|
+
|
273
|
+
|
274
|
+
/**
|
275
|
+
* xmlParserInputRead:
|
276
|
+
* @in: an XML parser input
|
277
|
+
* @len: an indicative size for the lookahead
|
278
|
+
*
|
279
|
+
* This function was internal and is deprecated.
|
280
|
+
*
|
281
|
+
* Returns -1 as this is an error to use it.
|
282
|
+
*/
|
283
|
+
int
|
284
|
+
xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) {
|
285
|
+
return(-1);
|
286
|
+
}
|
287
|
+
|
288
|
+
/**
|
289
|
+
* xmlParserInputGrow:
|
290
|
+
* @in: an XML parser input
|
291
|
+
* @len: an indicative size for the lookahead
|
292
|
+
*
|
293
|
+
* This function increase the input for the parser. It tries to
|
294
|
+
* preserve pointers to the input buffer, and keep already read data
|
295
|
+
*
|
296
|
+
* Returns the amount of char read, or -1 in case of error, 0 indicate the
|
297
|
+
* end of this entity
|
298
|
+
*/
|
299
|
+
int
|
300
|
+
xmlParserInputGrow(xmlParserInputPtr in, int len) {
|
301
|
+
int ret;
|
302
|
+
size_t indx;
|
303
|
+
const xmlChar *content;
|
304
|
+
|
305
|
+
if ((in == NULL) || (len < 0)) return(-1);
|
306
|
+
#ifdef DEBUG_INPUT
|
307
|
+
xmlGenericError(xmlGenericErrorContext, "Grow\n");
|
308
|
+
#endif
|
309
|
+
if (in->buf == NULL) return(-1);
|
310
|
+
if (in->base == NULL) return(-1);
|
311
|
+
if (in->cur == NULL) return(-1);
|
312
|
+
if (in->buf->buffer == NULL) return(-1);
|
313
|
+
|
314
|
+
CHECK_BUFFER(in);
|
315
|
+
|
316
|
+
indx = in->cur - in->base;
|
317
|
+
if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
|
318
|
+
|
319
|
+
CHECK_BUFFER(in);
|
320
|
+
|
321
|
+
return(0);
|
322
|
+
}
|
323
|
+
if (in->buf->readcallback != NULL) {
|
324
|
+
ret = xmlParserInputBufferGrow(in->buf, len);
|
325
|
+
} else
|
326
|
+
return(0);
|
327
|
+
|
328
|
+
/*
|
329
|
+
* NOTE : in->base may be a "dangling" i.e. freed pointer in this
|
330
|
+
* block, but we use it really as an integer to do some
|
331
|
+
* pointer arithmetic. Insure will raise it as a bug but in
|
332
|
+
* that specific case, that's not !
|
333
|
+
*/
|
334
|
+
|
335
|
+
content = xmlBufContent(in->buf->buffer);
|
336
|
+
if (in->base != content) {
|
337
|
+
/*
|
338
|
+
* the buffer has been reallocated
|
339
|
+
*/
|
340
|
+
indx = in->cur - in->base;
|
341
|
+
in->base = content;
|
342
|
+
in->cur = &content[indx];
|
343
|
+
}
|
344
|
+
in->end = xmlBufEnd(in->buf->buffer);
|
345
|
+
|
346
|
+
CHECK_BUFFER(in);
|
347
|
+
|
348
|
+
return(ret);
|
349
|
+
}
|
350
|
+
|
351
|
+
/**
|
352
|
+
* xmlParserInputShrink:
|
353
|
+
* @in: an XML parser input
|
354
|
+
*
|
355
|
+
* This function removes used input for the parser.
|
356
|
+
*/
|
357
|
+
void
|
358
|
+
xmlParserInputShrink(xmlParserInputPtr in) {
|
359
|
+
size_t used;
|
360
|
+
size_t ret;
|
361
|
+
size_t indx;
|
362
|
+
const xmlChar *content;
|
363
|
+
|
364
|
+
#ifdef DEBUG_INPUT
|
365
|
+
xmlGenericError(xmlGenericErrorContext, "Shrink\n");
|
366
|
+
#endif
|
367
|
+
if (in == NULL) return;
|
368
|
+
if (in->buf == NULL) return;
|
369
|
+
if (in->base == NULL) return;
|
370
|
+
if (in->cur == NULL) return;
|
371
|
+
if (in->buf->buffer == NULL) return;
|
372
|
+
|
373
|
+
CHECK_BUFFER(in);
|
374
|
+
|
375
|
+
used = in->cur - xmlBufContent(in->buf->buffer);
|
376
|
+
/*
|
377
|
+
* Do not shrink on large buffers whose only a tiny fraction
|
378
|
+
* was consumed
|
379
|
+
*/
|
380
|
+
if (used > INPUT_CHUNK) {
|
381
|
+
ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
|
382
|
+
if (ret > 0) {
|
383
|
+
in->cur -= ret;
|
384
|
+
in->consumed += ret;
|
385
|
+
}
|
386
|
+
in->end = xmlBufEnd(in->buf->buffer);
|
387
|
+
}
|
388
|
+
|
389
|
+
CHECK_BUFFER(in);
|
390
|
+
|
391
|
+
if (xmlBufUse(in->buf->buffer) > INPUT_CHUNK) {
|
392
|
+
return;
|
393
|
+
}
|
394
|
+
xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
|
395
|
+
content = xmlBufContent(in->buf->buffer);
|
396
|
+
if (in->base != content) {
|
397
|
+
/*
|
398
|
+
* the buffer has been reallocated
|
399
|
+
*/
|
400
|
+
indx = in->cur - in->base;
|
401
|
+
in->base = content;
|
402
|
+
in->cur = &content[indx];
|
403
|
+
}
|
404
|
+
in->end = xmlBufEnd(in->buf->buffer);
|
405
|
+
|
406
|
+
CHECK_BUFFER(in);
|
407
|
+
}
|
408
|
+
|
409
|
+
/************************************************************************
|
410
|
+
* *
|
411
|
+
* UTF8 character input and related functions *
|
412
|
+
* *
|
413
|
+
************************************************************************/
|
414
|
+
|
415
|
+
/**
|
416
|
+
* xmlNextChar:
|
417
|
+
* @ctxt: the XML parser context
|
418
|
+
*
|
419
|
+
* Skip to the next char input char.
|
420
|
+
*/
|
421
|
+
|
422
|
+
void
|
423
|
+
xmlNextChar(xmlParserCtxtPtr ctxt)
|
424
|
+
{
|
425
|
+
if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
|
426
|
+
(ctxt->input == NULL))
|
427
|
+
return;
|
428
|
+
|
429
|
+
if (!(VALID_CTXT(ctxt))) {
|
430
|
+
xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
|
431
|
+
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
|
432
|
+
xmlStopParser(ctxt);
|
433
|
+
return;
|
434
|
+
}
|
435
|
+
|
436
|
+
if ((*ctxt->input->cur == 0) &&
|
437
|
+
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
|
438
|
+
return;
|
439
|
+
}
|
440
|
+
|
441
|
+
if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
|
442
|
+
const unsigned char *cur;
|
443
|
+
unsigned char c;
|
444
|
+
|
445
|
+
/*
|
446
|
+
* 2.11 End-of-Line Handling
|
447
|
+
* the literal two-character sequence "#xD#xA" or a standalone
|
448
|
+
* literal #xD, an XML processor must pass to the application
|
449
|
+
* the single character #xA.
|
450
|
+
*/
|
451
|
+
if (*(ctxt->input->cur) == '\n') {
|
452
|
+
ctxt->input->line++; ctxt->input->col = 1;
|
453
|
+
} else
|
454
|
+
ctxt->input->col++;
|
455
|
+
|
456
|
+
/*
|
457
|
+
* We are supposed to handle UTF8, check it's valid
|
458
|
+
* From rfc2044: encoding of the Unicode values on UTF-8:
|
459
|
+
*
|
460
|
+
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
461
|
+
* 0000 0000-0000 007F 0xxxxxxx
|
462
|
+
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
463
|
+
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
464
|
+
*
|
465
|
+
* Check for the 0x110000 limit too
|
466
|
+
*/
|
467
|
+
cur = ctxt->input->cur;
|
468
|
+
|
469
|
+
c = *cur;
|
470
|
+
if (c & 0x80) {
|
471
|
+
if (c == 0xC0)
|
472
|
+
goto encoding_error;
|
473
|
+
if (cur[1] == 0) {
|
474
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
475
|
+
cur = ctxt->input->cur;
|
476
|
+
}
|
477
|
+
if ((cur[1] & 0xc0) != 0x80)
|
478
|
+
goto encoding_error;
|
479
|
+
if ((c & 0xe0) == 0xe0) {
|
480
|
+
unsigned int val;
|
481
|
+
|
482
|
+
if (cur[2] == 0) {
|
483
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
484
|
+
cur = ctxt->input->cur;
|
485
|
+
}
|
486
|
+
if ((cur[2] & 0xc0) != 0x80)
|
487
|
+
goto encoding_error;
|
488
|
+
if ((c & 0xf0) == 0xf0) {
|
489
|
+
if (cur[3] == 0) {
|
490
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
491
|
+
cur = ctxt->input->cur;
|
492
|
+
}
|
493
|
+
if (((c & 0xf8) != 0xf0) ||
|
494
|
+
((cur[3] & 0xc0) != 0x80))
|
495
|
+
goto encoding_error;
|
496
|
+
/* 4-byte code */
|
497
|
+
ctxt->input->cur += 4;
|
498
|
+
val = (cur[0] & 0x7) << 18;
|
499
|
+
val |= (cur[1] & 0x3f) << 12;
|
500
|
+
val |= (cur[2] & 0x3f) << 6;
|
501
|
+
val |= cur[3] & 0x3f;
|
502
|
+
} else {
|
503
|
+
/* 3-byte code */
|
504
|
+
ctxt->input->cur += 3;
|
505
|
+
val = (cur[0] & 0xf) << 12;
|
506
|
+
val |= (cur[1] & 0x3f) << 6;
|
507
|
+
val |= cur[2] & 0x3f;
|
508
|
+
}
|
509
|
+
if (((val > 0xd7ff) && (val < 0xe000)) ||
|
510
|
+
((val > 0xfffd) && (val < 0x10000)) ||
|
511
|
+
(val >= 0x110000)) {
|
512
|
+
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
|
513
|
+
"Char 0x%X out of allowed range\n",
|
514
|
+
val);
|
515
|
+
}
|
516
|
+
} else
|
517
|
+
/* 2-byte code */
|
518
|
+
ctxt->input->cur += 2;
|
519
|
+
} else
|
520
|
+
/* 1-byte code */
|
521
|
+
ctxt->input->cur++;
|
522
|
+
} else {
|
523
|
+
/*
|
524
|
+
* Assume it's a fixed length encoding (1) with
|
525
|
+
* a compatible encoding for the ASCII set, since
|
526
|
+
* XML constructs only use < 128 chars
|
527
|
+
*/
|
528
|
+
|
529
|
+
if (*(ctxt->input->cur) == '\n') {
|
530
|
+
ctxt->input->line++; ctxt->input->col = 1;
|
531
|
+
} else
|
532
|
+
ctxt->input->col++;
|
533
|
+
ctxt->input->cur++;
|
534
|
+
}
|
535
|
+
if (*ctxt->input->cur == 0)
|
536
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
537
|
+
return;
|
538
|
+
encoding_error:
|
539
|
+
/*
|
540
|
+
* If we detect an UTF8 error that probably mean that the
|
541
|
+
* input encoding didn't get properly advertised in the
|
542
|
+
* declaration header. Report the error and switch the encoding
|
543
|
+
* to ISO-Latin-1 (if you don't like this policy, just declare the
|
544
|
+
* encoding !)
|
545
|
+
*/
|
546
|
+
if ((ctxt == NULL) || (ctxt->input == NULL) ||
|
547
|
+
(ctxt->input->end - ctxt->input->cur < 4)) {
|
548
|
+
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
|
549
|
+
"Input is not proper UTF-8, indicate encoding !\n",
|
550
|
+
NULL, NULL);
|
551
|
+
} else {
|
552
|
+
char buffer[150];
|
553
|
+
|
554
|
+
snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
|
555
|
+
ctxt->input->cur[0], ctxt->input->cur[1],
|
556
|
+
ctxt->input->cur[2], ctxt->input->cur[3]);
|
557
|
+
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
|
558
|
+
"Input is not proper UTF-8, indicate encoding !\n%s",
|
559
|
+
BAD_CAST buffer, NULL);
|
560
|
+
}
|
561
|
+
ctxt->charset = XML_CHAR_ENCODING_8859_1;
|
562
|
+
ctxt->input->cur++;
|
563
|
+
return;
|
564
|
+
}
|
565
|
+
|
566
|
+
/**
|
567
|
+
* xmlCurrentChar:
|
568
|
+
* @ctxt: the XML parser context
|
569
|
+
* @len: pointer to the length of the char read
|
570
|
+
*
|
571
|
+
* The current char value, if using UTF-8 this may actually span multiple
|
572
|
+
* bytes in the input buffer. Implement the end of line normalization:
|
573
|
+
* 2.11 End-of-Line Handling
|
574
|
+
* Wherever an external parsed entity or the literal entity value
|
575
|
+
* of an internal parsed entity contains either the literal two-character
|
576
|
+
* sequence "#xD#xA" or a standalone literal #xD, an XML processor
|
577
|
+
* must pass to the application the single character #xA.
|
578
|
+
* This behavior can conveniently be produced by normalizing all
|
579
|
+
* line breaks to #xA on input, before parsing.)
|
580
|
+
*
|
581
|
+
* Returns the current char value and its length
|
582
|
+
*/
|
583
|
+
|
584
|
+
int
|
585
|
+
xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
|
586
|
+
if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
|
587
|
+
if (ctxt->instate == XML_PARSER_EOF)
|
588
|
+
return(0);
|
589
|
+
|
590
|
+
if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
|
591
|
+
*len = 1;
|
592
|
+
return((int) *ctxt->input->cur);
|
593
|
+
}
|
594
|
+
if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
|
595
|
+
/*
|
596
|
+
* We are supposed to handle UTF8, check it's valid
|
597
|
+
* From rfc2044: encoding of the Unicode values on UTF-8:
|
598
|
+
*
|
599
|
+
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
600
|
+
* 0000 0000-0000 007F 0xxxxxxx
|
601
|
+
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
602
|
+
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
603
|
+
*
|
604
|
+
* Check for the 0x110000 limit too
|
605
|
+
*/
|
606
|
+
const unsigned char *cur = ctxt->input->cur;
|
607
|
+
unsigned char c;
|
608
|
+
unsigned int val;
|
609
|
+
|
610
|
+
c = *cur;
|
611
|
+
if (c & 0x80) {
|
612
|
+
if (((c & 0x40) == 0) || (c == 0xC0))
|
613
|
+
goto encoding_error;
|
614
|
+
if (cur[1] == 0) {
|
615
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
616
|
+
cur = ctxt->input->cur;
|
617
|
+
}
|
618
|
+
if ((cur[1] & 0xc0) != 0x80)
|
619
|
+
goto encoding_error;
|
620
|
+
if ((c & 0xe0) == 0xe0) {
|
621
|
+
if (cur[2] == 0) {
|
622
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
623
|
+
cur = ctxt->input->cur;
|
624
|
+
}
|
625
|
+
if ((cur[2] & 0xc0) != 0x80)
|
626
|
+
goto encoding_error;
|
627
|
+
if ((c & 0xf0) == 0xf0) {
|
628
|
+
if (cur[3] == 0) {
|
629
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
630
|
+
cur = ctxt->input->cur;
|
631
|
+
}
|
632
|
+
if (((c & 0xf8) != 0xf0) ||
|
633
|
+
((cur[3] & 0xc0) != 0x80))
|
634
|
+
goto encoding_error;
|
635
|
+
/* 4-byte code */
|
636
|
+
*len = 4;
|
637
|
+
val = (cur[0] & 0x7) << 18;
|
638
|
+
val |= (cur[1] & 0x3f) << 12;
|
639
|
+
val |= (cur[2] & 0x3f) << 6;
|
640
|
+
val |= cur[3] & 0x3f;
|
641
|
+
if (val < 0x10000)
|
642
|
+
goto encoding_error;
|
643
|
+
} else {
|
644
|
+
/* 3-byte code */
|
645
|
+
*len = 3;
|
646
|
+
val = (cur[0] & 0xf) << 12;
|
647
|
+
val |= (cur[1] & 0x3f) << 6;
|
648
|
+
val |= cur[2] & 0x3f;
|
649
|
+
if (val < 0x800)
|
650
|
+
goto encoding_error;
|
651
|
+
}
|
652
|
+
} else {
|
653
|
+
/* 2-byte code */
|
654
|
+
*len = 2;
|
655
|
+
val = (cur[0] & 0x1f) << 6;
|
656
|
+
val |= cur[1] & 0x3f;
|
657
|
+
if (val < 0x80)
|
658
|
+
goto encoding_error;
|
659
|
+
}
|
660
|
+
if (!IS_CHAR(val)) {
|
661
|
+
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
|
662
|
+
"Char 0x%X out of allowed range\n", val);
|
663
|
+
}
|
664
|
+
return(val);
|
665
|
+
} else {
|
666
|
+
/* 1-byte code */
|
667
|
+
*len = 1;
|
668
|
+
if (*ctxt->input->cur == 0)
|
669
|
+
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
|
670
|
+
if ((*ctxt->input->cur == 0) &&
|
671
|
+
(ctxt->input->end > ctxt->input->cur)) {
|
672
|
+
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
|
673
|
+
"Char 0x0 out of allowed range\n", 0);
|
674
|
+
}
|
675
|
+
if (*ctxt->input->cur == 0xD) {
|
676
|
+
if (ctxt->input->cur[1] == 0xA) {
|
677
|
+
ctxt->input->cur++;
|
678
|
+
}
|
679
|
+
return(0xA);
|
680
|
+
}
|
681
|
+
return((int) *ctxt->input->cur);
|
682
|
+
}
|
683
|
+
}
|
684
|
+
/*
|
685
|
+
* Assume it's a fixed length encoding (1) with
|
686
|
+
* a compatible encoding for the ASCII set, since
|
687
|
+
* XML constructs only use < 128 chars
|
688
|
+
*/
|
689
|
+
*len = 1;
|
690
|
+
if (*ctxt->input->cur == 0xD) {
|
691
|
+
if (ctxt->input->cur[1] == 0xA) {
|
692
|
+
ctxt->input->cur++;
|
693
|
+
}
|
694
|
+
return(0xA);
|
695
|
+
}
|
696
|
+
return((int) *ctxt->input->cur);
|
697
|
+
encoding_error:
|
698
|
+
/*
|
699
|
+
* An encoding problem may arise from a truncated input buffer
|
700
|
+
* splitting a character in the middle. In that case do not raise
|
701
|
+
* an error but return 0 to indicate an end of stream problem
|
702
|
+
*/
|
703
|
+
if (ctxt->input->end - ctxt->input->cur < 4) {
|
704
|
+
*len = 0;
|
705
|
+
return(0);
|
706
|
+
}
|
707
|
+
|
708
|
+
/*
|
709
|
+
* If we detect an UTF8 error that probably mean that the
|
710
|
+
* input encoding didn't get properly advertised in the
|
711
|
+
* declaration header. Report the error and switch the encoding
|
712
|
+
* to ISO-Latin-1 (if you don't like this policy, just declare the
|
713
|
+
* encoding !)
|
714
|
+
*/
|
715
|
+
{
|
716
|
+
char buffer[150];
|
717
|
+
|
718
|
+
snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
|
719
|
+
ctxt->input->cur[0], ctxt->input->cur[1],
|
720
|
+
ctxt->input->cur[2], ctxt->input->cur[3]);
|
721
|
+
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
|
722
|
+
"Input is not proper UTF-8, indicate encoding !\n%s",
|
723
|
+
BAD_CAST buffer, NULL);
|
724
|
+
}
|
725
|
+
ctxt->charset = XML_CHAR_ENCODING_8859_1;
|
726
|
+
*len = 1;
|
727
|
+
return((int) *ctxt->input->cur);
|
728
|
+
}
|
729
|
+
|
730
|
+
/**
|
731
|
+
* xmlStringCurrentChar:
|
732
|
+
* @ctxt: the XML parser context
|
733
|
+
* @cur: pointer to the beginning of the char
|
734
|
+
* @len: pointer to the length of the char read
|
735
|
+
*
|
736
|
+
* The current char value, if using UTF-8 this may actually span multiple
|
737
|
+
* bytes in the input buffer.
|
738
|
+
*
|
739
|
+
* Returns the current char value and its length
|
740
|
+
*/
|
741
|
+
|
742
|
+
int
|
743
|
+
xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
|
744
|
+
{
|
745
|
+
if ((len == NULL) || (cur == NULL)) return(0);
|
746
|
+
if ((ctxt == NULL) || (ctxt->charset == XML_CHAR_ENCODING_UTF8)) {
|
747
|
+
/*
|
748
|
+
* We are supposed to handle UTF8, check it's valid
|
749
|
+
* From rfc2044: encoding of the Unicode values on UTF-8:
|
750
|
+
*
|
751
|
+
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
752
|
+
* 0000 0000-0000 007F 0xxxxxxx
|
753
|
+
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
754
|
+
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
755
|
+
*
|
756
|
+
* Check for the 0x110000 limit too
|
757
|
+
*/
|
758
|
+
unsigned char c;
|
759
|
+
unsigned int val;
|
760
|
+
|
761
|
+
c = *cur;
|
762
|
+
if (c & 0x80) {
|
763
|
+
if ((cur[1] & 0xc0) != 0x80)
|
764
|
+
goto encoding_error;
|
765
|
+
if ((c & 0xe0) == 0xe0) {
|
766
|
+
|
767
|
+
if ((cur[2] & 0xc0) != 0x80)
|
768
|
+
goto encoding_error;
|
769
|
+
if ((c & 0xf0) == 0xf0) {
|
770
|
+
if (((c & 0xf8) != 0xf0) || ((cur[3] & 0xc0) != 0x80))
|
771
|
+
goto encoding_error;
|
772
|
+
/* 4-byte code */
|
773
|
+
*len = 4;
|
774
|
+
val = (cur[0] & 0x7) << 18;
|
775
|
+
val |= (cur[1] & 0x3f) << 12;
|
776
|
+
val |= (cur[2] & 0x3f) << 6;
|
777
|
+
val |= cur[3] & 0x3f;
|
778
|
+
} else {
|
779
|
+
/* 3-byte code */
|
780
|
+
*len = 3;
|
781
|
+
val = (cur[0] & 0xf) << 12;
|
782
|
+
val |= (cur[1] & 0x3f) << 6;
|
783
|
+
val |= cur[2] & 0x3f;
|
784
|
+
}
|
785
|
+
} else {
|
786
|
+
/* 2-byte code */
|
787
|
+
*len = 2;
|
788
|
+
val = (cur[0] & 0x1f) << 6;
|
789
|
+
val |= cur[1] & 0x3f;
|
790
|
+
}
|
791
|
+
if (!IS_CHAR(val)) {
|
792
|
+
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
|
793
|
+
"Char 0x%X out of allowed range\n", val);
|
794
|
+
}
|
795
|
+
return (val);
|
796
|
+
} else {
|
797
|
+
/* 1-byte code */
|
798
|
+
*len = 1;
|
799
|
+
return ((int) *cur);
|
800
|
+
}
|
801
|
+
}
|
802
|
+
/*
|
803
|
+
* Assume it's a fixed length encoding (1) with
|
804
|
+
* a compatible encoding for the ASCII set, since
|
805
|
+
* XML constructs only use < 128 chars
|
806
|
+
*/
|
807
|
+
*len = 1;
|
808
|
+
return ((int) *cur);
|
809
|
+
encoding_error:
|
810
|
+
|
811
|
+
/*
|
812
|
+
* An encoding problem may arise from a truncated input buffer
|
813
|
+
* splitting a character in the middle. In that case do not raise
|
814
|
+
* an error but return 0 to indicate an end of stream problem
|
815
|
+
*/
|
816
|
+
if ((ctxt == NULL) || (ctxt->input == NULL) ||
|
817
|
+
(ctxt->input->end - ctxt->input->cur < 4)) {
|
818
|
+
*len = 0;
|
819
|
+
return(0);
|
820
|
+
}
|
821
|
+
/*
|
822
|
+
* If we detect an UTF8 error that probably mean that the
|
823
|
+
* input encoding didn't get properly advertised in the
|
824
|
+
* declaration header. Report the error and switch the encoding
|
825
|
+
* to ISO-Latin-1 (if you don't like this policy, just declare the
|
826
|
+
* encoding !)
|
827
|
+
*/
|
828
|
+
{
|
829
|
+
char buffer[150];
|
830
|
+
|
831
|
+
snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
|
832
|
+
ctxt->input->cur[0], ctxt->input->cur[1],
|
833
|
+
ctxt->input->cur[2], ctxt->input->cur[3]);
|
834
|
+
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
|
835
|
+
"Input is not proper UTF-8, indicate encoding !\n%s",
|
836
|
+
BAD_CAST buffer, NULL);
|
837
|
+
}
|
838
|
+
*len = 1;
|
839
|
+
return ((int) *cur);
|
840
|
+
}
|
841
|
+
|
842
|
+
/**
|
843
|
+
* xmlCopyCharMultiByte:
|
844
|
+
* @out: pointer to an array of xmlChar
|
845
|
+
* @val: the char value
|
846
|
+
*
|
847
|
+
* append the char value in the array
|
848
|
+
*
|
849
|
+
* Returns the number of xmlChar written
|
850
|
+
*/
|
851
|
+
int
|
852
|
+
xmlCopyCharMultiByte(xmlChar *out, int val) {
|
853
|
+
if (out == NULL) return(0);
|
854
|
+
/*
|
855
|
+
* We are supposed to handle UTF8, check it's valid
|
856
|
+
* From rfc2044: encoding of the Unicode values on UTF-8:
|
857
|
+
*
|
858
|
+
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
859
|
+
* 0000 0000-0000 007F 0xxxxxxx
|
860
|
+
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
861
|
+
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
862
|
+
*/
|
863
|
+
if (val >= 0x80) {
|
864
|
+
xmlChar *savedout = out;
|
865
|
+
int bits;
|
866
|
+
if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
|
867
|
+
else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6;}
|
868
|
+
else if (val < 0x110000) { *out++= (val >> 18) | 0xF0; bits= 12; }
|
869
|
+
else {
|
870
|
+
xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
|
871
|
+
"Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
|
872
|
+
val);
|
873
|
+
return(0);
|
874
|
+
}
|
875
|
+
for ( ; bits >= 0; bits-= 6)
|
876
|
+
*out++= ((val >> bits) & 0x3F) | 0x80 ;
|
877
|
+
return (out - savedout);
|
878
|
+
}
|
879
|
+
*out = (xmlChar) val;
|
880
|
+
return 1;
|
881
|
+
}
|
882
|
+
|
883
|
+
/**
|
884
|
+
* xmlCopyChar:
|
885
|
+
* @len: Ignored, compatibility
|
886
|
+
* @out: pointer to an array of xmlChar
|
887
|
+
* @val: the char value
|
888
|
+
*
|
889
|
+
* append the char value in the array
|
890
|
+
*
|
891
|
+
* Returns the number of xmlChar written
|
892
|
+
*/
|
893
|
+
|
894
|
+
int
|
895
|
+
xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
|
896
|
+
if (out == NULL) return(0);
|
897
|
+
/* the len parameter is ignored */
|
898
|
+
if (val >= 0x80) {
|
899
|
+
return(xmlCopyCharMultiByte (out, val));
|
900
|
+
}
|
901
|
+
*out = (xmlChar) val;
|
902
|
+
return 1;
|
903
|
+
}
|
904
|
+
|
905
|
+
/************************************************************************
|
906
|
+
* *
|
907
|
+
* Commodity functions to switch encodings *
|
908
|
+
* *
|
909
|
+
************************************************************************/
|
910
|
+
|
911
|
+
static int
|
912
|
+
xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
|
913
|
+
xmlCharEncodingHandlerPtr handler, int len);
|
914
|
+
static int
|
915
|
+
xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
916
|
+
xmlCharEncodingHandlerPtr handler, int len);
|
917
|
+
/**
|
918
|
+
* xmlSwitchEncoding:
|
919
|
+
* @ctxt: the parser context
|
920
|
+
* @enc: the encoding value (number)
|
921
|
+
*
|
922
|
+
* change the input functions when discovering the character encoding
|
923
|
+
* of a given entity.
|
924
|
+
*
|
925
|
+
* Returns 0 in case of success, -1 otherwise
|
926
|
+
*/
|
927
|
+
int
|
928
|
+
xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
|
929
|
+
{
|
930
|
+
xmlCharEncodingHandlerPtr handler;
|
931
|
+
int len = -1;
|
932
|
+
int ret;
|
933
|
+
|
934
|
+
if (ctxt == NULL) return(-1);
|
935
|
+
switch (enc) {
|
936
|
+
case XML_CHAR_ENCODING_ERROR:
|
937
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
|
938
|
+
"encoding unknown\n", NULL, NULL);
|
939
|
+
return(-1);
|
940
|
+
case XML_CHAR_ENCODING_NONE:
|
941
|
+
/* let's assume it's UTF-8 without the XML decl */
|
942
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
943
|
+
return(0);
|
944
|
+
case XML_CHAR_ENCODING_UTF8:
|
945
|
+
/* default encoding, no conversion should be needed */
|
946
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
947
|
+
|
948
|
+
/*
|
949
|
+
* Errata on XML-1.0 June 20 2001
|
950
|
+
* Specific handling of the Byte Order Mark for
|
951
|
+
* UTF-8
|
952
|
+
*/
|
953
|
+
if ((ctxt->input != NULL) &&
|
954
|
+
(ctxt->input->cur[0] == 0xEF) &&
|
955
|
+
(ctxt->input->cur[1] == 0xBB) &&
|
956
|
+
(ctxt->input->cur[2] == 0xBF)) {
|
957
|
+
ctxt->input->cur += 3;
|
958
|
+
}
|
959
|
+
return(0);
|
960
|
+
case XML_CHAR_ENCODING_UTF16LE:
|
961
|
+
case XML_CHAR_ENCODING_UTF16BE:
|
962
|
+
/*The raw input characters are encoded
|
963
|
+
*in UTF-16. As we expect this function
|
964
|
+
*to be called after xmlCharEncInFunc, we expect
|
965
|
+
*ctxt->input->cur to contain UTF-8 encoded characters.
|
966
|
+
*So the raw UTF16 Byte Order Mark
|
967
|
+
*has also been converted into
|
968
|
+
*an UTF-8 BOM. Let's skip that BOM.
|
969
|
+
*/
|
970
|
+
if ((ctxt->input != NULL) && (ctxt->input->cur != NULL) &&
|
971
|
+
(ctxt->input->cur[0] == 0xEF) &&
|
972
|
+
(ctxt->input->cur[1] == 0xBB) &&
|
973
|
+
(ctxt->input->cur[2] == 0xBF)) {
|
974
|
+
ctxt->input->cur += 3;
|
975
|
+
}
|
976
|
+
len = 90;
|
977
|
+
break;
|
978
|
+
case XML_CHAR_ENCODING_UCS2:
|
979
|
+
len = 90;
|
980
|
+
break;
|
981
|
+
case XML_CHAR_ENCODING_UCS4BE:
|
982
|
+
case XML_CHAR_ENCODING_UCS4LE:
|
983
|
+
case XML_CHAR_ENCODING_UCS4_2143:
|
984
|
+
case XML_CHAR_ENCODING_UCS4_3412:
|
985
|
+
len = 180;
|
986
|
+
break;
|
987
|
+
case XML_CHAR_ENCODING_EBCDIC:
|
988
|
+
case XML_CHAR_ENCODING_8859_1:
|
989
|
+
case XML_CHAR_ENCODING_8859_2:
|
990
|
+
case XML_CHAR_ENCODING_8859_3:
|
991
|
+
case XML_CHAR_ENCODING_8859_4:
|
992
|
+
case XML_CHAR_ENCODING_8859_5:
|
993
|
+
case XML_CHAR_ENCODING_8859_6:
|
994
|
+
case XML_CHAR_ENCODING_8859_7:
|
995
|
+
case XML_CHAR_ENCODING_8859_8:
|
996
|
+
case XML_CHAR_ENCODING_8859_9:
|
997
|
+
case XML_CHAR_ENCODING_ASCII:
|
998
|
+
case XML_CHAR_ENCODING_2022_JP:
|
999
|
+
case XML_CHAR_ENCODING_SHIFT_JIS:
|
1000
|
+
case XML_CHAR_ENCODING_EUC_JP:
|
1001
|
+
len = 45;
|
1002
|
+
break;
|
1003
|
+
}
|
1004
|
+
handler = xmlGetCharEncodingHandler(enc);
|
1005
|
+
if (handler == NULL) {
|
1006
|
+
/*
|
1007
|
+
* Default handlers.
|
1008
|
+
*/
|
1009
|
+
switch (enc) {
|
1010
|
+
case XML_CHAR_ENCODING_ASCII:
|
1011
|
+
/* default encoding, no conversion should be needed */
|
1012
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
1013
|
+
return(0);
|
1014
|
+
case XML_CHAR_ENCODING_UTF16LE:
|
1015
|
+
break;
|
1016
|
+
case XML_CHAR_ENCODING_UTF16BE:
|
1017
|
+
break;
|
1018
|
+
case XML_CHAR_ENCODING_UCS4LE:
|
1019
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1020
|
+
"encoding not supported %s\n",
|
1021
|
+
BAD_CAST "USC4 little endian", NULL);
|
1022
|
+
break;
|
1023
|
+
case XML_CHAR_ENCODING_UCS4BE:
|
1024
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1025
|
+
"encoding not supported %s\n",
|
1026
|
+
BAD_CAST "USC4 big endian", NULL);
|
1027
|
+
break;
|
1028
|
+
case XML_CHAR_ENCODING_EBCDIC:
|
1029
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1030
|
+
"encoding not supported %s\n",
|
1031
|
+
BAD_CAST "EBCDIC", NULL);
|
1032
|
+
break;
|
1033
|
+
case XML_CHAR_ENCODING_UCS4_2143:
|
1034
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1035
|
+
"encoding not supported %s\n",
|
1036
|
+
BAD_CAST "UCS4 2143", NULL);
|
1037
|
+
break;
|
1038
|
+
case XML_CHAR_ENCODING_UCS4_3412:
|
1039
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1040
|
+
"encoding not supported %s\n",
|
1041
|
+
BAD_CAST "UCS4 3412", NULL);
|
1042
|
+
break;
|
1043
|
+
case XML_CHAR_ENCODING_UCS2:
|
1044
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1045
|
+
"encoding not supported %s\n",
|
1046
|
+
BAD_CAST "UCS2", NULL);
|
1047
|
+
break;
|
1048
|
+
case XML_CHAR_ENCODING_8859_1:
|
1049
|
+
case XML_CHAR_ENCODING_8859_2:
|
1050
|
+
case XML_CHAR_ENCODING_8859_3:
|
1051
|
+
case XML_CHAR_ENCODING_8859_4:
|
1052
|
+
case XML_CHAR_ENCODING_8859_5:
|
1053
|
+
case XML_CHAR_ENCODING_8859_6:
|
1054
|
+
case XML_CHAR_ENCODING_8859_7:
|
1055
|
+
case XML_CHAR_ENCODING_8859_8:
|
1056
|
+
case XML_CHAR_ENCODING_8859_9:
|
1057
|
+
/*
|
1058
|
+
* We used to keep the internal content in the
|
1059
|
+
* document encoding however this turns being unmaintainable
|
1060
|
+
* So xmlGetCharEncodingHandler() will return non-null
|
1061
|
+
* values for this now.
|
1062
|
+
*/
|
1063
|
+
if ((ctxt->inputNr == 1) &&
|
1064
|
+
(ctxt->encoding == NULL) &&
|
1065
|
+
(ctxt->input != NULL) &&
|
1066
|
+
(ctxt->input->encoding != NULL)) {
|
1067
|
+
ctxt->encoding = xmlStrdup(ctxt->input->encoding);
|
1068
|
+
}
|
1069
|
+
ctxt->charset = enc;
|
1070
|
+
return(0);
|
1071
|
+
case XML_CHAR_ENCODING_2022_JP:
|
1072
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1073
|
+
"encoding not supported %s\n",
|
1074
|
+
BAD_CAST "ISO-2022-JP", NULL);
|
1075
|
+
break;
|
1076
|
+
case XML_CHAR_ENCODING_SHIFT_JIS:
|
1077
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1078
|
+
"encoding not supported %s\n",
|
1079
|
+
BAD_CAST "Shift_JIS", NULL);
|
1080
|
+
break;
|
1081
|
+
case XML_CHAR_ENCODING_EUC_JP:
|
1082
|
+
__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
|
1083
|
+
"encoding not supported %s\n",
|
1084
|
+
BAD_CAST "EUC-JP", NULL);
|
1085
|
+
break;
|
1086
|
+
default:
|
1087
|
+
break;
|
1088
|
+
}
|
1089
|
+
}
|
1090
|
+
/*
|
1091
|
+
* TODO: We could recover from errors in external entities if we
|
1092
|
+
* didn't stop the parser. But most callers of this function don't
|
1093
|
+
* check the return value.
|
1094
|
+
*/
|
1095
|
+
if (handler == NULL) {
|
1096
|
+
xmlStopParser(ctxt);
|
1097
|
+
return(-1);
|
1098
|
+
}
|
1099
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
1100
|
+
ret = xmlSwitchToEncodingInt(ctxt, handler, len);
|
1101
|
+
if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
|
1102
|
+
/*
|
1103
|
+
* on encoding conversion errors, stop the parser
|
1104
|
+
*/
|
1105
|
+
xmlStopParser(ctxt);
|
1106
|
+
ctxt->errNo = XML_I18N_CONV_FAILED;
|
1107
|
+
}
|
1108
|
+
return(ret);
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
/**
|
1112
|
+
* xmlSwitchInputEncoding:
|
1113
|
+
* @ctxt: the parser context
|
1114
|
+
* @input: the input stream
|
1115
|
+
* @handler: the encoding handler
|
1116
|
+
* @len: the number of bytes to convert for the first line or -1
|
1117
|
+
*
|
1118
|
+
* change the input functions when discovering the character encoding
|
1119
|
+
* of a given entity.
|
1120
|
+
*
|
1121
|
+
* Returns 0 in case of success, -1 otherwise
|
1122
|
+
*/
|
1123
|
+
static int
|
1124
|
+
xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
1125
|
+
xmlCharEncodingHandlerPtr handler, int len)
|
1126
|
+
{
|
1127
|
+
int nbchars;
|
1128
|
+
|
1129
|
+
if (handler == NULL)
|
1130
|
+
return (-1);
|
1131
|
+
if (input == NULL)
|
1132
|
+
return (-1);
|
1133
|
+
if (input->buf != NULL) {
|
1134
|
+
if (input->buf->encoder != NULL) {
|
1135
|
+
/*
|
1136
|
+
* Check in case the auto encoding detection triggered
|
1137
|
+
* in already.
|
1138
|
+
*/
|
1139
|
+
if (input->buf->encoder == handler)
|
1140
|
+
return (0);
|
1141
|
+
|
1142
|
+
/*
|
1143
|
+
* "UTF-16" can be used for both LE and BE
|
1144
|
+
if ((!xmlStrncmp(BAD_CAST input->buf->encoder->name,
|
1145
|
+
BAD_CAST "UTF-16", 6)) &&
|
1146
|
+
(!xmlStrncmp(BAD_CAST handler->name,
|
1147
|
+
BAD_CAST "UTF-16", 6))) {
|
1148
|
+
return(0);
|
1149
|
+
}
|
1150
|
+
*/
|
1151
|
+
|
1152
|
+
/*
|
1153
|
+
* Note: this is a bit dangerous, but that's what it
|
1154
|
+
* takes to use nearly compatible signature for different
|
1155
|
+
* encodings.
|
1156
|
+
*
|
1157
|
+
* FIXME: Encoders might buffer partial byte sequences, so
|
1158
|
+
* this probably can't work. We should return an error and
|
1159
|
+
* make sure that callers never try to switch the encoding
|
1160
|
+
* twice.
|
1161
|
+
*/
|
1162
|
+
xmlCharEncCloseFunc(input->buf->encoder);
|
1163
|
+
input->buf->encoder = handler;
|
1164
|
+
return (0);
|
1165
|
+
}
|
1166
|
+
input->buf->encoder = handler;
|
1167
|
+
|
1168
|
+
/*
|
1169
|
+
* Is there already some content down the pipe to convert ?
|
1170
|
+
*/
|
1171
|
+
if (xmlBufIsEmpty(input->buf->buffer) == 0) {
|
1172
|
+
int processed;
|
1173
|
+
unsigned int use;
|
1174
|
+
|
1175
|
+
/*
|
1176
|
+
* Specific handling of the Byte Order Mark for
|
1177
|
+
* UTF-16
|
1178
|
+
*/
|
1179
|
+
if ((handler->name != NULL) &&
|
1180
|
+
(!strcmp(handler->name, "UTF-16LE") ||
|
1181
|
+
!strcmp(handler->name, "UTF-16")) &&
|
1182
|
+
(input->cur[0] == 0xFF) && (input->cur[1] == 0xFE)) {
|
1183
|
+
input->cur += 2;
|
1184
|
+
}
|
1185
|
+
if ((handler->name != NULL) &&
|
1186
|
+
(!strcmp(handler->name, "UTF-16BE")) &&
|
1187
|
+
(input->cur[0] == 0xFE) && (input->cur[1] == 0xFF)) {
|
1188
|
+
input->cur += 2;
|
1189
|
+
}
|
1190
|
+
/*
|
1191
|
+
* Errata on XML-1.0 June 20 2001
|
1192
|
+
* Specific handling of the Byte Order Mark for
|
1193
|
+
* UTF-8
|
1194
|
+
*/
|
1195
|
+
if ((handler->name != NULL) &&
|
1196
|
+
(!strcmp(handler->name, "UTF-8")) &&
|
1197
|
+
(input->cur[0] == 0xEF) &&
|
1198
|
+
(input->cur[1] == 0xBB) && (input->cur[2] == 0xBF)) {
|
1199
|
+
input->cur += 3;
|
1200
|
+
}
|
1201
|
+
|
1202
|
+
/*
|
1203
|
+
* Shrink the current input buffer.
|
1204
|
+
* Move it as the raw buffer and create a new input buffer
|
1205
|
+
*/
|
1206
|
+
processed = input->cur - input->base;
|
1207
|
+
xmlBufShrink(input->buf->buffer, processed);
|
1208
|
+
input->buf->raw = input->buf->buffer;
|
1209
|
+
input->buf->buffer = xmlBufCreate();
|
1210
|
+
input->buf->rawconsumed = processed;
|
1211
|
+
use = xmlBufUse(input->buf->raw);
|
1212
|
+
|
1213
|
+
if (ctxt->html) {
|
1214
|
+
/*
|
1215
|
+
* convert as much as possible of the buffer
|
1216
|
+
*/
|
1217
|
+
nbchars = xmlCharEncInput(input->buf, 1);
|
1218
|
+
} else {
|
1219
|
+
/*
|
1220
|
+
* convert just enough to get
|
1221
|
+
* '<?xml version="1.0" encoding="xxx"?>'
|
1222
|
+
* parsed with the autodetected encoding
|
1223
|
+
* into the parser reading buffer.
|
1224
|
+
*/
|
1225
|
+
nbchars = xmlCharEncFirstLineInput(input->buf, len);
|
1226
|
+
}
|
1227
|
+
xmlBufResetInput(input->buf->buffer, input);
|
1228
|
+
if (nbchars < 0) {
|
1229
|
+
xmlErrInternal(ctxt,
|
1230
|
+
"switching encoding: encoder error\n",
|
1231
|
+
NULL);
|
1232
|
+
return (-1);
|
1233
|
+
}
|
1234
|
+
input->buf->rawconsumed += use - xmlBufUse(input->buf->raw);
|
1235
|
+
}
|
1236
|
+
return (0);
|
1237
|
+
} else if (input->length == 0) {
|
1238
|
+
/*
|
1239
|
+
* When parsing a static memory array one must know the
|
1240
|
+
* size to be able to convert the buffer.
|
1241
|
+
*/
|
1242
|
+
xmlErrInternal(ctxt, "switching encoding : no input\n", NULL);
|
1243
|
+
/*
|
1244
|
+
* Callers assume that the input buffer takes ownership of the
|
1245
|
+
* encoding handler. xmlCharEncCloseFunc frees unregistered
|
1246
|
+
* handlers and avoids a memory leak.
|
1247
|
+
*/
|
1248
|
+
xmlCharEncCloseFunc(handler);
|
1249
|
+
return (-1);
|
1250
|
+
}
|
1251
|
+
/*
|
1252
|
+
* We should actually raise an error here, see issue #34.
|
1253
|
+
*/
|
1254
|
+
xmlCharEncCloseFunc(handler);
|
1255
|
+
return (0);
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
/**
|
1259
|
+
* xmlSwitchInputEncoding:
|
1260
|
+
* @ctxt: the parser context
|
1261
|
+
* @input: the input stream
|
1262
|
+
* @handler: the encoding handler
|
1263
|
+
*
|
1264
|
+
* change the input functions when discovering the character encoding
|
1265
|
+
* of a given entity.
|
1266
|
+
*
|
1267
|
+
* Returns 0 in case of success, -1 otherwise
|
1268
|
+
*/
|
1269
|
+
int
|
1270
|
+
xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
1271
|
+
xmlCharEncodingHandlerPtr handler) {
|
1272
|
+
return(xmlSwitchInputEncodingInt(ctxt, input, handler, -1));
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
/**
|
1276
|
+
* xmlSwitchToEncodingInt:
|
1277
|
+
* @ctxt: the parser context
|
1278
|
+
* @handler: the encoding handler
|
1279
|
+
* @len: the length to convert or -1
|
1280
|
+
*
|
1281
|
+
* change the input functions when discovering the character encoding
|
1282
|
+
* of a given entity, and convert only @len bytes of the output, this
|
1283
|
+
* is needed on auto detect to allows any declared encoding later to
|
1284
|
+
* convert the actual content after the xmlDecl
|
1285
|
+
*
|
1286
|
+
* Returns 0 in case of success, -1 otherwise
|
1287
|
+
*/
|
1288
|
+
static int
|
1289
|
+
xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
|
1290
|
+
xmlCharEncodingHandlerPtr handler, int len) {
|
1291
|
+
int ret = 0;
|
1292
|
+
|
1293
|
+
if (handler != NULL) {
|
1294
|
+
if (ctxt->input != NULL) {
|
1295
|
+
ret = xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, len);
|
1296
|
+
} else {
|
1297
|
+
xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
|
1298
|
+
NULL);
|
1299
|
+
return(-1);
|
1300
|
+
}
|
1301
|
+
/*
|
1302
|
+
* The parsing is now done in UTF8 natively
|
1303
|
+
*/
|
1304
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
1305
|
+
} else
|
1306
|
+
return(-1);
|
1307
|
+
return(ret);
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
/**
|
1311
|
+
* xmlSwitchToEncoding:
|
1312
|
+
* @ctxt: the parser context
|
1313
|
+
* @handler: the encoding handler
|
1314
|
+
*
|
1315
|
+
* change the input functions when discovering the character encoding
|
1316
|
+
* of a given entity.
|
1317
|
+
*
|
1318
|
+
* Returns 0 in case of success, -1 otherwise
|
1319
|
+
*/
|
1320
|
+
int
|
1321
|
+
xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
|
1322
|
+
{
|
1323
|
+
return (xmlSwitchToEncodingInt(ctxt, handler, -1));
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
/************************************************************************
|
1327
|
+
* *
|
1328
|
+
* Commodity functions to handle entities processing *
|
1329
|
+
* *
|
1330
|
+
************************************************************************/
|
1331
|
+
|
1332
|
+
/**
|
1333
|
+
* xmlFreeInputStream:
|
1334
|
+
* @input: an xmlParserInputPtr
|
1335
|
+
*
|
1336
|
+
* Free up an input stream.
|
1337
|
+
*/
|
1338
|
+
void
|
1339
|
+
xmlFreeInputStream(xmlParserInputPtr input) {
|
1340
|
+
if (input == NULL) return;
|
1341
|
+
|
1342
|
+
if (input->filename != NULL) xmlFree((char *) input->filename);
|
1343
|
+
if (input->directory != NULL) xmlFree((char *) input->directory);
|
1344
|
+
if (input->encoding != NULL) xmlFree((char *) input->encoding);
|
1345
|
+
if (input->version != NULL) xmlFree((char *) input->version);
|
1346
|
+
if ((input->free != NULL) && (input->base != NULL))
|
1347
|
+
input->free((xmlChar *) input->base);
|
1348
|
+
if (input->buf != NULL)
|
1349
|
+
xmlFreeParserInputBuffer(input->buf);
|
1350
|
+
xmlFree(input);
|
1351
|
+
}
|
1352
|
+
|
1353
|
+
/**
|
1354
|
+
* xmlNewInputStream:
|
1355
|
+
* @ctxt: an XML parser context
|
1356
|
+
*
|
1357
|
+
* Create a new input stream structure.
|
1358
|
+
*
|
1359
|
+
* Returns the new input stream or NULL
|
1360
|
+
*/
|
1361
|
+
xmlParserInputPtr
|
1362
|
+
xmlNewInputStream(xmlParserCtxtPtr ctxt) {
|
1363
|
+
xmlParserInputPtr input;
|
1364
|
+
|
1365
|
+
input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
|
1366
|
+
if (input == NULL) {
|
1367
|
+
xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
|
1368
|
+
return(NULL);
|
1369
|
+
}
|
1370
|
+
memset(input, 0, sizeof(xmlParserInput));
|
1371
|
+
input->line = 1;
|
1372
|
+
input->col = 1;
|
1373
|
+
input->standalone = -1;
|
1374
|
+
|
1375
|
+
/*
|
1376
|
+
* If the context is NULL the id cannot be initialized, but that
|
1377
|
+
* should not happen while parsing which is the situation where
|
1378
|
+
* the id is actually needed.
|
1379
|
+
*/
|
1380
|
+
if (ctxt != NULL)
|
1381
|
+
input->id = ctxt->input_id++;
|
1382
|
+
|
1383
|
+
return(input);
|
1384
|
+
}
|
1385
|
+
|
1386
|
+
/**
|
1387
|
+
* xmlNewIOInputStream:
|
1388
|
+
* @ctxt: an XML parser context
|
1389
|
+
* @input: an I/O Input
|
1390
|
+
* @enc: the charset encoding if known
|
1391
|
+
*
|
1392
|
+
* Create a new input stream structure encapsulating the @input into
|
1393
|
+
* a stream suitable for the parser.
|
1394
|
+
*
|
1395
|
+
* Returns the new input stream or NULL
|
1396
|
+
*/
|
1397
|
+
xmlParserInputPtr
|
1398
|
+
xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
|
1399
|
+
xmlCharEncoding enc) {
|
1400
|
+
xmlParserInputPtr inputStream;
|
1401
|
+
|
1402
|
+
if (input == NULL) return(NULL);
|
1403
|
+
if (xmlParserDebugEntities)
|
1404
|
+
xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
|
1405
|
+
inputStream = xmlNewInputStream(ctxt);
|
1406
|
+
if (inputStream == NULL) {
|
1407
|
+
return(NULL);
|
1408
|
+
}
|
1409
|
+
inputStream->filename = NULL;
|
1410
|
+
inputStream->buf = input;
|
1411
|
+
xmlBufResetInput(inputStream->buf->buffer, inputStream);
|
1412
|
+
|
1413
|
+
if (enc != XML_CHAR_ENCODING_NONE) {
|
1414
|
+
xmlSwitchEncoding(ctxt, enc);
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
return(inputStream);
|
1418
|
+
}
|
1419
|
+
|
1420
|
+
/**
|
1421
|
+
* xmlNewEntityInputStream:
|
1422
|
+
* @ctxt: an XML parser context
|
1423
|
+
* @entity: an Entity pointer
|
1424
|
+
*
|
1425
|
+
* Create a new input stream based on an xmlEntityPtr
|
1426
|
+
*
|
1427
|
+
* Returns the new input stream or NULL
|
1428
|
+
*/
|
1429
|
+
xmlParserInputPtr
|
1430
|
+
xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
|
1431
|
+
xmlParserInputPtr input;
|
1432
|
+
|
1433
|
+
if (entity == NULL) {
|
1434
|
+
xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
|
1435
|
+
NULL);
|
1436
|
+
return(NULL);
|
1437
|
+
}
|
1438
|
+
if (xmlParserDebugEntities)
|
1439
|
+
xmlGenericError(xmlGenericErrorContext,
|
1440
|
+
"new input from entity: %s\n", entity->name);
|
1441
|
+
if (entity->content == NULL) {
|
1442
|
+
switch (entity->etype) {
|
1443
|
+
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
|
1444
|
+
xmlErrInternal(ctxt, "Cannot parse entity %s\n",
|
1445
|
+
entity->name);
|
1446
|
+
break;
|
1447
|
+
case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
|
1448
|
+
case XML_EXTERNAL_PARAMETER_ENTITY:
|
1449
|
+
return(xmlLoadExternalEntity((char *) entity->URI,
|
1450
|
+
(char *) entity->ExternalID, ctxt));
|
1451
|
+
case XML_INTERNAL_GENERAL_ENTITY:
|
1452
|
+
xmlErrInternal(ctxt,
|
1453
|
+
"Internal entity %s without content !\n",
|
1454
|
+
entity->name);
|
1455
|
+
break;
|
1456
|
+
case XML_INTERNAL_PARAMETER_ENTITY:
|
1457
|
+
xmlErrInternal(ctxt,
|
1458
|
+
"Internal parameter entity %s without content !\n",
|
1459
|
+
entity->name);
|
1460
|
+
break;
|
1461
|
+
case XML_INTERNAL_PREDEFINED_ENTITY:
|
1462
|
+
xmlErrInternal(ctxt,
|
1463
|
+
"Predefined entity %s without content !\n",
|
1464
|
+
entity->name);
|
1465
|
+
break;
|
1466
|
+
}
|
1467
|
+
return(NULL);
|
1468
|
+
}
|
1469
|
+
input = xmlNewInputStream(ctxt);
|
1470
|
+
if (input == NULL) {
|
1471
|
+
return(NULL);
|
1472
|
+
}
|
1473
|
+
if (entity->URI != NULL)
|
1474
|
+
input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
|
1475
|
+
input->base = entity->content;
|
1476
|
+
if (entity->length == 0)
|
1477
|
+
entity->length = xmlStrlen(entity->content);
|
1478
|
+
input->cur = entity->content;
|
1479
|
+
input->length = entity->length;
|
1480
|
+
input->end = &entity->content[input->length];
|
1481
|
+
return(input);
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
/**
|
1485
|
+
* xmlNewStringInputStream:
|
1486
|
+
* @ctxt: an XML parser context
|
1487
|
+
* @buffer: an memory buffer
|
1488
|
+
*
|
1489
|
+
* Create a new input stream based on a memory buffer.
|
1490
|
+
* Returns the new input stream
|
1491
|
+
*/
|
1492
|
+
xmlParserInputPtr
|
1493
|
+
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
|
1494
|
+
xmlParserInputPtr input;
|
1495
|
+
|
1496
|
+
if (buffer == NULL) {
|
1497
|
+
xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
|
1498
|
+
NULL);
|
1499
|
+
return(NULL);
|
1500
|
+
}
|
1501
|
+
if (xmlParserDebugEntities)
|
1502
|
+
xmlGenericError(xmlGenericErrorContext,
|
1503
|
+
"new fixed input: %.30s\n", buffer);
|
1504
|
+
input = xmlNewInputStream(ctxt);
|
1505
|
+
if (input == NULL) {
|
1506
|
+
xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
|
1507
|
+
return(NULL);
|
1508
|
+
}
|
1509
|
+
input->base = buffer;
|
1510
|
+
input->cur = buffer;
|
1511
|
+
input->length = xmlStrlen(buffer);
|
1512
|
+
input->end = &buffer[input->length];
|
1513
|
+
return(input);
|
1514
|
+
}
|
1515
|
+
|
1516
|
+
/**
|
1517
|
+
* xmlNewInputFromFile:
|
1518
|
+
* @ctxt: an XML parser context
|
1519
|
+
* @filename: the filename to use as entity
|
1520
|
+
*
|
1521
|
+
* Create a new input stream based on a file or an URL.
|
1522
|
+
*
|
1523
|
+
* Returns the new input stream or NULL in case of error
|
1524
|
+
*/
|
1525
|
+
xmlParserInputPtr
|
1526
|
+
xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
|
1527
|
+
xmlParserInputBufferPtr buf;
|
1528
|
+
xmlParserInputPtr inputStream;
|
1529
|
+
char *directory = NULL;
|
1530
|
+
xmlChar *URI = NULL;
|
1531
|
+
|
1532
|
+
if (xmlParserDebugEntities)
|
1533
|
+
xmlGenericError(xmlGenericErrorContext,
|
1534
|
+
"new input from file: %s\n", filename);
|
1535
|
+
if (ctxt == NULL) return(NULL);
|
1536
|
+
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
|
1537
|
+
if (buf == NULL) {
|
1538
|
+
if (filename == NULL)
|
1539
|
+
__xmlLoaderErr(ctxt,
|
1540
|
+
"failed to load external entity: NULL filename \n",
|
1541
|
+
NULL);
|
1542
|
+
else
|
1543
|
+
__xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
|
1544
|
+
(const char *) filename);
|
1545
|
+
return(NULL);
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
inputStream = xmlNewInputStream(ctxt);
|
1549
|
+
if (inputStream == NULL)
|
1550
|
+
return(NULL);
|
1551
|
+
|
1552
|
+
inputStream->buf = buf;
|
1553
|
+
inputStream = xmlCheckHTTPInput(ctxt, inputStream);
|
1554
|
+
if (inputStream == NULL)
|
1555
|
+
return(NULL);
|
1556
|
+
|
1557
|
+
if (inputStream->filename == NULL)
|
1558
|
+
URI = xmlStrdup((xmlChar *) filename);
|
1559
|
+
else
|
1560
|
+
URI = xmlStrdup((xmlChar *) inputStream->filename);
|
1561
|
+
directory = xmlParserGetDirectory((const char *) URI);
|
1562
|
+
if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
|
1563
|
+
inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
|
1564
|
+
if (URI != NULL) xmlFree((char *) URI);
|
1565
|
+
inputStream->directory = directory;
|
1566
|
+
|
1567
|
+
xmlBufResetInput(inputStream->buf->buffer, inputStream);
|
1568
|
+
if ((ctxt->directory == NULL) && (directory != NULL))
|
1569
|
+
ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
|
1570
|
+
return(inputStream);
|
1571
|
+
}
|
1572
|
+
|
1573
|
+
/************************************************************************
|
1574
|
+
* *
|
1575
|
+
* Commodity functions to handle parser contexts *
|
1576
|
+
* *
|
1577
|
+
************************************************************************/
|
1578
|
+
|
1579
|
+
/**
|
1580
|
+
* xmlInitParserCtxt:
|
1581
|
+
* @ctxt: an XML parser context
|
1582
|
+
*
|
1583
|
+
* Initialize a parser context
|
1584
|
+
*
|
1585
|
+
* Returns 0 in case of success and -1 in case of error
|
1586
|
+
*/
|
1587
|
+
|
1588
|
+
int
|
1589
|
+
xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
1590
|
+
{
|
1591
|
+
xmlParserInputPtr input;
|
1592
|
+
|
1593
|
+
if(ctxt==NULL) {
|
1594
|
+
xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
|
1595
|
+
return(-1);
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
xmlDefaultSAXHandlerInit();
|
1599
|
+
|
1600
|
+
if (ctxt->dict == NULL)
|
1601
|
+
ctxt->dict = xmlDictCreate();
|
1602
|
+
if (ctxt->dict == NULL) {
|
1603
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1604
|
+
return(-1);
|
1605
|
+
}
|
1606
|
+
xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
|
1607
|
+
|
1608
|
+
if (ctxt->sax == NULL)
|
1609
|
+
ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
|
1610
|
+
if (ctxt->sax == NULL) {
|
1611
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1612
|
+
return(-1);
|
1613
|
+
}
|
1614
|
+
else
|
1615
|
+
xmlSAXVersion(ctxt->sax, 2);
|
1616
|
+
|
1617
|
+
ctxt->maxatts = 0;
|
1618
|
+
ctxt->atts = NULL;
|
1619
|
+
/* Allocate the Input stack */
|
1620
|
+
if (ctxt->inputTab == NULL) {
|
1621
|
+
ctxt->inputTab = (xmlParserInputPtr *)
|
1622
|
+
xmlMalloc(5 * sizeof(xmlParserInputPtr));
|
1623
|
+
ctxt->inputMax = 5;
|
1624
|
+
}
|
1625
|
+
if (ctxt->inputTab == NULL) {
|
1626
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1627
|
+
ctxt->inputNr = 0;
|
1628
|
+
ctxt->inputMax = 0;
|
1629
|
+
ctxt->input = NULL;
|
1630
|
+
return(-1);
|
1631
|
+
}
|
1632
|
+
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
|
1633
|
+
xmlFreeInputStream(input);
|
1634
|
+
}
|
1635
|
+
ctxt->inputNr = 0;
|
1636
|
+
ctxt->input = NULL;
|
1637
|
+
|
1638
|
+
ctxt->version = NULL;
|
1639
|
+
ctxt->encoding = NULL;
|
1640
|
+
ctxt->standalone = -1;
|
1641
|
+
ctxt->hasExternalSubset = 0;
|
1642
|
+
ctxt->hasPErefs = 0;
|
1643
|
+
ctxt->html = 0;
|
1644
|
+
ctxt->external = 0;
|
1645
|
+
ctxt->instate = XML_PARSER_START;
|
1646
|
+
ctxt->token = 0;
|
1647
|
+
ctxt->directory = NULL;
|
1648
|
+
|
1649
|
+
/* Allocate the Node stack */
|
1650
|
+
if (ctxt->nodeTab == NULL) {
|
1651
|
+
ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
|
1652
|
+
ctxt->nodeMax = 10;
|
1653
|
+
}
|
1654
|
+
if (ctxt->nodeTab == NULL) {
|
1655
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1656
|
+
ctxt->nodeNr = 0;
|
1657
|
+
ctxt->nodeMax = 0;
|
1658
|
+
ctxt->node = NULL;
|
1659
|
+
ctxt->inputNr = 0;
|
1660
|
+
ctxt->inputMax = 0;
|
1661
|
+
ctxt->input = NULL;
|
1662
|
+
return(-1);
|
1663
|
+
}
|
1664
|
+
ctxt->nodeNr = 0;
|
1665
|
+
ctxt->node = NULL;
|
1666
|
+
|
1667
|
+
/* Allocate the Name stack */
|
1668
|
+
if (ctxt->nameTab == NULL) {
|
1669
|
+
ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
|
1670
|
+
ctxt->nameMax = 10;
|
1671
|
+
}
|
1672
|
+
if (ctxt->nameTab == NULL) {
|
1673
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1674
|
+
ctxt->nodeNr = 0;
|
1675
|
+
ctxt->nodeMax = 0;
|
1676
|
+
ctxt->node = NULL;
|
1677
|
+
ctxt->inputNr = 0;
|
1678
|
+
ctxt->inputMax = 0;
|
1679
|
+
ctxt->input = NULL;
|
1680
|
+
ctxt->nameNr = 0;
|
1681
|
+
ctxt->nameMax = 0;
|
1682
|
+
ctxt->name = NULL;
|
1683
|
+
return(-1);
|
1684
|
+
}
|
1685
|
+
ctxt->nameNr = 0;
|
1686
|
+
ctxt->name = NULL;
|
1687
|
+
|
1688
|
+
/* Allocate the space stack */
|
1689
|
+
if (ctxt->spaceTab == NULL) {
|
1690
|
+
ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
|
1691
|
+
ctxt->spaceMax = 10;
|
1692
|
+
}
|
1693
|
+
if (ctxt->spaceTab == NULL) {
|
1694
|
+
xmlErrMemory(NULL, "cannot initialize parser context\n");
|
1695
|
+
ctxt->nodeNr = 0;
|
1696
|
+
ctxt->nodeMax = 0;
|
1697
|
+
ctxt->node = NULL;
|
1698
|
+
ctxt->inputNr = 0;
|
1699
|
+
ctxt->inputMax = 0;
|
1700
|
+
ctxt->input = NULL;
|
1701
|
+
ctxt->nameNr = 0;
|
1702
|
+
ctxt->nameMax = 0;
|
1703
|
+
ctxt->name = NULL;
|
1704
|
+
ctxt->spaceNr = 0;
|
1705
|
+
ctxt->spaceMax = 0;
|
1706
|
+
ctxt->space = NULL;
|
1707
|
+
return(-1);
|
1708
|
+
}
|
1709
|
+
ctxt->spaceNr = 1;
|
1710
|
+
ctxt->spaceMax = 10;
|
1711
|
+
ctxt->spaceTab[0] = -1;
|
1712
|
+
ctxt->space = &ctxt->spaceTab[0];
|
1713
|
+
ctxt->userData = ctxt;
|
1714
|
+
ctxt->myDoc = NULL;
|
1715
|
+
ctxt->wellFormed = 1;
|
1716
|
+
ctxt->nsWellFormed = 1;
|
1717
|
+
ctxt->valid = 1;
|
1718
|
+
ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
|
1719
|
+
if (ctxt->loadsubset) {
|
1720
|
+
ctxt->options |= XML_PARSE_DTDLOAD;
|
1721
|
+
}
|
1722
|
+
ctxt->validate = xmlDoValidityCheckingDefaultValue;
|
1723
|
+
ctxt->pedantic = xmlPedanticParserDefaultValue;
|
1724
|
+
if (ctxt->pedantic) {
|
1725
|
+
ctxt->options |= XML_PARSE_PEDANTIC;
|
1726
|
+
}
|
1727
|
+
ctxt->linenumbers = xmlLineNumbersDefaultValue;
|
1728
|
+
ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
|
1729
|
+
if (ctxt->keepBlanks == 0) {
|
1730
|
+
ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
|
1731
|
+
ctxt->options |= XML_PARSE_NOBLANKS;
|
1732
|
+
}
|
1733
|
+
|
1734
|
+
ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
|
1735
|
+
ctxt->vctxt.userData = ctxt;
|
1736
|
+
ctxt->vctxt.error = xmlParserValidityError;
|
1737
|
+
ctxt->vctxt.warning = xmlParserValidityWarning;
|
1738
|
+
if (ctxt->validate) {
|
1739
|
+
if (xmlGetWarningsDefaultValue == 0)
|
1740
|
+
ctxt->vctxt.warning = NULL;
|
1741
|
+
else
|
1742
|
+
ctxt->vctxt.warning = xmlParserValidityWarning;
|
1743
|
+
ctxt->vctxt.nodeMax = 0;
|
1744
|
+
ctxt->options |= XML_PARSE_DTDVALID;
|
1745
|
+
}
|
1746
|
+
ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
|
1747
|
+
if (ctxt->replaceEntities) {
|
1748
|
+
ctxt->options |= XML_PARSE_NOENT;
|
1749
|
+
}
|
1750
|
+
ctxt->record_info = 0;
|
1751
|
+
ctxt->checkIndex = 0;
|
1752
|
+
ctxt->inSubset = 0;
|
1753
|
+
ctxt->errNo = XML_ERR_OK;
|
1754
|
+
ctxt->depth = 0;
|
1755
|
+
ctxt->charset = XML_CHAR_ENCODING_UTF8;
|
1756
|
+
ctxt->catalogs = NULL;
|
1757
|
+
ctxt->nbentities = 0;
|
1758
|
+
ctxt->sizeentities = 0;
|
1759
|
+
ctxt->sizeentcopy = 0;
|
1760
|
+
ctxt->input_id = 1;
|
1761
|
+
xmlInitNodeInfoSeq(&ctxt->node_seq);
|
1762
|
+
return(0);
|
1763
|
+
}
|
1764
|
+
|
1765
|
+
/**
|
1766
|
+
* xmlFreeParserCtxt:
|
1767
|
+
* @ctxt: an XML parser context
|
1768
|
+
*
|
1769
|
+
* Free all the memory used by a parser context. However the parsed
|
1770
|
+
* document in ctxt->myDoc is not freed.
|
1771
|
+
*/
|
1772
|
+
|
1773
|
+
void
|
1774
|
+
xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
|
1775
|
+
{
|
1776
|
+
xmlParserInputPtr input;
|
1777
|
+
|
1778
|
+
if (ctxt == NULL) return;
|
1779
|
+
|
1780
|
+
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
|
1781
|
+
xmlFreeInputStream(input);
|
1782
|
+
}
|
1783
|
+
if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
|
1784
|
+
if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
|
1785
|
+
if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
|
1786
|
+
if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
|
1787
|
+
if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
|
1788
|
+
if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
|
1789
|
+
if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
|
1790
|
+
if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
|
1791
|
+
if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
|
1792
|
+
#ifdef LIBXML_SAX1_ENABLED
|
1793
|
+
if ((ctxt->sax != NULL) &&
|
1794
|
+
(ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
|
1795
|
+
#else
|
1796
|
+
if (ctxt->sax != NULL)
|
1797
|
+
#endif /* LIBXML_SAX1_ENABLED */
|
1798
|
+
xmlFree(ctxt->sax);
|
1799
|
+
if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
|
1800
|
+
if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
|
1801
|
+
if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
|
1802
|
+
if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
|
1803
|
+
if (ctxt->nsTab != NULL) xmlFree((char *) ctxt->nsTab);
|
1804
|
+
if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
|
1805
|
+
if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
|
1806
|
+
if (ctxt->attsDefault != NULL)
|
1807
|
+
xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
|
1808
|
+
if (ctxt->attsSpecial != NULL)
|
1809
|
+
xmlHashFree(ctxt->attsSpecial, NULL);
|
1810
|
+
if (ctxt->freeElems != NULL) {
|
1811
|
+
xmlNodePtr cur, next;
|
1812
|
+
|
1813
|
+
cur = ctxt->freeElems;
|
1814
|
+
while (cur != NULL) {
|
1815
|
+
next = cur->next;
|
1816
|
+
xmlFree(cur);
|
1817
|
+
cur = next;
|
1818
|
+
}
|
1819
|
+
}
|
1820
|
+
if (ctxt->freeAttrs != NULL) {
|
1821
|
+
xmlAttrPtr cur, next;
|
1822
|
+
|
1823
|
+
cur = ctxt->freeAttrs;
|
1824
|
+
while (cur != NULL) {
|
1825
|
+
next = cur->next;
|
1826
|
+
xmlFree(cur);
|
1827
|
+
cur = next;
|
1828
|
+
}
|
1829
|
+
}
|
1830
|
+
/*
|
1831
|
+
* cleanup the error strings
|
1832
|
+
*/
|
1833
|
+
if (ctxt->lastError.message != NULL)
|
1834
|
+
xmlFree(ctxt->lastError.message);
|
1835
|
+
if (ctxt->lastError.file != NULL)
|
1836
|
+
xmlFree(ctxt->lastError.file);
|
1837
|
+
if (ctxt->lastError.str1 != NULL)
|
1838
|
+
xmlFree(ctxt->lastError.str1);
|
1839
|
+
if (ctxt->lastError.str2 != NULL)
|
1840
|
+
xmlFree(ctxt->lastError.str2);
|
1841
|
+
if (ctxt->lastError.str3 != NULL)
|
1842
|
+
xmlFree(ctxt->lastError.str3);
|
1843
|
+
|
1844
|
+
#ifdef LIBXML_CATALOG_ENABLED
|
1845
|
+
if (ctxt->catalogs != NULL)
|
1846
|
+
xmlCatalogFreeLocal(ctxt->catalogs);
|
1847
|
+
#endif
|
1848
|
+
xmlFree(ctxt);
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
/**
|
1852
|
+
* xmlNewParserCtxt:
|
1853
|
+
*
|
1854
|
+
* Allocate and initialize a new parser context.
|
1855
|
+
*
|
1856
|
+
* Returns the xmlParserCtxtPtr or NULL
|
1857
|
+
*/
|
1858
|
+
|
1859
|
+
xmlParserCtxtPtr
|
1860
|
+
xmlNewParserCtxt(void)
|
1861
|
+
{
|
1862
|
+
xmlParserCtxtPtr ctxt;
|
1863
|
+
|
1864
|
+
ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
|
1865
|
+
if (ctxt == NULL) {
|
1866
|
+
xmlErrMemory(NULL, "cannot allocate parser context\n");
|
1867
|
+
return(NULL);
|
1868
|
+
}
|
1869
|
+
memset(ctxt, 0, sizeof(xmlParserCtxt));
|
1870
|
+
if (xmlInitParserCtxt(ctxt) < 0) {
|
1871
|
+
xmlFreeParserCtxt(ctxt);
|
1872
|
+
return(NULL);
|
1873
|
+
}
|
1874
|
+
return(ctxt);
|
1875
|
+
}
|
1876
|
+
|
1877
|
+
/************************************************************************
|
1878
|
+
* *
|
1879
|
+
* Handling of node information *
|
1880
|
+
* *
|
1881
|
+
************************************************************************/
|
1882
|
+
|
1883
|
+
/**
|
1884
|
+
* xmlClearParserCtxt:
|
1885
|
+
* @ctxt: an XML parser context
|
1886
|
+
*
|
1887
|
+
* Clear (release owned resources) and reinitialize a parser context
|
1888
|
+
*/
|
1889
|
+
|
1890
|
+
void
|
1891
|
+
xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
|
1892
|
+
{
|
1893
|
+
if (ctxt==NULL)
|
1894
|
+
return;
|
1895
|
+
xmlClearNodeInfoSeq(&ctxt->node_seq);
|
1896
|
+
xmlCtxtReset(ctxt);
|
1897
|
+
}
|
1898
|
+
|
1899
|
+
|
1900
|
+
/**
|
1901
|
+
* xmlParserFindNodeInfo:
|
1902
|
+
* @ctx: an XML parser context
|
1903
|
+
* @node: an XML node within the tree
|
1904
|
+
*
|
1905
|
+
* Find the parser node info struct for a given node
|
1906
|
+
*
|
1907
|
+
* Returns an xmlParserNodeInfo block pointer or NULL
|
1908
|
+
*/
|
1909
|
+
const xmlParserNodeInfo *
|
1910
|
+
xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
|
1911
|
+
{
|
1912
|
+
unsigned long pos;
|
1913
|
+
|
1914
|
+
if ((ctx == NULL) || (node == NULL))
|
1915
|
+
return (NULL);
|
1916
|
+
/* Find position where node should be at */
|
1917
|
+
pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
|
1918
|
+
if (pos < ctx->node_seq.length
|
1919
|
+
&& ctx->node_seq.buffer[pos].node == node)
|
1920
|
+
return &ctx->node_seq.buffer[pos];
|
1921
|
+
else
|
1922
|
+
return NULL;
|
1923
|
+
}
|
1924
|
+
|
1925
|
+
|
1926
|
+
/**
|
1927
|
+
* xmlInitNodeInfoSeq:
|
1928
|
+
* @seq: a node info sequence pointer
|
1929
|
+
*
|
1930
|
+
* -- Initialize (set to initial state) node info sequence
|
1931
|
+
*/
|
1932
|
+
void
|
1933
|
+
xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
|
1934
|
+
{
|
1935
|
+
if (seq == NULL)
|
1936
|
+
return;
|
1937
|
+
seq->length = 0;
|
1938
|
+
seq->maximum = 0;
|
1939
|
+
seq->buffer = NULL;
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
/**
|
1943
|
+
* xmlClearNodeInfoSeq:
|
1944
|
+
* @seq: a node info sequence pointer
|
1945
|
+
*
|
1946
|
+
* -- Clear (release memory and reinitialize) node
|
1947
|
+
* info sequence
|
1948
|
+
*/
|
1949
|
+
void
|
1950
|
+
xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
|
1951
|
+
{
|
1952
|
+
if (seq == NULL)
|
1953
|
+
return;
|
1954
|
+
if (seq->buffer != NULL)
|
1955
|
+
xmlFree(seq->buffer);
|
1956
|
+
xmlInitNodeInfoSeq(seq);
|
1957
|
+
}
|
1958
|
+
|
1959
|
+
/**
|
1960
|
+
* xmlParserFindNodeInfoIndex:
|
1961
|
+
* @seq: a node info sequence pointer
|
1962
|
+
* @node: an XML node pointer
|
1963
|
+
*
|
1964
|
+
*
|
1965
|
+
* xmlParserFindNodeInfoIndex : Find the index that the info record for
|
1966
|
+
* the given node is or should be at in a sorted sequence
|
1967
|
+
*
|
1968
|
+
* Returns a long indicating the position of the record
|
1969
|
+
*/
|
1970
|
+
unsigned long
|
1971
|
+
xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
|
1972
|
+
const xmlNodePtr node)
|
1973
|
+
{
|
1974
|
+
unsigned long upper, lower, middle;
|
1975
|
+
int found = 0;
|
1976
|
+
|
1977
|
+
if ((seq == NULL) || (node == NULL))
|
1978
|
+
return ((unsigned long) -1);
|
1979
|
+
|
1980
|
+
/* Do a binary search for the key */
|
1981
|
+
lower = 1;
|
1982
|
+
upper = seq->length;
|
1983
|
+
middle = 0;
|
1984
|
+
while (lower <= upper && !found) {
|
1985
|
+
middle = lower + (upper - lower) / 2;
|
1986
|
+
if (node == seq->buffer[middle - 1].node)
|
1987
|
+
found = 1;
|
1988
|
+
else if (node < seq->buffer[middle - 1].node)
|
1989
|
+
upper = middle - 1;
|
1990
|
+
else
|
1991
|
+
lower = middle + 1;
|
1992
|
+
}
|
1993
|
+
|
1994
|
+
/* Return position */
|
1995
|
+
if (middle == 0 || seq->buffer[middle - 1].node < node)
|
1996
|
+
return middle;
|
1997
|
+
else
|
1998
|
+
return middle - 1;
|
1999
|
+
}
|
2000
|
+
|
2001
|
+
|
2002
|
+
/**
|
2003
|
+
* xmlParserAddNodeInfo:
|
2004
|
+
* @ctxt: an XML parser context
|
2005
|
+
* @info: a node info sequence pointer
|
2006
|
+
*
|
2007
|
+
* Insert node info record into the sorted sequence
|
2008
|
+
*/
|
2009
|
+
void
|
2010
|
+
xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
|
2011
|
+
const xmlParserNodeInfoPtr info)
|
2012
|
+
{
|
2013
|
+
unsigned long pos;
|
2014
|
+
|
2015
|
+
if ((ctxt == NULL) || (info == NULL)) return;
|
2016
|
+
|
2017
|
+
/* Find pos and check to see if node is already in the sequence */
|
2018
|
+
pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
|
2019
|
+
info->node);
|
2020
|
+
|
2021
|
+
if ((pos < ctxt->node_seq.length) &&
|
2022
|
+
(ctxt->node_seq.buffer != NULL) &&
|
2023
|
+
(ctxt->node_seq.buffer[pos].node == info->node)) {
|
2024
|
+
ctxt->node_seq.buffer[pos] = *info;
|
2025
|
+
}
|
2026
|
+
|
2027
|
+
/* Otherwise, we need to add new node to buffer */
|
2028
|
+
else {
|
2029
|
+
if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
|
2030
|
+
(ctxt->node_seq.buffer == NULL)) {
|
2031
|
+
xmlParserNodeInfo *tmp_buffer;
|
2032
|
+
unsigned int byte_size;
|
2033
|
+
|
2034
|
+
if (ctxt->node_seq.maximum == 0)
|
2035
|
+
ctxt->node_seq.maximum = 2;
|
2036
|
+
byte_size = (sizeof(*ctxt->node_seq.buffer) *
|
2037
|
+
(2 * ctxt->node_seq.maximum));
|
2038
|
+
|
2039
|
+
if (ctxt->node_seq.buffer == NULL)
|
2040
|
+
tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
|
2041
|
+
else
|
2042
|
+
tmp_buffer =
|
2043
|
+
(xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
|
2044
|
+
byte_size);
|
2045
|
+
|
2046
|
+
if (tmp_buffer == NULL) {
|
2047
|
+
xmlErrMemory(ctxt, "failed to allocate buffer\n");
|
2048
|
+
return;
|
2049
|
+
}
|
2050
|
+
ctxt->node_seq.buffer = tmp_buffer;
|
2051
|
+
ctxt->node_seq.maximum *= 2;
|
2052
|
+
}
|
2053
|
+
|
2054
|
+
/* If position is not at end, move elements out of the way */
|
2055
|
+
if (pos != ctxt->node_seq.length) {
|
2056
|
+
unsigned long i;
|
2057
|
+
|
2058
|
+
for (i = ctxt->node_seq.length; i > pos; i--)
|
2059
|
+
ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
|
2060
|
+
}
|
2061
|
+
|
2062
|
+
/* Copy element and increase length */
|
2063
|
+
ctxt->node_seq.buffer[pos] = *info;
|
2064
|
+
ctxt->node_seq.length++;
|
2065
|
+
}
|
2066
|
+
}
|
2067
|
+
|
2068
|
+
/************************************************************************
|
2069
|
+
* *
|
2070
|
+
* Defaults settings *
|
2071
|
+
* *
|
2072
|
+
************************************************************************/
|
2073
|
+
/**
|
2074
|
+
* xmlPedanticParserDefault:
|
2075
|
+
* @val: int 0 or 1
|
2076
|
+
*
|
2077
|
+
* Set and return the previous value for enabling pedantic warnings.
|
2078
|
+
*
|
2079
|
+
* Returns the last value for 0 for no substitution, 1 for substitution.
|
2080
|
+
*/
|
2081
|
+
|
2082
|
+
int
|
2083
|
+
xmlPedanticParserDefault(int val) {
|
2084
|
+
int old = xmlPedanticParserDefaultValue;
|
2085
|
+
|
2086
|
+
xmlPedanticParserDefaultValue = val;
|
2087
|
+
return(old);
|
2088
|
+
}
|
2089
|
+
|
2090
|
+
/**
|
2091
|
+
* xmlLineNumbersDefault:
|
2092
|
+
* @val: int 0 or 1
|
2093
|
+
*
|
2094
|
+
* Set and return the previous value for enabling line numbers in elements
|
2095
|
+
* contents. This may break on old application and is turned off by default.
|
2096
|
+
*
|
2097
|
+
* Returns the last value for 0 for no substitution, 1 for substitution.
|
2098
|
+
*/
|
2099
|
+
|
2100
|
+
int
|
2101
|
+
xmlLineNumbersDefault(int val) {
|
2102
|
+
int old = xmlLineNumbersDefaultValue;
|
2103
|
+
|
2104
|
+
xmlLineNumbersDefaultValue = val;
|
2105
|
+
return(old);
|
2106
|
+
}
|
2107
|
+
|
2108
|
+
/**
|
2109
|
+
* xmlSubstituteEntitiesDefault:
|
2110
|
+
* @val: int 0 or 1
|
2111
|
+
*
|
2112
|
+
* Set and return the previous value for default entity support.
|
2113
|
+
* Initially the parser always keep entity references instead of substituting
|
2114
|
+
* entity values in the output. This function has to be used to change the
|
2115
|
+
* default parser behavior
|
2116
|
+
* SAX::substituteEntities() has to be used for changing that on a file by
|
2117
|
+
* file basis.
|
2118
|
+
*
|
2119
|
+
* Returns the last value for 0 for no substitution, 1 for substitution.
|
2120
|
+
*/
|
2121
|
+
|
2122
|
+
int
|
2123
|
+
xmlSubstituteEntitiesDefault(int val) {
|
2124
|
+
int old = xmlSubstituteEntitiesDefaultValue;
|
2125
|
+
|
2126
|
+
xmlSubstituteEntitiesDefaultValue = val;
|
2127
|
+
return(old);
|
2128
|
+
}
|
2129
|
+
|
2130
|
+
/**
|
2131
|
+
* xmlKeepBlanksDefault:
|
2132
|
+
* @val: int 0 or 1
|
2133
|
+
*
|
2134
|
+
* Set and return the previous value for default blanks text nodes support.
|
2135
|
+
* The 1.x version of the parser used an heuristic to try to detect
|
2136
|
+
* ignorable white spaces. As a result the SAX callback was generating
|
2137
|
+
* xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
|
2138
|
+
* using the DOM output text nodes containing those blanks were not generated.
|
2139
|
+
* The 2.x and later version will switch to the XML standard way and
|
2140
|
+
* ignorableWhitespace() are only generated when running the parser in
|
2141
|
+
* validating mode and when the current element doesn't allow CDATA or
|
2142
|
+
* mixed content.
|
2143
|
+
* This function is provided as a way to force the standard behavior
|
2144
|
+
* on 1.X libs and to switch back to the old mode for compatibility when
|
2145
|
+
* running 1.X client code on 2.X . Upgrade of 1.X code should be done
|
2146
|
+
* by using xmlIsBlankNode() commodity function to detect the "empty"
|
2147
|
+
* nodes generated.
|
2148
|
+
* This value also affect autogeneration of indentation when saving code
|
2149
|
+
* if blanks sections are kept, indentation is not generated.
|
2150
|
+
*
|
2151
|
+
* Returns the last value for 0 for no substitution, 1 for substitution.
|
2152
|
+
*/
|
2153
|
+
|
2154
|
+
int
|
2155
|
+
xmlKeepBlanksDefault(int val) {
|
2156
|
+
int old = xmlKeepBlanksDefaultValue;
|
2157
|
+
|
2158
|
+
xmlKeepBlanksDefaultValue = val;
|
2159
|
+
if (!val) xmlIndentTreeOutput = 1;
|
2160
|
+
return(old);
|
2161
|
+
}
|
2162
|
+
|
2163
|
+
#define bottom_parserInternals
|
2164
|
+
#include "elfgcchack.h"
|