Apache HTTPD
xmlwf.c
Go to the documentation of this file.
1/*
2 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000 Clark Cooper <[email protected]>
11 Copyright (c) 2001-2003 Fred L. Drake, Jr. <[email protected]>
12 Copyright (c) 2004-2009 Karl Waclawek <[email protected]>
13 Copyright (c) 2005-2007 Steven Solie <[email protected]>
14 Copyright (c) 2016-2023 Sebastian Pipping <[email protected]>
15 Copyright (c) 2017 Rhodri James <[email protected]>
16 Copyright (c) 2019 David Loffredo <[email protected]>
17 Copyright (c) 2020 Joe Orton <[email protected]>
18 Copyright (c) 2020 Kleber TarcĂ­sio <[email protected]>
19 Copyright (c) 2021 Tim Bray <[email protected]>
20 Copyright (c) 2022 Martin Ettl <[email protected]>
21 Copyright (c) 2022 Sean McBride <[email protected]>
22 Licensed under the MIT license:
23
24 Permission is hereby granted, free of charge, to any person obtaining
25 a copy of this software and associated documentation files (the
26 "Software"), to deal in the Software without restriction, including
27 without limitation the rights to use, copy, modify, merge, publish,
28 distribute, sublicense, and/or sell copies of the Software, and to permit
29 persons to whom the Software is furnished to do so, subject to the
30 following conditions:
31
32 The above copyright notice and this permission notice shall be included
33 in all copies or substantial portions of the Software.
34
35 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
38 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
39 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
40 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
41 USE OR OTHER DEALINGS IN THE SOFTWARE.
42*/
43
44#include "expat_config.h"
45
46#include <assert.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <stddef.h>
50#include <string.h>
51#include <math.h> /* for isnan */
52#include <errno.h>
53
54#include "expat.h"
55#include "codepage.h"
56#include "internal.h" /* for UNUSED_P only */
57#include "xmlfile.h"
58#include "xmltchar.h"
59
60#ifdef _MSC_VER
61# include <crtdbg.h>
62#endif
63
64#ifdef XML_UNICODE
65# include <wchar.h>
66#endif
67
75
76/* Structures for handler user data */
83
89
90/* This ensures proper sorting. */
91
92#define NSSEP T('\001')
93
94static void XMLCALL
95characterData(void *userData, const XML_Char *s, int len) {
96 FILE *fp = ((XmlwfUserData *)userData)->fp;
97 for (; len > 0; --len, ++s) {
98 switch (*s) {
99 case T('&'):
100 fputts(T("&amp;"), fp);
101 break;
102 case T('<'):
103 fputts(T("&lt;"), fp);
104 break;
105 case T('>'):
106 fputts(T("&gt;"), fp);
107 break;
108#ifdef W3C14N
109 case 13:
110 fputts(T("&#xD;"), fp);
111 break;
112#else
113 case T('"'):
114 fputts(T("&quot;"), fp);
115 break;
116 case 9:
117 case 10:
118 case 13:
119 ftprintf(fp, T("&#%d;"), *s);
120 break;
121#endif
122 default:
123 puttc(*s, fp);
124 break;
125 }
126 }
127}
128
129static void
131 puttc(T('='), fp);
132 puttc(T('"'), fp);
133 assert(s);
134 for (;;) {
135 switch (*s) {
136 case 0:
137 case NSSEP:
138 puttc(T('"'), fp);
139 return;
140 case T('&'):
141 fputts(T("&amp;"), fp);
142 break;
143 case T('<'):
144 fputts(T("&lt;"), fp);
145 break;
146 case T('"'):
147 fputts(T("&quot;"), fp);
148 break;
149#ifdef W3C14N
150 case 9:
151 fputts(T("&#x9;"), fp);
152 break;
153 case 10:
154 fputts(T("&#xA;"), fp);
155 break;
156 case 13:
157 fputts(T("&#xD;"), fp);
158 break;
159#else
160 case T('>'):
161 fputts(T("&gt;"), fp);
162 break;
163 case 9:
164 case 10:
165 case 13:
166 ftprintf(fp, T("&#%d;"), *s);
167 break;
168#endif
169 default:
170 puttc(*s, fp);
171 break;
172 }
173 s++;
174 }
175}
176
177/* Lexicographically comparing UTF-8 encoded attribute values,
178is equivalent to lexicographically comparing based on the character number. */
179
180static int
181attcmp(const void *att1, const void *att2) {
182 return tcscmp(*(const XML_Char *const *)att1, *(const XML_Char *const *)att2);
183}
184
185static void XMLCALL
186startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
187 int nAtts;
188 const XML_Char **p;
189 FILE *fp = ((XmlwfUserData *)userData)->fp;
190 puttc(T('<'), fp);
191 fputts(name, fp);
192
193 p = atts;
194 while (*p)
195 ++p;
196 nAtts = (int)((p - atts) >> 1);
197 if (nAtts > 1)
198 qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
199 while (*atts) {
200 puttc(T(' '), fp);
201 fputts(*atts++, fp);
202 attributeValue(fp, *atts);
203 atts++;
204 }
205 puttc(T('>'), fp);
206}
207
208static void XMLCALL
209endElement(void *userData, const XML_Char *name) {
210 FILE *fp = ((XmlwfUserData *)userData)->fp;
211 puttc(T('<'), fp);
212 puttc(T('/'), fp);
213 fputts(name, fp);
214 puttc(T('>'), fp);
215}
216
217static int
218nsattcmp(const void *p1, const void *p2) {
219 const XML_Char *att1 = *(const XML_Char *const *)p1;
220 const XML_Char *att2 = *(const XML_Char *const *)p2;
221 int sep1 = (tcsrchr(att1, NSSEP) != 0);
222 int sep2 = (tcsrchr(att2, NSSEP) != 0);
223 if (sep1 != sep2)
224 return sep1 - sep2;
225 return tcscmp(att1, att2);
226}
227
228static void XMLCALL
229startElementNS(void *userData, const XML_Char *name, const XML_Char **atts) {
230 int nAtts;
231 int nsi;
232 const XML_Char **p;
233 FILE *fp = ((XmlwfUserData *)userData)->fp;
234 const XML_Char *sep;
235 puttc(T('<'), fp);
236
237 sep = tcsrchr(name, NSSEP);
238 if (sep) {
239 fputts(T("n1:"), fp);
240 fputts(sep + 1, fp);
241 fputts(T(" xmlns:n1"), fp);
242 attributeValue(fp, name);
243 nsi = 2;
244 } else {
245 fputts(name, fp);
246 nsi = 1;
247 }
248
249 p = atts;
250 while (*p)
251 ++p;
252 nAtts = (int)((p - atts) >> 1);
253 if (nAtts > 1)
254 qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
255 while (*atts) {
256 name = *atts++;
257 sep = tcsrchr(name, NSSEP);
258 puttc(T(' '), fp);
259 if (sep) {
260 ftprintf(fp, T("n%d:"), nsi);
261 fputts(sep + 1, fp);
262 } else
263 fputts(name, fp);
264 attributeValue(fp, *atts);
265 if (sep) {
266 ftprintf(fp, T(" xmlns:n%d"), nsi++);
267 attributeValue(fp, name);
268 }
269 atts++;
270 }
271 puttc(T('>'), fp);
272}
273
274static void XMLCALL
275endElementNS(void *userData, const XML_Char *name) {
276 FILE *fp = ((XmlwfUserData *)userData)->fp;
277 const XML_Char *sep;
278 puttc(T('<'), fp);
279 puttc(T('/'), fp);
280 sep = tcsrchr(name, NSSEP);
281 if (sep) {
282 fputts(T("n1:"), fp);
283 fputts(sep + 1, fp);
284 } else
285 fputts(name, fp);
286 puttc(T('>'), fp);
287}
288
289#ifndef W3C14N
290
291static void XMLCALL
292processingInstruction(void *userData, const XML_Char *target,
293 const XML_Char *data) {
294 FILE *fp = ((XmlwfUserData *)userData)->fp;
295 puttc(T('<'), fp);
296 puttc(T('?'), fp);
297 fputts(target, fp);
298 puttc(T(' '), fp);
299 fputts(data, fp);
300 puttc(T('?'), fp);
301 puttc(T('>'), fp);
302}
303
304static XML_Char *
307 int count = 0;
308 int numBytes;
309
310 /* Get the length of the string, including terminator */
311 while (s[count++] != 0) {
312 /* Do nothing */
313 }
314 numBytes = count * sizeof(XML_Char);
316 if (result == NULL)
317 return NULL;
319 return result;
320}
321
322static void XMLCALL
323startDoctypeDecl(void *userData, const XML_Char *doctypeName,
324 const XML_Char *sysid, const XML_Char *publid,
326 XmlwfUserData *data = (XmlwfUserData *)userData;
330 data->currentDoctypeName = xcsdup(doctypeName);
331}
332
333static void
335 NotationList *notationListHead = data->notationListHead;
336
337 while (notationListHead != NULL) {
338 NotationList *next = notationListHead->next;
339 free((void *)notationListHead->notationName);
340 free((void *)notationListHead->systemId);
341 free((void *)notationListHead->publicId);
342 free(notationListHead);
343 notationListHead = next;
344 }
345 data->notationListHead = NULL;
346}
347
348static void
350 free((void *)userData->currentDoctypeName);
351 userData->currentDoctypeName = NULL;
352 freeNotations(userData);
353}
354
355static int
356xcscmp(const XML_Char *xs, const XML_Char *xt) {
357 while (*xs != 0 && *xt != 0) {
358 if (*xs < *xt)
359 return -1;
360 if (*xs > *xt)
361 return 1;
362 xs++;
363 xt++;
364 }
365 if (*xs < *xt)
366 return -1;
367 if (*xs > *xt)
368 return 1;
369 return 0;
370}
371
372static int
373notationCmp(const void *a, const void *b) {
374 const NotationList *const n1 = *(const NotationList *const *)a;
375 const NotationList *const n2 = *(const NotationList *const *)b;
376
377 return xcscmp(n1->notationName, n2->notationName);
378}
379
380static void XMLCALL
381endDoctypeDecl(void *userData) {
382 XmlwfUserData *data = (XmlwfUserData *)userData;
384 int notationCount = 0;
386 int i;
387
388 /* How many notations do we have? */
389 for (p = data->notationListHead; p != NULL; p = p->next)
391 if (notationCount == 0) {
392 /* Nothing to report */
393 free((void *)data->currentDoctypeName);
394 data->currentDoctypeName = NULL;
395 return;
396 }
397
399 if (notations == NULL) {
400 fprintf(stderr, "Unable to sort notations");
402 return;
403 }
404
405 for (p = data->notationListHead, i = 0; i < notationCount; p = p->next, i++) {
406 notations[i] = p;
407 }
409
410 /* Output the DOCTYPE header */
411 fputts(T("<!DOCTYPE "), data->fp);
412 fputts(data->currentDoctypeName, data->fp);
413 fputts(T(" [\n"), data->fp);
414
415 /* Now the NOTATIONs */
416 for (i = 0; i < notationCount; i++) {
417 fputts(T("<!NOTATION "), data->fp);
418 fputts(notations[i]->notationName, data->fp);
419 if (notations[i]->publicId != NULL) {
420 fputts(T(" PUBLIC '"), data->fp);
421 fputts(notations[i]->publicId, data->fp);
422 puttc(T('\''), data->fp);
423 if (notations[i]->systemId != NULL) {
424 puttc(T(' '), data->fp);
425 puttc(T('\''), data->fp);
426 fputts(notations[i]->systemId, data->fp);
427 puttc(T('\''), data->fp);
428 }
429 } else if (notations[i]->systemId != NULL) {
430 fputts(T(" SYSTEM '"), data->fp);
431 fputts(notations[i]->systemId, data->fp);
432 puttc(T('\''), data->fp);
433 }
434 puttc(T('>'), data->fp);
435 puttc(T('\n'), data->fp);
436 }
437
438 /* Finally end the DOCTYPE */
439 fputts(T("]>\n"), data->fp);
440
441 free(notations);
443 free((void *)data->currentDoctypeName);
444 data->currentDoctypeName = NULL;
445}
446
447static void XMLCALL
448notationDecl(void *userData, const XML_Char *notationName, const XML_Char *base,
449 const XML_Char *systemId, const XML_Char *publicId) {
450 XmlwfUserData *data = (XmlwfUserData *)userData;
451 NotationList *entry = malloc(sizeof(NotationList));
452 const char *errorMessage = "Unable to store NOTATION for output\n";
453
454 UNUSED_P(base);
455 if (entry == NULL) {
457 return; /* Nothing we can really do about this */
458 }
459 entry->notationName = xcsdup(notationName);
460 if (entry->notationName == NULL) {
462 free(entry);
463 return;
464 }
465 if (systemId != NULL) {
466 entry->systemId = xcsdup(systemId);
467 if (entry->systemId == NULL) {
469 free((void *)entry->notationName);
470 free(entry);
471 return;
472 }
473 } else {
474 entry->systemId = NULL;
475 }
476 if (publicId != NULL) {
477 entry->publicId = xcsdup(publicId);
478 if (entry->publicId == NULL) {
480 free((void *)entry->systemId); /* Safe if it's NULL */
481 free((void *)entry->notationName);
482 free(entry);
483 return;
484 }
485 } else {
486 entry->publicId = NULL;
487 }
488
489 entry->next = data->notationListHead;
490 data->notationListHead = entry;
491}
492
493#endif /* not W3C14N */
494
495static void XMLCALL
496defaultCharacterData(void *userData, const XML_Char *s, int len) {
497 UNUSED_P(s);
498 UNUSED_P(len);
500}
501
502static void XMLCALL
503defaultStartElement(void *userData, const XML_Char *name,
504 const XML_Char **atts) {
505 UNUSED_P(name);
506 UNUSED_P(atts);
508}
509
510static void XMLCALL
511defaultEndElement(void *userData, const XML_Char *name) {
512 UNUSED_P(name);
514}
515
516static void XMLCALL
517defaultProcessingInstruction(void *userData, const XML_Char *target,
518 const XML_Char *data) {
519 UNUSED_P(target);
520 UNUSED_P(data);
522}
523
524static void XMLCALL
525nopCharacterData(void *userData, const XML_Char *s, int len) {
526 UNUSED_P(userData);
527 UNUSED_P(s);
528 UNUSED_P(len);
529}
530
531static void XMLCALL
532nopStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
533 UNUSED_P(userData);
534 UNUSED_P(name);
535 UNUSED_P(atts);
536}
537
538static void XMLCALL
539nopEndElement(void *userData, const XML_Char *name) {
540 UNUSED_P(userData);
541 UNUSED_P(name);
542}
543
544static void XMLCALL
545nopProcessingInstruction(void *userData, const XML_Char *target,
546 const XML_Char *data) {
547 UNUSED_P(userData);
548 UNUSED_P(target);
549 UNUSED_P(data);
550}
551
552static void XMLCALL
553markup(void *userData, const XML_Char *s, int len) {
554 FILE *fp = ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp;
555 for (; len > 0; --len, ++s)
556 puttc(*s, fp);
557}
558
559static void
561 const XML_Char *uri = XML_GetBase(parser);
563 if (uri)
564 ftprintf(fp, T(" uri=\"%s\""), uri);
565 ftprintf(fp,
566 T(" byte=\"%") T(XML_FMT_INT_MOD) T("d\"") T(" nbytes=\"%d\"")
567 T(" line=\"%") T(XML_FMT_INT_MOD) T("u\"") T(" col=\"%")
568 T(XML_FMT_INT_MOD) T("u\""),
572}
573
574static void
575metaStartDocument(void *userData) {
576 fputts(T("<document>\n"),
577 ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp);
578}
579
580static void
581metaEndDocument(void *userData) {
582 fputts(T("</document>\n"),
583 ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp);
584}
585
586static void XMLCALL
587metaStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
588 XML_Parser parser = (XML_Parser)userData;
590 FILE *fp = data->fp;
593 const XML_Char **idAttPtr;
595 if (idAttIndex < 0)
596 idAttPtr = 0;
597 else
598 idAttPtr = atts + idAttIndex;
599
600 ftprintf(fp, T("<starttag name=\"%s\""), name);
602 if (*atts) {
603 fputts(T(">\n"), fp);
604 do {
605 ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
606 characterData(data, atts[1], (int)tcslen(atts[1]));
607 if (atts >= specifiedAttsEnd)
608 fputts(T("\" defaulted=\"yes\"/>\n"), fp);
609 else if (atts == idAttPtr)
610 fputts(T("\" id=\"yes\"/>\n"), fp);
611 else
612 fputts(T("\"/>\n"), fp);
613 } while (*(atts += 2));
614 fputts(T("</starttag>\n"), fp);
615 } else
616 fputts(T("/>\n"), fp);
617}
618
619static void XMLCALL
620metaEndElement(void *userData, const XML_Char *name) {
621 XML_Parser parser = (XML_Parser)userData;
623 FILE *fp = data->fp;
624 ftprintf(fp, T("<endtag name=\"%s\""), name);
626 fputts(T("/>\n"), fp);
627}
628
629static void XMLCALL
630metaProcessingInstruction(void *userData, const XML_Char *target,
631 const XML_Char *data) {
632 XML_Parser parser = (XML_Parser)userData;
634 FILE *fp = usrData->fp;
635 ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
637 puttc(T('"'), fp);
639 fputts(T("/>\n"), fp);
640}
641
642static void XMLCALL
643metaComment(void *userData, const XML_Char *data) {
644 XML_Parser parser = (XML_Parser)userData;
646 FILE *fp = usrData->fp;
647 fputts(T("<comment data=\""), fp);
649 puttc(T('"'), fp);
651 fputts(T("/>\n"), fp);
652}
653
654static void XMLCALL
655metaStartCdataSection(void *userData) {
656 XML_Parser parser = (XML_Parser)userData;
658 FILE *fp = data->fp;
659 fputts(T("<startcdata"), fp);
661 fputts(T("/>\n"), fp);
662}
663
664static void XMLCALL
665metaEndCdataSection(void *userData) {
666 XML_Parser parser = (XML_Parser)userData;
668 FILE *fp = data->fp;
669 fputts(T("<endcdata"), fp);
671 fputts(T("/>\n"), fp);
672}
673
674static void XMLCALL
675metaCharacterData(void *userData, const XML_Char *s, int len) {
676 XML_Parser parser = (XML_Parser)userData;
678 FILE *fp = data->fp;
679 fputts(T("<chars str=\""), fp);
681 puttc(T('"'), fp);
683 fputts(T("/>\n"), fp);
684}
685
686static void XMLCALL
688 const XML_Char *sysid, const XML_Char *pubid,
690 XML_Parser parser = (XML_Parser)userData;
692 FILE *fp = data->fp;
696 ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
698 fputts(T("/>\n"), fp);
699}
700
701static void XMLCALL
702metaEndDoctypeDecl(void *userData) {
703 XML_Parser parser = (XML_Parser)userData;
705 FILE *fp = data->fp;
706 fputts(T("<enddoctype"), fp);
708 fputts(T("/>\n"), fp);
709}
710
711static void XMLCALL
712metaNotationDecl(void *userData, const XML_Char *notationName,
713 const XML_Char *base, const XML_Char *systemId,
714 const XML_Char *publicId) {
715 XML_Parser parser = (XML_Parser)userData;
717 FILE *fp = data->fp;
718 UNUSED_P(base);
719 ftprintf(fp, T("<notation name=\"%s\""), notationName);
720 if (publicId)
721 ftprintf(fp, T(" public=\"%s\""), publicId);
722 if (systemId) {
723 fputts(T(" system=\""), fp);
724 characterData(data, systemId, (int)tcslen(systemId));
725 puttc(T('"'), fp);
726 }
728 fputts(T("/>\n"), fp);
729}
730
731static void XMLCALL
732metaEntityDecl(void *userData, const XML_Char *entityName, int is_param,
733 const XML_Char *value, int value_length, const XML_Char *base,
734 const XML_Char *systemId, const XML_Char *publicId,
735 const XML_Char *notationName) {
736 XML_Parser parser = (XML_Parser)userData;
738 FILE *fp = data->fp;
739
740 UNUSED_P(is_param);
741 UNUSED_P(base);
742 if (value) {
743 ftprintf(fp, T("<entity name=\"%s\""), entityName);
745 puttc(T('>'), fp);
747 fputts(T("</entity/>\n"), fp);
748 } else if (notationName) {
749 ftprintf(fp, T("<entity name=\"%s\""), entityName);
750 if (publicId)
751 ftprintf(fp, T(" public=\"%s\""), publicId);
752 fputts(T(" system=\""), fp);
753 characterData(data, systemId, (int)tcslen(systemId));
754 puttc(T('"'), fp);
755 ftprintf(fp, T(" notation=\"%s\""), notationName);
757 fputts(T("/>\n"), fp);
758 } else {
759 ftprintf(fp, T("<entity name=\"%s\""), entityName);
760 if (publicId)
761 ftprintf(fp, T(" public=\"%s\""), publicId);
762 fputts(T(" system=\""), fp);
763 characterData(data, systemId, (int)tcslen(systemId));
764 puttc(T('"'), fp);
766 fputts(T("/>\n"), fp);
767 }
768}
769
770static void XMLCALL
772 const XML_Char *uri) {
773 XML_Parser parser = (XML_Parser)userData;
775 FILE *fp = data->fp;
776 fputts(T("<startns"), fp);
777 if (prefix)
778 ftprintf(fp, T(" prefix=\"%s\""), prefix);
779 if (uri) {
780 fputts(T(" ns=\""), fp);
782 fputts(T("\"/>\n"), fp);
783 } else
784 fputts(T("/>\n"), fp);
785}
786
787static void XMLCALL
788metaEndNamespaceDecl(void *userData, const XML_Char *prefix) {
789 XML_Parser parser = (XML_Parser)userData;
791 FILE *fp = data->fp;
792 if (! prefix)
793 fputts(T("<endns/>\n"), fp);
794 else
795 ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
796}
797
798static int XMLCALL
799unknownEncodingConvert(void *data, const char *p) {
800 return codepageConvert(*(int *)data, p);
801}
802
803static int XMLCALL
804unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info) {
805 int cp;
806 static const XML_Char prefixL[] = T("windows-");
807 static const XML_Char prefixU[] = T("WINDOWS-");
808 int i;
809
810 UNUSED_P(userData);
811 for (i = 0; prefixU[i]; i++)
812 if (name[i] != prefixU[i] && name[i] != prefixL[i])
813 return 0;
814
815 cp = 0;
816 for (; name[i]; i++) {
817 static const XML_Char digits[] = T("0123456789");
818 const XML_Char *s = tcschr(digits, name[i]);
819 if (! s)
820 return 0;
821 cp *= 10;
822 cp += (int)(s - digits);
823 if (cp >= 0x10000)
824 return 0;
825 }
826 if (! codepageMap(cp, info->map))
827 return 0;
828 info->convert = unknownEncodingConvert;
829 /* We could just cast the code page integer to a void *,
830 and avoid the use of release. */
831 info->release = free;
832 info->data = malloc(sizeof(int));
833 if (! info->data)
834 return 0;
835 *(int *)info->data = cp;
836 return 1;
837}
838
839static int XMLCALL
840notStandalone(void *userData) {
841 UNUSED_P(userData);
842 return 0;
843}
844
845static void
847 XML_Char *s = prog;
848 XML_Char ch;
850 while ((ch = *s) != 0) {
851 if (ch == '/'
852#if defined(_WIN32)
853 || ch == '\\'
854#endif
855 )
856 prog = s + 1;
857 ++s;
858 }
859 ftprintf(stdout, T("%s using %s\n"), prog, XML_ExpatVersion());
860 if (features != NULL && features[0].feature != XML_FEATURE_END) {
861 int i = 1;
862 ftprintf(stdout, T("%s"), features[0].name);
863 if (features[0].value)
864 ftprintf(stdout, T("=%ld"), features[0].value);
865 while (features[i].feature != XML_FEATURE_END) {
866 ftprintf(stdout, T(", %s"), features[i].name);
867 if (features[i].value)
868 ftprintf(stdout, T("=%ld"), features[i].value);
869 ++i;
870 }
871 ftprintf(stdout, T("\n"));
872 }
873}
874
875#if defined(__GNUC__)
877#endif
878static void
879usage(const XML_Char *prog, int rc) {
880 ftprintf(
881 stderr,
882 /* Generated with:
883 * $ xmlwf/xmlwf_helpgen.sh
884 * To update, change xmlwf/xmlwf_helpgen.py, then paste the output of
885 * xmlwf/xmlwf_helpgen.sh in here.
886 */
887 /* clang-format off */
888 T("usage:\n")
889 T(" %s [OPTIONS] [FILE ...]\n")
890 T(" %s -h|--help\n")
891 T(" %s -v|--version\n")
892 T("\n")
893 T("xmlwf - Determines if an XML document is well-formed\n")
894 T("\n")
895 T("positional arguments:\n")
896 T(" FILE file to process (default: STDIN)\n")
897 T("\n")
898 T("input control arguments:\n")
899 T(" -s print an error if the document is not [s]tandalone\n")
900 T(" -n enable [n]amespace processing\n")
901 T(" -p enable processing of external DTDs and [p]arameter entities\n")
902 T(" -x enable processing of e[x]ternal entities\n")
903 T(" -e ENCODING override any in-document [e]ncoding declaration\n")
904 T(" -w enable support for [W]indows code pages\n")
905 T(" -r disable memory-mapping and use [r]ead calls instead\n")
906 T(" -g BYTES buffer size to request per call pair to XML_[G]etBuffer and read (default: 8 KiB)\n")
907 T(" -k when processing multiple files, [k]eep processing after first file with error\n")
908 T("\n")
909 T("output control arguments:\n")
910 T(" -d DIRECTORY output [d]estination directory\n")
911 T(" -c write a [c]opy of input XML, not canonical XML\n")
912 T(" -m write [m]eta XML, not canonical XML\n")
913 T(" -t write no XML output for [t]iming of plain parsing\n")
914 T(" -N enable adding doctype and [n]otation declarations\n")
915 T("\n")
916 T("billion laughs attack protection:\n")
917 T(" NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n")
918 T("\n")
919 T(" -a FACTOR set maximum tolerated [a]mplification factor (default: 100.0)\n")
920 T(" -b BYTES set number of output [b]ytes needed to activate (default: 8 MiB)\n")
921 T("\n")
922 T("reparse deferral:\n")
923 T(" -q disable reparse deferral, and allow [q]uadratic parse runtime with large tokens\n")
924 T("\n")
925 T("info arguments:\n")
926 T(" -h, --help show this [h]elp message and exit\n")
927 T(" -v, --version show program's [v]ersion number and exit\n")
928 T("\n")
929 T("exit status:\n")
930 T(" 0 the input files are well-formed and the output (if requested) was written successfully\n")
931 T(" 1 could not allocate data structures, signals a serious problem with execution environment\n")
932 T(" 2 one or more input files were not well-formed\n")
933 T(" 3 could not create an output file\n")
934 T(" 4 command-line argument error\n")
935 T("\n")
936 T("xmlwf of libexpat is software libre, licensed under the MIT license.\n")
937 T("Please report bugs at https://github.com/libexpat/libexpat/issues -- thank you!\n")
938 , /* clang-format on */
939 prog, prog, prog);
940 exit(rc);
941}
942
943#if defined(__MINGW32__) && defined(XML_UNICODE)
944/* Silence warning about missing prototype */
945int wmain(int argc, XML_Char **argv);
946#endif
947
948#define XMLWF_SHIFT_ARG_INTO(constCharStarTarget, argc, argv, i, j) \
949 { \
950 if (argv[i][j + 1] == T('\0')) { \
951 if (++i == argc) { \
952 usage(argv[0], XMLWF_EXIT_USAGE_ERROR); \
953 /* usage called exit(..), never gets here */ \
954 } \
955 constCharStarTarget = argv[i]; \
956 } else { \
957 constCharStarTarget = argv[i] + j + 1; \
958 } \
959 i++; \
960 j = 0; \
961 }
962
963int
965 int i, j;
966 const XML_Char *outputDir = NULL;
967 const XML_Char *encoding = NULL;
968 unsigned processFlags = XML_MAP_FILE;
969 int windowsCodePages = 0;
970 int outputType = 0;
971 int useNamespaces = 0;
972 int requireStandalone = 0;
973 int requiresNotations = 0;
974 int continueOnError = 0;
975
976 float attackMaximumAmplification = -1.0f; /* signaling "not set" */
977 unsigned long long attackThresholdBytes = 0;
979
981
985 int useStdin = 0;
986 XmlwfUserData userData = {NULL, NULL, NULL};
987
988#ifdef _MSC_VER
990#endif
991
992 i = 1;
993 j = 0;
994 while (i < argc) {
995 if (j == 0) {
996 if (argv[i][0] != T('-'))
997 break;
998 if (argv[i][1] == T('-')) {
999 if (argv[i][2] == T('\0')) {
1000 i++;
1001 break;
1002 } else if (tcscmp(argv[i] + 2, T("help")) == 0) {
1004 // usage called exit(..), never gets here
1005 } else if (tcscmp(argv[i] + 2, T("version")) == 0) {
1006 showVersion(argv[0]);
1007 return XMLWF_EXIT_SUCCESS;
1008 }
1009 }
1010 j++;
1011 }
1012 switch (argv[i][j]) {
1013 case T('r'):
1015 j++;
1016 break;
1017 case T('s'):
1019 j++;
1020 break;
1021 case T('n'):
1022 useNamespaces = 1;
1023 j++;
1024 break;
1025 case T('p'):
1027 /* fall through */
1028 case T('x'):
1030 j++;
1031 break;
1032 case T('w'):
1033 windowsCodePages = 1;
1034 j++;
1035 break;
1036 case T('m'):
1037 outputType = 'm';
1038 j++;
1039 break;
1040 case T('c'):
1041 outputType = 'c';
1042 useNamespaces = 0;
1043 j++;
1044 break;
1045 case T('t'):
1046 outputType = 't';
1047 j++;
1048 break;
1049 case T('N'):
1051 j++;
1052 break;
1053 case T('d'):
1055 break;
1056 case T('e'):
1058 break;
1059 case T('h'):
1061 // usage called exit(..), never gets here
1062 case T('v'):
1063 showVersion(argv[0]);
1064 return XMLWF_EXIT_SUCCESS;
1065 case T('g'): {
1066 const XML_Char *valueText = NULL;
1068
1069 errno = 0;
1071 const long long read_size_bytes_candidate
1073 if ((errno != 0) || (afterValueText[0] != T('\0'))
1075 || (read_size_bytes_candidate > (INT_MAX / 2 + 1))) {
1076 // This prevents tperror(..) from reporting misleading "[..]: Success"
1077 errno = ERANGE;
1078 tperror(T("invalid buffer size") T(
1079 " (needs an integer from 1 to INT_MAX/2+1 i.e. 1,073,741,824 on most platforms)"));
1081 }
1083 break;
1084 }
1085 case T('k'):
1086 continueOnError = 1;
1087 j++;
1088 break;
1089 case T('a'): {
1090 const XML_Char *valueText = NULL;
1092
1093 errno = 0;
1096 if ((errno != 0) || (afterValueText[0] != T('\0'))
1098 || (attackMaximumAmplification < 1.0f)) {
1099 // This prevents tperror(..) from reporting misleading "[..]: Success"
1100 errno = ERANGE;
1101 tperror(T("invalid amplification limit") T(
1102 " (needs a floating point number greater or equal than 1.0)"));
1104 }
1105#if XML_GE == 0
1107 T("Warning: Given amplification limit ignored")
1108 T(", xmlwf has been compiled without DTD/GE support.\n"));
1109#endif
1110 break;
1111 }
1112 case T('b'): {
1113 const XML_Char *valueText = NULL;
1115
1116 errno = 0;
1119 if ((errno != 0) || (afterValueText[0] != T('\0'))) {
1120 // This prevents tperror(..) from reporting misleading "[..]: Success"
1121 errno = ERANGE;
1122 tperror(T("invalid ignore threshold")
1123 T(" (needs an integer from 0 to 2^64-1)"));
1125 }
1127#if XML_GE == 0
1129 T("Warning: Given attack threshold ignored")
1130 T(", xmlwf has been compiled without DTD/GE support.\n"));
1131#endif
1132 break;
1133 }
1134 case T('q'): {
1136 j++;
1137 break;
1138 }
1139 case T('\0'):
1140 if (j > 1) {
1141 i++;
1142 j = 0;
1143 break;
1144 }
1145 /* fall through */
1146 default:
1148 // usage called exit(..), never gets here
1149 }
1150 }
1151 if (i == argc) {
1152 useStdin = 1;
1154 i--;
1155 }
1156 for (; i < argc; i++) {
1157 XML_Char *outName = 0;
1158 int result;
1160 if (useNamespaces)
1162 else
1164
1165 if (! parser) {
1166 tperror(T("Could not instantiate parser"));
1168 }
1169
1170 if (attackMaximumAmplification != -1.0f) {
1171#if XML_GE == 1
1174#endif
1175 }
1177#if XML_GE == 1
1180#else
1181 (void)attackThresholdBytes; // silence -Wunused-but-set-variable
1182#endif
1183 }
1184
1185 if (disableDeferral) {
1187 if (! success) {
1188 // This prevents tperror(..) from reporting misleading "[..]: Success"
1189 errno = EINVAL;
1190 tperror(T("Failed to disable reparse deferral"));
1192 }
1193 }
1194
1198 if (outputType == 't') {
1199 /* This is for doing timings; this gives a more realistic estimate of
1200 the parsing time. */
1201 outputDir = 0;
1205 } else if (outputDir) {
1206 const XML_Char *delim = T("/");
1207 const XML_Char *file = useStdin ? T("STDIN") : argv[i];
1208 if (! useStdin) {
1209 /* Jump after last (back)slash */
1210 const XML_Char *lastDelim = tcsrchr(file, delim[0]);
1211 if (lastDelim)
1212 file = lastDelim + 1;
1213#if defined(_WIN32)
1214 else {
1215 const XML_Char *winDelim = T("\\");
1217 if (lastDelim) {
1218 file = lastDelim + 1;
1219 delim = winDelim;
1220 }
1221 }
1222#endif
1223 }
1225 * sizeof(XML_Char));
1226 if (! outName) {
1227 tperror(T("Could not allocate memory"));
1229 }
1233 userData.fp = tfopen(outName, T("wb"));
1234 if (! userData.fp) {
1237 free(outName);
1239 if (continueOnError) {
1240 continue;
1241 } else {
1242 break;
1243 }
1244 }
1245 setvbuf(userData.fp, NULL, _IOFBF, 16384);
1246#ifdef XML_UNICODE
1247 puttc(0xFEFF, userData.fp);
1248#endif
1249 XML_SetUserData(parser, &userData);
1250 switch (outputType) {
1251 case 'm':
1266 break;
1267 case 'c':
1274 break;
1275 default:
1276 if (useNamespaces)
1278 else
1281#ifndef W3C14N
1283 if (requiresNotations) {
1286 }
1287#endif /* not W3C14N */
1288 break;
1289 }
1290 }
1291 if (windowsCodePages)
1294 if (outputDir) {
1295 if (outputType == 'm')
1297 fclose(userData.fp);
1298 if (! result) {
1300 }
1301 free(outName);
1302 }
1304 if (! result) {
1306 cleanupUserData(&userData);
1307 if (! continueOnError) {
1308 break;
1309 }
1310 }
1311 }
1312 return exitCode;
1313}
const char apr_size_t len
Definition ap_regex.h:187
int wmain(int argc, const wchar_t **wargv, const wchar_t **wenv)
Definition apr_app.c:50
int codepageConvert(int cp, const char *p)
Definition codepage.c:85
int codepageMap(int cp, int *map)
Definition codepage.c:48
#define XML_FMT_INT_MOD
int XML_GetCurrentByteCount(XML_Parser parser)
Definition xmlparse.c:2335
#define XML_FALSE
Definition expat.h:59
int XML_GetSpecifiedAttributeCount(XML_Parser parser)
Definition xmlparse.c:1668
XML_Bool XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled)
Definition xmlparse.c:2641
void XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end)
Definition xmlparse.c:1732
void XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
Definition xmlparse.c:1691
int XML_GetIdAttributeIndex(XML_Parser parser)
Definition xmlparse.c:1675
@ XML_FEATURE_END
Definition expat.h:1020
XML_Index XML_GetCurrentByteIndex(XML_Parser parser)
Definition xmlparse.c:2325
void XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler)
Definition xmlparse.c:1726
void XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler)
Definition xmlparse.c:1831
unsigned char XML_Bool
Definition expat.h:57
void XML_UseParserAsHandlerArg(XML_Parser parser)
Definition xmlparse.c:1603
void XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler)
Definition xmlparse.c:1712
const XML_Char * XML_GetBase(XML_Parser parser)
Definition xmlparse.c:1661
void XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler)
Definition xmlparse.c:1883
const XML_Feature * XML_GetFeatureList(void)
Definition xmlparse.c:2567
void XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData)
Definition xmlparse.c:1862
XML_ParamEntityParsing
Definition expat.h:880
@ XML_PARAM_ENTITY_PARSING_ALWAYS
Definition expat.h:883
@ XML_PARAM_ENTITY_PARSING_NEVER
Definition expat.h:881
void XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end)
Definition xmlparse.c:1772
void XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end)
Definition xmlparse.c:1807
#define XML_GetUserData(parser)
Definition expat.h:683
XML_Parser XML_ParserCreate(const XML_Char *encoding)
Definition xmlparse.c:766
void XML_ParserFree(XML_Parser parser)
Definition xmlparse.c:1537
void XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler)
Definition xmlparse.c:1756
XML_Size XML_GetCurrentLineNumber(XML_Parser parser)
Definition xmlparse.c:2364
struct XML_ParserStruct * XML_Parser
Definition expat.h:55
void XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler)
Definition xmlparse.c:1801
XML_Size XML_GetCurrentColumnNumber(XML_Parser parser)
Definition xmlparse.c:2376
void XML_SetUserData(XML_Parser parser, void *userData)
Definition xmlparse.c:1637
XML_Parser XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator)
Definition xmlparse.c:771
void XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler)
Definition xmlparse.c:1719
void XML_DefaultCurrent(XML_Parser parser)
Definition xmlparse.c:2414
const XML_LChar * XML_ExpatVersion(void)
Definition xmlparse.c:2537
#define XML_TRUE
Definition expat.h:58
int XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing parsing)
Definition xmlparse.c:1895
char XML_Char
#define XMLCALL
ap_conf_vector_t * base
unsigned int count
Definition apr_md5.h:152
apr_bucket apr_bucket_brigade * a
apr_redis_t * rc
Definition apr_redis.h:173
const char * uri
Definition apr_uri.h:159
apr_xml_parser ** parser
Definition apr_xml.h:228
apr_size_t size
const char * value
Definition apr_env.h:51
void * data
const char apr_file_t * file
apr_array_header_t ** result
apr_pool_t int argc
Definition apr_getopt.h:104
apr_pool_t * b
Definition apr_pools.h:529
const char apr_status_t(*) apr_pool_t *poo __attribute__)((nonnull(2, 4)))
Definition apr_pools.h:567
const char * sep
const char * s
Definition apr_strings.h:95
#define UNUSED_P(p)
Definition internal.h:137
apr_pool_t * p
Definition md_event.c:32
const char * argv[3]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
char * name
struct NotationList * next
Definition xmlwf.c:78
const XML_Char * publicId
Definition xmlwf.c:81
const XML_Char * systemId
Definition xmlwf.c:80
const XML_Char * notationName
Definition xmlwf.c:79
const XML_Char * currentDoctypeName
Definition xmlwf.c:87
FILE * fp
Definition xmlwf.c:85
NotationList * notationListHead
Definition xmlwf.c:86
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray
INT info
int XML_ProcessFile(XML_Parser parser, const XML_Char *filename, unsigned flags)
Definition xmlfile.c:245
int g_read_size_bytes
Definition xmlfile.c:75
#define XML_EXTERNAL_ENTITIES
Definition xmlfile.h:37
#define XML_MAP_FILE
Definition xmlfile.h:36
#define fputts
Definition xmltchar.h:64
#define tperror
Definition xmltchar.h:72
#define tfopen
Definition xmltchar.h:63
#define T(x)
Definition xmltchar.h:61
#define ftprintf
Definition xmltchar.h:62
#define tcscpy
Definition xmltchar.h:67
#define tcstof
Definition xmltchar.h:77
#define tcscmp
Definition xmltchar.h:66
#define tcsrchr
Definition xmltchar.h:70
#define tcschr
Definition xmltchar.h:69
#define tcstoull
Definition xmltchar.h:78
#define tmain
Definition xmltchar.h:74
#define puttc
Definition xmltchar.h:65
#define tremove
Definition xmltchar.h:75
#define tcscat
Definition xmltchar.h:68
#define tcslen
Definition xmltchar.h:71
static void XMLCALL metaEndDoctypeDecl(void *userData)
Definition xmlwf.c:702
static void XMLCALL defaultCharacterData(void *userData, const XML_Char *s, int len)
Definition xmlwf.c:496
static void XMLCALL nopCharacterData(void *userData, const XML_Char *s, int len)
Definition xmlwf.c:525
static XML_Char * xcsdup(const XML_Char *s)
Definition xmlwf.c:305
static void XMLCALL defaultProcessingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
Definition xmlwf.c:517
struct xmlwfUserData XmlwfUserData
static void XMLCALL metaProcessingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
Definition xmlwf.c:630
static void XMLCALL endElement(void *userData, const XML_Char *name)
Definition xmlwf.c:209
static void XMLCALL endDoctypeDecl(void *userData)
Definition xmlwf.c:381
static void XMLCALL defaultStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
Definition xmlwf.c:503
static void XMLCALL startElement(void *userData, const XML_Char *name, const XML_Char **atts)
Definition xmlwf.c:186
static void XMLCALL metaStartDoctypeDecl(void *userData, const XML_Char *doctypeName, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset)
Definition xmlwf.c:687
static void XMLCALL metaStartNamespaceDecl(void *userData, const XML_Char *prefix, const XML_Char *uri)
Definition xmlwf.c:771
ExitCode
Definition xmlwf.c:68
@ XMLWF_EXIT_USAGE_ERROR
Definition xmlwf.c:73
@ XMLWF_EXIT_NOT_WELLFORMED
Definition xmlwf.c:71
@ XMLWF_EXIT_INTERNAL_ERROR
Definition xmlwf.c:70
@ XMLWF_EXIT_OUTPUT_ERROR
Definition xmlwf.c:72
@ XMLWF_EXIT_SUCCESS
Definition xmlwf.c:69
static void cleanupUserData(XmlwfUserData *userData)
Definition xmlwf.c:349
static void XMLCALL characterData(void *userData, const XML_Char *s, int len)
Definition xmlwf.c:95
static void XMLCALL markup(void *userData, const XML_Char *s, int len)
Definition xmlwf.c:553
static void XMLCALL endElementNS(void *userData, const XML_Char *name)
Definition xmlwf.c:275
#define XMLWF_SHIFT_ARG_INTO(constCharStarTarget, argc, argv, i, j)
Definition xmlwf.c:948
static void XMLCALL metaStartCdataSection(void *userData)
Definition xmlwf.c:655
static void metaEndDocument(void *userData)
Definition xmlwf.c:581
static void XMLCALL metaEndCdataSection(void *userData)
Definition xmlwf.c:665
static void XMLCALL notationDecl(void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId)
Definition xmlwf.c:448
static void XMLCALL processingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
Definition xmlwf.c:292
static int xcscmp(const XML_Char *xs, const XML_Char *xt)
Definition xmlwf.c:356
static void XMLCALL defaultEndElement(void *userData, const XML_Char *name)
Definition xmlwf.c:511
static void XMLCALL metaCharacterData(void *userData, const XML_Char *s, int len)
Definition xmlwf.c:675
static void XMLCALL metaNotationDecl(void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId)
Definition xmlwf.c:712
static void XMLCALL metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
Definition xmlwf.c:788
static int attcmp(const void *att1, const void *att2)
Definition xmlwf.c:181
static void attributeValue(FILE *fp, const XML_Char *s)
Definition xmlwf.c:130
#define NSSEP
Definition xmlwf.c:92
static void XMLCALL metaEndElement(void *userData, const XML_Char *name)
Definition xmlwf.c:620
static void metaLocation(XML_Parser parser)
Definition xmlwf.c:560
static void XMLCALL nopEndElement(void *userData, const XML_Char *name)
Definition xmlwf.c:539
static void XMLCALL metaStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
Definition xmlwf.c:587
static void showVersion(XML_Char *prog)
Definition xmlwf.c:846
static void XMLCALL startDoctypeDecl(void *userData, const XML_Char *doctypeName, const XML_Char *sysid, const XML_Char *publid, int has_internal_subset)
Definition xmlwf.c:323
static void XMLCALL nopStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
Definition xmlwf.c:532
static int XMLCALL notStandalone(void *userData)
Definition xmlwf.c:840
static void XMLCALL nopProcessingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
Definition xmlwf.c:545
static void usage(const XML_Char *prog, int rc)
Definition xmlwf.c:879
static int nsattcmp(const void *p1, const void *p2)
Definition xmlwf.c:218
static int XMLCALL unknownEncodingConvert(void *data, const char *p)
Definition xmlwf.c:799
static void metaStartDocument(void *userData)
Definition xmlwf.c:575
static void XMLCALL startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
Definition xmlwf.c:229
static int notationCmp(const void *a, const void *b)
Definition xmlwf.c:373
static void XMLCALL metaComment(void *userData, const XML_Char *data)
Definition xmlwf.c:643
static int XMLCALL unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info)
Definition xmlwf.c:804
static void XMLCALL metaEntityDecl(void *userData, const XML_Char *entityName, int is_param, const XML_Char *value, int value_length, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName)
Definition xmlwf.c:732
static void freeNotations(XmlwfUserData *data)
Definition xmlwf.c:334