Line data Source code
1 : /**
2 : * XML Security Library (http://www.aleksey.com/xmlsec).
3 : *
4 : * XML Parser transform and utility functions.
5 : *
6 : * This is free software; see Copyright file in the source
7 : * distribution for preciese wording.
8 : *
9 : * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
10 : */
11 : #include "globals.h"
12 :
13 : #include <stdlib.h>
14 : #include <string.h>
15 :
16 : #include <libxml/tree.h>
17 : #include <libxml/parser.h>
18 : #include <libxml/parserInternals.h>
19 :
20 : #include <xmlsec/xmlsec.h>
21 : #include <xmlsec/xmltree.h>
22 : #include <xmlsec/keys.h>
23 : #include <xmlsec/transforms.h>
24 : #include <xmlsec/parser.h>
25 : #include <xmlsec/errors.h>
26 :
27 : /**************************************************************************
28 : *
29 : * Internal parser
30 : *
31 : *****************************************************************************/
32 : typedef struct _xmlSecParserCtx xmlSecParserCtx,
33 : *xmlSecParserCtxPtr;
34 : struct _xmlSecParserCtx {
35 : xmlParserCtxtPtr parserCtx;
36 : };
37 :
38 : /**************************************************************************
39 : *
40 : * XML Parser transform
41 : *
42 : * xmlSecParserCtx is located after xmlSecTransform
43 : *
44 : ***************************************************************************/
45 : #define xmlSecParserSize \
46 : (sizeof(xmlSecTransform) + sizeof(xmlSecParserCtx))
47 : #define xmlSecParserGetCtx(transform) \
48 : ((xmlSecTransformCheckSize((transform), xmlSecParserSize)) ? \
49 : ((xmlSecParserCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform))) : \
50 : (xmlSecParserCtxPtr)NULL)
51 :
52 : static int xmlSecParserInitialize (xmlSecTransformPtr transform);
53 : static void xmlSecParserFinalize (xmlSecTransformPtr transform);
54 : static int xmlSecParserPushBin (xmlSecTransformPtr transform,
55 : const xmlSecByte* data,
56 : xmlSecSize dataSize,
57 : int final,
58 : xmlSecTransformCtxPtr transformCtx);
59 : static int xmlSecParserPopXml (xmlSecTransformPtr transform,
60 : xmlSecNodeSetPtr* nodes,
61 : xmlSecTransformCtxPtr transformCtx);
62 :
63 : static xmlSecTransformKlass xmlSecParserKlass = {
64 : /* klass/object sizes */
65 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
66 : xmlSecParserSize, /* xmlSecSize objSize */
67 :
68 : BAD_CAST "xml-parser", /* const xmlChar* name; */
69 : NULL, /* const xmlChar* href; */
70 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
71 :
72 : xmlSecParserInitialize, /* xmlSecTransformInitializeMethod initialize; */
73 : xmlSecParserFinalize, /* xmlSecTransformFinalizeMethod finalize; */
74 : NULL, /* xmlSecTransformNodeReadMethod readNode; */
75 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
76 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
77 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
78 : NULL, /* xmlSecTransformValidateMethod validate; */
79 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
80 : xmlSecParserPushBin, /* xmlSecTransformPushBinMethod pushBin; */
81 : NULL, /* xmlSecTransformPopBinMethod popBin; */
82 : NULL, /* xmlSecTransformPushXmlMethod pushXml; */
83 : xmlSecParserPopXml, /* xmlSecTransformPopXmlMethod popXml; */
84 : NULL, /* xmlSecTransformExecuteMethod execute; */
85 :
86 : NULL, /* void* reserved0; */
87 : NULL, /* void* reserved1; */
88 : };
89 :
90 : /**
91 : * xmlSecTransformXmlParserGetKlass:
92 : *
93 : * The XML parser transform.
94 : *
95 : * Returns: XML parser transform klass.
96 : */
97 : xmlSecTransformId
98 0 : xmlSecTransformXmlParserGetKlass(void) {
99 0 : return(&xmlSecParserKlass);
100 : }
101 :
102 : static int
103 0 : xmlSecParserInitialize(xmlSecTransformPtr transform) {
104 : xmlSecParserCtxPtr ctx;
105 :
106 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXmlParserId), -1);
107 0 : xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecParserSize), -1);
108 :
109 0 : ctx = xmlSecParserGetCtx(transform);
110 0 : xmlSecAssert2(ctx != NULL, -1);
111 :
112 : /* initialize context */
113 0 : memset(ctx, 0, sizeof(xmlSecParserCtx));
114 0 : return(0);
115 : }
116 :
117 : static void
118 0 : xmlSecParserFinalize(xmlSecTransformPtr transform) {
119 : xmlSecParserCtxPtr ctx;
120 :
121 0 : xmlSecAssert(xmlSecTransformCheckId(transform, xmlSecTransformXmlParserId));
122 0 : xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecParserSize));
123 :
124 0 : ctx = xmlSecParserGetCtx(transform);
125 0 : xmlSecAssert(ctx != NULL);
126 :
127 0 : if(ctx->parserCtx != NULL) {
128 0 : xmlFreeParserCtxt(ctx->parserCtx);
129 : }
130 0 : memset(ctx, 0, sizeof(xmlSecParserCtx));
131 : }
132 :
133 : static int
134 0 : xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
135 : xmlSecSize dataSize, int final, xmlSecTransformCtxPtr transformCtx) {
136 : xmlSecParserCtxPtr ctx;
137 : int ret;
138 :
139 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXmlParserId), -1);
140 0 : xmlSecAssert2(transformCtx != NULL, -1);
141 :
142 0 : ctx = xmlSecParserGetCtx(transform);
143 0 : xmlSecAssert2(ctx != NULL, -1);
144 :
145 : /* check/update current transform status */
146 0 : if(transform->status == xmlSecTransformStatusNone) {
147 0 : xmlSecAssert2(ctx->parserCtx == NULL, -1);
148 :
149 0 : ctx->parserCtx = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
150 0 : if(ctx->parserCtx == NULL) {
151 0 : xmlSecError(XMLSEC_ERRORS_HERE,
152 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
153 : "xmlCreatePushParserCtxt",
154 : XMLSEC_ERRORS_R_XML_FAILED,
155 : XMLSEC_ERRORS_NO_MESSAGE);
156 0 : return(-1);
157 : }
158 :
159 : /* required for c14n! */
160 0 : ctx->parserCtx->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
161 0 : ctx->parserCtx->replaceEntities = 1;
162 :
163 0 : transform->status = xmlSecTransformStatusWorking;
164 0 : } else if(transform->status == xmlSecTransformStatusFinished) {
165 0 : return(0);
166 0 : } else if(transform->status != xmlSecTransformStatusWorking) {
167 0 : xmlSecError(XMLSEC_ERRORS_HERE,
168 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
169 : NULL,
170 : XMLSEC_ERRORS_R_INVALID_STATUS,
171 0 : "status=%d", transform->status);
172 0 : return(-1);
173 : }
174 0 : xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
175 0 : xmlSecAssert2(ctx->parserCtx != NULL, -1);
176 :
177 : /* push data to the input buffer */
178 0 : if((data != NULL) && (dataSize > 0)) {
179 0 : ret = xmlParseChunk(ctx->parserCtx, (const char*)data, dataSize, 0);
180 0 : if(ret != 0) {
181 0 : xmlSecError(XMLSEC_ERRORS_HERE,
182 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
183 : "xmlParseChunk",
184 : XMLSEC_ERRORS_R_XML_FAILED,
185 : "size=%d", dataSize);
186 0 : return(-1);
187 : }
188 : }
189 :
190 : /* finish parsing and push to next in the chain */
191 0 : if(final != 0) {
192 0 : ret = xmlParseChunk(ctx->parserCtx, NULL, 0, 1);
193 0 : if((ret != 0) || (ctx->parserCtx->myDoc == NULL)) {
194 0 : xmlSecError(XMLSEC_ERRORS_HERE,
195 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
196 : "xmlParseChunk",
197 : XMLSEC_ERRORS_R_XML_FAILED,
198 : XMLSEC_ERRORS_NO_MESSAGE);
199 0 : return(-1);
200 : }
201 :
202 : /* todo: check that document is well formed? */
203 0 : transform->outNodes = xmlSecNodeSetCreate(ctx->parserCtx->myDoc,
204 : NULL, xmlSecNodeSetTree);
205 0 : if(transform->outNodes == NULL) {
206 0 : xmlSecError(XMLSEC_ERRORS_HERE,
207 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
208 : "xmlSecNodeSetCreate",
209 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
210 : XMLSEC_ERRORS_NO_MESSAGE);
211 0 : xmlFreeDoc(ctx->parserCtx->myDoc);
212 0 : ctx->parserCtx->myDoc = NULL;
213 0 : return(-1);
214 : }
215 0 : xmlSecNodeSetDocDestroy(transform->outNodes); /* this node set "owns" the doc pointer */
216 0 : ctx->parserCtx->myDoc = NULL;
217 :
218 : /* push result to the next transform (if exist) */
219 0 : if(transform->next != NULL) {
220 0 : ret = xmlSecTransformPushXml(transform->next, transform->outNodes, transformCtx);
221 0 : if(ret < 0) {
222 0 : xmlSecError(XMLSEC_ERRORS_HERE,
223 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
224 : "xmlSecTransformPushXml",
225 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
226 : XMLSEC_ERRORS_NO_MESSAGE);
227 0 : return(-1);
228 : }
229 : }
230 :
231 0 : transform->status = xmlSecTransformStatusFinished;
232 : }
233 :
234 0 : return(0);
235 : }
236 :
237 : static int
238 0 : xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
239 : xmlSecTransformCtxPtr transformCtx) {
240 : xmlSecParserCtxPtr ctx;
241 : xmlParserInputBufferPtr buf;
242 : xmlParserInputPtr input;
243 : xmlParserCtxtPtr ctxt;
244 : xmlDocPtr doc;
245 : int ret;
246 :
247 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXmlParserId), -1);
248 0 : xmlSecAssert2(nodes != NULL, -1);
249 0 : xmlSecAssert2(transformCtx != NULL, -1);
250 :
251 0 : ctx = xmlSecParserGetCtx(transform);
252 0 : xmlSecAssert2(ctx != NULL, -1);
253 :
254 : /* check/update current transform status */
255 0 : switch(transform->status) {
256 : case xmlSecTransformStatusNone:
257 0 : transform->status = xmlSecTransformStatusWorking;
258 0 : break;
259 : case xmlSecTransformStatusWorking:
260 : /* just do nothing */
261 0 : break;
262 : case xmlSecTransformStatusFinished:
263 0 : (*nodes) = NULL;
264 0 : return(0);
265 : default:
266 0 : xmlSecError(XMLSEC_ERRORS_HERE,
267 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
268 : NULL,
269 : XMLSEC_ERRORS_R_INVALID_STATUS,
270 0 : "status=%d", transform->status);
271 0 : return(-1);
272 : }
273 0 : xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
274 :
275 : /* prepare parser context */
276 0 : if(transform->prev == NULL) {
277 0 : xmlSecError(XMLSEC_ERRORS_HERE,
278 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
279 : NULL,
280 : XMLSEC_ERRORS_R_INVALID_TRANSFORM,
281 : "prev transform is null");
282 0 : return(-1);
283 : }
284 :
285 0 : buf = xmlSecTransformCreateInputBuffer(transform->prev, transformCtx);
286 0 : if(buf == NULL) {
287 0 : xmlSecError(XMLSEC_ERRORS_HERE,
288 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
289 : "xmlSecTransformCreateInputBuffer",
290 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
291 : XMLSEC_ERRORS_NO_MESSAGE);
292 0 : return(-1);
293 : }
294 :
295 0 : ctxt = xmlNewParserCtxt();
296 0 : if (ctxt == NULL) {
297 0 : xmlSecError(XMLSEC_ERRORS_HERE,
298 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
299 : "xmlNewParserCtxt",
300 : XMLSEC_ERRORS_R_XML_FAILED,
301 : XMLSEC_ERRORS_NO_MESSAGE);
302 0 : xmlFreeParserInputBuffer(buf);
303 0 : return(-1);
304 : }
305 :
306 0 : input = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
307 0 : if(input == NULL) {
308 0 : xmlSecError(XMLSEC_ERRORS_HERE,
309 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
310 : "xmlNewParserCtxt",
311 : XMLSEC_ERRORS_R_XML_FAILED,
312 : XMLSEC_ERRORS_NO_MESSAGE);
313 0 : xmlFreeParserCtxt(ctxt);
314 0 : xmlFreeParserInputBuffer(buf);
315 0 : return(-1);
316 : }
317 :
318 0 : ret = inputPush(ctxt, input);
319 0 : if(input == NULL) {
320 0 : xmlSecError(XMLSEC_ERRORS_HERE,
321 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
322 : "inputPush",
323 : XMLSEC_ERRORS_R_XML_FAILED,
324 : XMLSEC_ERRORS_NO_MESSAGE);
325 0 : xmlFreeInputStream(input);
326 0 : xmlFreeParserCtxt(ctxt);
327 0 : return(-1);
328 : }
329 :
330 : /* required for c14n! */
331 0 : ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
332 0 : ctxt->replaceEntities = 1;
333 :
334 : /* finaly do the parsing */
335 0 : ret = xmlParseDocument(ctxt);
336 0 : if(ret < 0) {
337 0 : xmlSecError(XMLSEC_ERRORS_HERE,
338 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
339 : "xmlParseDocument",
340 : XMLSEC_ERRORS_R_XML_FAILED,
341 : XMLSEC_ERRORS_NO_MESSAGE);
342 0 : if(ctxt->myDoc != NULL) {
343 0 : xmlFreeDoc(ctxt->myDoc);
344 0 : ctxt->myDoc = NULL;
345 : }
346 0 : xmlFreeParserCtxt(ctxt);
347 0 : return(-1);
348 : }
349 :
350 : /* remember the result and free parsing context */
351 0 : doc = ctxt->myDoc;
352 0 : ctxt->myDoc = NULL;
353 0 : xmlFreeParserCtxt(ctxt);
354 :
355 : /* return result to the caller */
356 0 : (*nodes) = xmlSecNodeSetCreate(doc, NULL, xmlSecNodeSetTree);
357 0 : if((*nodes) == NULL) {
358 0 : xmlSecError(XMLSEC_ERRORS_HERE,
359 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
360 : "xmlSecNodeSetCreate",
361 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
362 : XMLSEC_ERRORS_NO_MESSAGE);
363 0 : xmlFreeDoc(doc);
364 0 : return(-1);
365 : }
366 0 : xmlSecNodeSetDocDestroy((*nodes)); /* this node set "owns" the doc pointer */
367 0 : transform->status = xmlSecTransformStatusFinished;
368 0 : return(0);
369 : }
370 :
371 : /**************************************************************************
372 : *
373 : * XML Parser functions
374 : *
375 : *************************************************************************/
376 : typedef struct _xmlSecExtMemoryParserCtx {
377 : const xmlSecByte *prefix;
378 : xmlSecSize prefixSize;
379 : const xmlSecByte *buffer;
380 : xmlSecSize bufferSize;
381 : const xmlSecByte *postfix;
382 : xmlSecSize postfixSize;
383 : } xmlSecExtMemoryParserCtx, *xmlSecExtMemoryParserCtxPtr;
384 :
385 : /**
386 : * xmlSecParseFile:
387 : * @filename: the filename.
388 : *
389 : * Loads XML Doc from file @filename. We need a special version because of
390 : * c14n issue. The code is copied from xmlSAXParseFileWithData() function.
391 : *
392 : * Returns: pointer to the loaded XML document or NULL if an error occurs.
393 : */
394 : xmlDocPtr
395 0 : xmlSecParseFile(const char *filename) {
396 : xmlDocPtr ret;
397 : xmlParserCtxtPtr ctxt;
398 0 : char *directory = NULL;
399 :
400 0 : xmlSecAssert2(filename != NULL, NULL);
401 :
402 0 : xmlInitParser();
403 0 : ctxt = xmlCreateFileParserCtxt(filename);
404 0 : if (ctxt == NULL) {
405 0 : return(NULL);
406 : }
407 :
408 : /* todo: set directories from current doc? */
409 0 : if ((ctxt->directory == NULL) && (directory == NULL))
410 0 : directory = xmlParserGetDirectory(filename);
411 0 : if ((ctxt->directory == NULL) && (directory != NULL))
412 0 : ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
413 :
414 : /* required for c14n! */
415 0 : ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
416 0 : ctxt->replaceEntities = 1;
417 :
418 0 : xmlParseDocument(ctxt);
419 :
420 0 : if(ctxt->wellFormed) {
421 0 : ret = ctxt->myDoc;
422 : } else {
423 0 : ret = NULL;
424 0 : xmlFreeDoc(ctxt->myDoc);
425 0 : ctxt->myDoc = NULL;
426 : }
427 0 : xmlFreeParserCtxt(ctxt);
428 0 : return(ret);
429 :
430 : }
431 :
432 : /**
433 : * xmlSecParseMemoryExt:
434 : * @prefix: the first part of the input.
435 : * @prefixSize: the size of the first part of the input.
436 : * @buffer: the second part of the input.
437 : * @bufferSize: the size of the second part of the input.
438 : * @postfix: the third part of the input.
439 : * @postfixSize: the size of the third part of the input.
440 : *
441 : * Loads XML Doc from 3 chunks of memory: @prefix, @buffer and @postfix.
442 : *
443 : * Returns: pointer to the loaded XML document or NULL if an error occurs.
444 : */
445 : xmlDocPtr
446 0 : xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
447 : const xmlSecByte *buffer, xmlSecSize bufferSize,
448 : const xmlSecByte *postfix, xmlSecSize postfixSize) {
449 0 : xmlParserCtxtPtr ctxt = NULL;
450 0 : xmlDocPtr doc = NULL;
451 : int ret;
452 :
453 : /* create context */
454 0 : ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
455 0 : if(ctxt == NULL) {
456 0 : xmlSecError(XMLSEC_ERRORS_HERE,
457 : NULL,
458 : "xmlCreatePushParserCtxt",
459 : XMLSEC_ERRORS_R_XML_FAILED,
460 : XMLSEC_ERRORS_NO_MESSAGE);
461 0 : goto done;
462 : }
463 :
464 : /* required for c14n! */
465 0 : ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
466 0 : ctxt->replaceEntities = 1;
467 :
468 : /* prefix */
469 0 : if((prefix != NULL) && (prefixSize > 0)) {
470 0 : ret = xmlParseChunk(ctxt, (const char*)prefix, prefixSize, 0);
471 0 : if(ret != 0) {
472 0 : xmlSecError(XMLSEC_ERRORS_HERE,
473 : NULL,
474 : "xmlParseChunk",
475 : XMLSEC_ERRORS_R_XML_FAILED,
476 : "prefixSize=%d", prefixSize);
477 0 : goto done;
478 : }
479 : }
480 :
481 : /* buffer */
482 0 : if((buffer != NULL) && (bufferSize > 0)) {
483 0 : ret = xmlParseChunk(ctxt, (const char*)buffer, bufferSize, 0);
484 0 : if(ret != 0) {
485 0 : xmlSecError(XMLSEC_ERRORS_HERE,
486 : NULL,
487 : "xmlParseChunk",
488 : XMLSEC_ERRORS_R_XML_FAILED,
489 : "bufferSize=%d", bufferSize);
490 0 : goto done;
491 : }
492 : }
493 :
494 : /* postfix */
495 0 : if((postfix != NULL) && (postfixSize > 0)) {
496 0 : ret = xmlParseChunk(ctxt, (const char*)postfix, postfixSize, 0);
497 0 : if(ret != 0) {
498 0 : xmlSecError(XMLSEC_ERRORS_HERE,
499 : NULL,
500 : "xmlParseChunk",
501 : XMLSEC_ERRORS_R_XML_FAILED,
502 : "postfixSize=%d", postfixSize);
503 0 : goto done;
504 : }
505 : }
506 :
507 : /* finishing */
508 0 : ret = xmlParseChunk(ctxt, NULL, 0, 1);
509 0 : if((ret != 0) || (ctxt->myDoc == NULL)) {
510 0 : xmlSecError(XMLSEC_ERRORS_HERE,
511 : NULL,
512 : "xmlParseChunk",
513 : XMLSEC_ERRORS_R_XML_FAILED,
514 : XMLSEC_ERRORS_NO_MESSAGE);
515 0 : goto done;
516 : }
517 0 : doc = ctxt->myDoc;
518 :
519 : done:
520 0 : if(ctxt != NULL) {
521 0 : xmlFreeParserCtxt(ctxt);
522 : }
523 0 : return(doc);
524 : }
525 :
526 :
527 : /**
528 : * xmlSecParseMemory:
529 : * @buffer: the input buffer.
530 : * @size: the input buffer size.
531 : * @recovery: the flag.
532 : *
533 : * Loads XML Doc from memory. We need a special version because of
534 : * c14n issue. The code is copied from xmlSAXParseMemory() function.
535 : *
536 : * Returns: pointer to the loaded XML document or NULL if an error occurs.
537 : */
538 : xmlDocPtr
539 0 : xmlSecParseMemory(const xmlSecByte *buffer, xmlSecSize size, int recovery) {
540 : xmlDocPtr ret;
541 : xmlParserCtxtPtr ctxt;
542 :
543 0 : xmlSecAssert2(buffer != NULL, NULL);
544 :
545 0 : ctxt = xmlCreateMemoryParserCtxt((char*)buffer, size);
546 0 : if (ctxt == NULL) {
547 0 : xmlSecError(XMLSEC_ERRORS_HERE,
548 : NULL,
549 : "xmlCreateMemoryParserCtxt",
550 : XMLSEC_ERRORS_R_XML_FAILED,
551 : XMLSEC_ERRORS_NO_MESSAGE);
552 0 : return(NULL);
553 : }
554 :
555 : /* required for c14n! */
556 0 : ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
557 0 : ctxt->replaceEntities = 1;
558 :
559 0 : xmlParseDocument(ctxt);
560 :
561 0 : if((ctxt->wellFormed) || recovery) {
562 0 : ret = ctxt->myDoc;
563 : } else {
564 0 : ret = NULL;
565 0 : xmlFreeDoc(ctxt->myDoc);
566 0 : ctxt->myDoc = NULL;
567 : }
568 0 : xmlFreeParserCtxt(ctxt);
569 0 : return(ret);
570 : }
571 :
|