Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch expat-2.2.3 Excluding Merge-Ins
This is equivalent to a diff from 6c9e8589f1 to 84a004b5f0
2017-08-31
| ||
02:47 | Exploring optimization possibilities. Using doc specific simple mem pools speeds up a [dom parse $xml doc; $doc delete] by a factor of 1.25 (though, while DOM tree building is also slightly faster most of the gain is a much faster doc free). Test suite runs valgrind clean. Some tests fail but most of them do rightly so. Because this has a price: no subree move between documentes (the DOM recommendation doesn't allow this but tdom did, so far), no [domNode delete] (but this in fact freed the memory already only in non-threaded builds), no line/column information. Needs creation of nodeCmds in doc specific namespace for cleanup of the tcl commands in one go (to be implemented) and thread safety consideration. If all goes well and still looks as a gain could be integrated in a switch on/of at runtime way. check-in: 1965531605 user: rolf tags: fastFree | |
2017-08-29
| ||
21:05 | There are a lot expat releases, lately. This is expat-2.2.4. check-in: 631d353e34 user: rolf tags: expat-update | |
2017-08-25
| ||
14:28 | Changed version to 0.9.1. check-in: fa48078af4 user: rolf tags: trunk | |
2017-08-24
| ||
16:15 | Merged from trunk. Closed-Leaf check-in: 84a004b5f0 user: rolf tags: expat-2.2.3 | |
15:33 | Release 0.9.0 check-in: 6c9e8589f1 user: rolf tags: trunk, tdom-0-9-0, release | |
13:57 | Install also tdomConfig.sh. And since tdomConfig.sh is generated by configure, don't remove it with make clean but only with make distclean. Closed-Leaf check-in: 9ca8c82d0a user: rolf tags: prepare-release | |
2017-08-23
| ||
22:34 | Started updating of the included expat to 2.2.3. check-in: 4a425e9b4b user: rolf tags: expat-2.2.3 | |
2017-08-21
| ||
23:46 | Some more proof reading. check-in: 9f9b4577ac user: rolf tags: trunk | |
Changes to configure.
5494 5494 5495 5495 vars="-I${srcdir}/expat" 5496 5496 for i in $vars; do 5497 5497 PKG_INCLUDES="$PKG_INCLUDES $i" 5498 5498 done 5499 5499 5500 5500 5501 + 5502 +$as_echo "#define XML_POOR_ENTROPY 1" >>confdefs.h 5503 + 5501 5504 else 5502 5505 { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using shared expat found in ${ac_cv_c_expat}" >&5 5503 5506 $as_echo "Using shared expat found in ${ac_cv_c_expat}" >&6; } 5504 5507 5505 5508 vars="-I${ac_cv_c_expat}/include" 5506 5509 for i in $vars; do 5507 5510 PKG_INCLUDES="$PKG_INCLUDES $i"
Changes to expat/COPYING.
1 1 Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper 2 -Copyright (c) 2001-2016 Expat maintainers 2 +Copyright (c) 2001-2017 Expat maintainers 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining 5 5 a copy of this software and associated documentation files (the 6 6 "Software"), to deal in the Software without restriction, including 7 7 without limitation the rights to use, copy, modify, merge, publish, 8 8 distribute, sublicense, and/or sell copies of the Software, and to 9 9 permit persons to whom the Software is furnished to do so, subject to
Changes to expat/Changes.
1 +NOTE: We are looking for help with a few things: 2 + https://github.com/libexpat/libexpat/labels/help%20wanted 3 + If you can help, please get in touch. Thanks! 4 + 5 +Release 2.2.3 Wed August 2 2017 6 + Security fixes: 7 + #82 CVE-2017-11742 -- Windows: Fix DLL hijacking vulnerability 8 + using Steve Holme's LoadLibrary wrapper for/of cURL 9 + 10 + Bug fixes: 11 + #85 Fix a dangling pointer issue related to realloc 12 + 13 + Other changes: 14 + Increase code coverage 15 + #91 Linux: Allow getrandom to fail if nonblocking pool has not 16 + yet been initialized and read /dev/urandom then, instead. 17 + This is in line with what recent Python does. 18 + #81 Pre-10.7/Lion macOS: Support entropy from arc4random 19 + #86 Check that a UTF-16 encoding in an XML declaration has the 20 + right endianness 21 + #4 #5 #7 Recover correctly when some reallocations fail 22 + Repair "./configure && make" for systems without any 23 + provider of high quality entropy 24 + and try reading /dev/urandom on those 25 + Ensure that user-defined character encodings have converter 26 + functions when they are needed 27 + Fix mis-leading description of argument -c in xmlwf.1 28 + Rely on macro HAVE_ARC4RANDOM_BUF (rather than __CloudABI__) 29 + for CloudABI 30 + #100 Fix use of SIPHASH_MAIN in siphash.h 31 + #23 Test suite: Fix memory leaks 32 + Version info bumped from 7:4:6 to 7:5:6 33 + 34 + Special thanks to: 35 + Chanho Park 36 + Joe Orton 37 + Pascal Cuoq 38 + Rhodri James 39 + Simon McVittie 40 + Vadim Zeitlin 41 + Viktor Szakats 42 + and 43 + Core Infrastructure Initiative 44 + 45 +Release 2.2.2 Wed July 12 2017 46 + Security fixes: 47 + #43 Protect against compilation without any source of high 48 + quality entropy enabled, e.g. with CMake build system; 49 + commit ff0207e6076e9828e536b8d9cd45c9c92069b895 50 + #60 Windows with _UNICODE: 51 + Unintended use of LoadLibraryW with a non-wide string 52 + resulted in failure to load advapi32.dll and degradation 53 + in quality of used entropy when compiled with _UNICODE for 54 + Windows; you can launch existing binaries with 55 + EXPAT_ENTROPY_DEBUG=1 in the environment to inspect the 56 + quality of entropy used during runtime; commits 57 + * 95b95032f907ef1cd17ee7a9a1768010a825d61d 58 + * 73a5a2e9c081f49f2d775cf7ced864158b68dc80 59 + [MOX-006] Fix non-NULL parser parameter validation in XML_Parse; 60 + resulted in NULL dereference, previously; 61 + commit ac256dafdffc9622ab0dc2c62fcecb0dfcfa71fe 62 + 63 + Bug fixes: 64 + #69 Fix improper use of unsigned long long integer literals 65 + 66 + Other changes: 67 + #73 Start requiring a C99 compiler 68 + #49 Fix "==" Bashism in configure script 69 + #50 Fix too eager getrandom detection for Debian GNU/kFreeBSD 70 + #52 and macOS 71 + #51 Address lack of stdint.h in Visual Studio 2003 to 2008 72 + #58 Address compile warnings 73 + #68 Fix "./buildconf.sh && ./configure" for some versions 74 + of Dash for /bin/sh 75 + #72 CMake: Ease use of Expat in context of a parent project 76 + with multipe CMakeLists.txt files 77 + #72 CMake: Resolve mistaken executable permissions 78 + #76 Address compile warning with -DNDEBUG (not recommended!) 79 + #77 Address compile warning about macro redefinition 80 + 81 + Special thanks to: 82 + Alexander Bluhm 83 + Ben Boeckel 84 + Cătălin Răceanu 85 + Kerin Millar 86 + László Böszörményi 87 + S. P. Zeidler 88 + Segev Finer 89 + Václav Slavík 90 + Victor Stinner 91 + Viktor Szakats 92 + and 93 + Radically Open Security 94 + 95 +Release 2.2.1 Sat June 17 2017 96 + Security fixes: 97 + CVE-2017-9233 -- External entity infinite loop DoS 98 + Details: https://libexpat.github.io/doc/cve-2017-9233/ 99 + Commit c4bf96bb51dd2a1b0e185374362ee136fe2c9d7f 100 + [MOX-002] CVE-2016-9063 -- Detect integer overflow; commit 101 + d4f735b88d9932bd5039df2335eefdd0723dbe20 102 + (Fixed version of existing downstream patches!) 103 + (SF.net) #539 Fix regression from fix to CVE-2016-0718 cutting off 104 + longer tag names; commits 105 + * 896b6c1fd3b842f377d1b62135dccf0a579cf65d 106 + * af507cef2c93cb8d40062a0abe43a4f4e9158fb2 107 + #16 * 0dbbf43fdb20f593ddf4fa1ff67288000dd4a7fd 108 + #25 More integer overflow detection (function poolGrow); commits 109 + * 810b74e4703dcfdd8f404e3cb177d44684775143 110 + * 44178553f3539ce69d34abee77a05e879a7982ac 111 + [MOX-002] Detect overflow from len=INT_MAX call to XML_Parse; commits 112 + * 4be2cb5afcc018d996f34bbbce6374b7befad47f 113 + * 7e5b71b748491b6e459e5c9a1d090820f94544d8 114 + [MOX-005] #30 Use high quality entropy for hash initialization: 115 + * arc4random_buf on BSD, systems with libbsd 116 + (when configured with --with-libbsd), CloudABI 117 + * RtlGenRandom on Windows XP / Server 2003 and later 118 + * getrandom on Linux 3.17+ 119 + In a way, that's still part of CVE-2016-5300. 120 + https://github.com/libexpat/libexpat/pull/30/commits 121 + [MOX-005] For the low quality entropy extraction fallback code, 122 + the parser instance address can no longer leak, commit 123 + 04ad658bd3079dd15cb60fc67087900f0ff4b083 124 + [MOX-003] Prevent use of uninitialised variable; commit 125 + [MOX-004] a4dc944f37b664a3ca7199c624a98ee37babdb4b 126 + Add missing parameter validation to public API functions 127 + and dedicated error code XML_ERROR_INVALID_ARGUMENT: 128 + [MOX-006] * NULL checks; commits 129 + * d37f74b2b7149a3a95a680c4c4cd2a451a51d60a (merge/many) 130 + * 9ed727064b675b7180c98cb3d4f75efba6966681 131 + * 6a747c837c50114dfa413994e07c0ba477be4534 132 + * Negative length (XML_Parse); commit 133 + [MOX-002] 70db8d2538a10f4c022655d6895e4c3e78692e7f 134 + [MOX-001] #35 Change hash algorithm to William Ahern's version of SipHash 135 + to go further with fixing CVE-2012-0876. 136 + https://github.com/libexpat/libexpat/pull/39/commits 137 + 138 + Bug fixes: 139 + #32 Fix sharing of hash salt across parsers; 140 + relevant where XML_ExternalEntityParserCreate is called 141 + prior to XML_Parse, in particular (e.g. FBReader) 142 + #28 xmlwf: Auto-disable use of memory-mapping (and parsing 143 + as a single chunk) for files larger than ~1 GB (2^30 bytes) 144 + rather than failing with error "out of memory" 145 + #3 Fix double free after malloc failure in DTD code; commit 146 + 7ae9c3d3af433cd4defe95234eae7dc8ed15637f 147 + #17 Fix memory leak on parser error for unbound XML attribute 148 + prefix with new namespaces defined in the same tag; 149 + found by Google's OSS-Fuzz; commits 150 + * 16f87daae5a16132e479e4f71862128c7a915c73 151 + * b47dbc9745932c160893d433220e462bd605f8cd 152 + xmlwf on Windows: Add missing calls to CloseHandle 153 + 154 + New features: 155 + #30 Introduced environment switch EXPAT_ENTROPY_DEBUG=1 156 + for runtime debugging of entropy extraction 157 + 158 + Other changes: 159 + Increase code coverage 160 + #33 Reject use of XML_UNICODE_WCHAR_T with sizeof(wchar_t) != 2; 161 + XML_UNICODE_WCHAR_T was never meant to be used outside 162 + of Windows; 4-byte wchar_t is common on Linux 163 + (SF.net) #538 Start using -fno-strict-aliasing 164 + (SF.net) #540 Support compilation against cloudlibc of CloudABI 165 + Allow MinGW cross-compilation 166 + (SF.net) #534 CMake: Introduce option "BUILD_doc" (enabled by default) 167 + to bypass compilation of the xmlwf.1 man page 168 + (SF.net) pr2 CMake: Introduce option "INSTALL" (enabled by default) 169 + to bypass installation of expat files 170 + CMake: Fix ninja support 171 + Autotools: Add parameters --enable-xml-context [COUNT] 172 + and --disable-xml-context; default of context of 1024 173 + bytes enabled unchanged 174 + #14 Drop AmigaOS 4.x code and includes 175 + #14 Drop ancient build systems: 176 + * Borland C++ Builder 177 + * OpenVMS 178 + * Open Watcom 179 + * Visual Studio 6.0 180 + * Pre-X Mac OS (MPW Makefile) 181 + If you happen to rely on some of these, please get in 182 + touch for joining with maintenance. 183 + #10 Move from WIN32 to _WIN32 184 + #13 Fix "make run-xmltest" order instability 185 + Address compile warnings 186 + Bump version info from 7:2:6 to 7:3:6 187 + Add AUTHORS file 188 + 189 + Infrastructure: 190 + #1 Migrate from SourceForge to GitHub (except downloads): 191 + https://github.com/libexpat/ 192 + #1 Re-create http://libexpat.org/ project website 193 + Start utilizing Travis CI 194 + 195 + Special thanks to: 196 + Andy Wang 197 + Don Lewis 198 + Ed Schouten 199 + Karl Waclawek 200 + Pascal Cuoq 201 + Rhodri James 202 + Sergei Nikulov 203 + Tobias Taschner 204 + Viktor Szakats 205 + and 206 + Core Infrastructure Initiative 207 + Mozilla Foundation (MOSS Track 3: Secure Open Source) 208 + Radically Open Security 209 + 1 210 Release 2.2.0 Tue June 21 2016 2 211 Security fixes: 3 212 #537 CVE-2016-0718 -- Fix crash on malformed input 4 213 CVE-2016-4472 -- Improve insufficient fix to CVE-2015-1283 / 5 214 CVE-2015-2716 introduced with Expat 2.1.1 6 215 #499 CVE-2016-5300 -- Use more entropy for hash initialization 7 216 than the original fix to CVE-2012-0876 ................................................................................ 59 268 Other changes: 60 269 #503: Document behavior of calling XML_SetHashSalt with salt 0 61 270 Minor improvements to man page xmlwf(1) 62 271 Improvements to the experimental CMake build system 63 272 libtool now invoked with --verbose 64 273 65 274 Release 2.1.0 Sat March 24 2012 275 + - Security fixes: 276 + #2958794: CVE-2012-1148 - Memory leak in poolGrow. 277 + #2895533: CVE-2012-1147 - Resource leak in readfilemap.c. 278 + #3496608: CVE-2012-0876 - Hash DOS attack. 279 + #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8(). 280 + #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences. 66 281 - Bug Fixes: 67 282 #1742315: Harmful XML_ParserCreateNS suggestion. 68 - #2895533: CVE-2012-1147 - Resource leak in readfilemap.c. 69 283 #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3. 70 284 #1983953, 2517952, 2517962, 2649838: 71 285 Build modifications using autoreconf instead of buildconf.sh. 72 286 #2815947, #2884086: OBJEXT and EXEEXT support while building. 73 - #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences. 74 287 #2517938: xmlwf should return non-zero exit status if not well-formed. 75 288 #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml. 76 289 #2855609: Dangling positionPtr after error. 77 - #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8(). 78 - #2958794: CVE-2012-1148 - Memory leak in poolGrow. 79 290 #2990652: CMake support. 80 291 #3010819: UNEXPECTED_STATE with a trailing "%" in entity value. 81 292 #3206497: Unitialized memory returned from XML_Parse. 82 293 #3287849: make check fails on mingw-w64. 83 - #3496608: CVE-2012-0876 - Hash DOS attack. 84 294 - Patches: 85 295 #1749198: pkg-config support. 86 296 #3010222: Fix for bug #3010819. 87 297 #3312568: CMake support. 88 298 #3446384: Report byte offsets for attr names and values. 89 299 - New Features / API changes: 90 300 Added new API member XML_SetHashSalt() that allows setting an initial
Changes to expat/VERSION.
1 -expat-2.2.0 1 +expat-2.2.3
Changes to expat/expat.h.
20 20 #ifdef __cplusplus 21 21 extern "C" { 22 22 #endif 23 23 24 24 struct XML_ParserStruct; 25 25 typedef struct XML_ParserStruct *XML_Parser; 26 26 27 -/* Should this be defined using stdbool.h when C99 is available? */ 28 27 typedef unsigned char XML_Bool; 29 28 #define XML_TRUE ((XML_Bool) 1) 30 29 #define XML_FALSE ((XML_Bool) 0) 31 30 32 31 /* The XML_Status enum gives the possible return values for several 33 32 API functions. The preprocessor #defines are included so this 34 33 stanza can be added to code that still needs to support older ................................................................................ 91 90 XML_ERROR_NOT_SUSPENDED, 92 91 XML_ERROR_ABORTED, 93 92 XML_ERROR_FINISHED, 94 93 XML_ERROR_SUSPEND_PE, 95 94 /* Added in 2.0. */ 96 95 XML_ERROR_RESERVED_PREFIX_XML, 97 96 XML_ERROR_RESERVED_PREFIX_XMLNS, 98 - XML_ERROR_RESERVED_NAMESPACE_URI 97 + XML_ERROR_RESERVED_NAMESPACE_URI, 98 + /* Added in 2.2.1. */ 99 + XML_ERROR_INVALID_ARGUMENT 99 100 }; 100 101 101 102 enum XML_Content_Type { 102 103 XML_CTYPE_EMPTY = 1, 103 104 XML_CTYPE_ANY, 104 105 XML_CTYPE_MIXED, 105 106 XML_CTYPE_NAME, ................................................................................ 702 703 have no effect after that. Returns 703 704 XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. 704 705 Note: If the document does not have a DOCTYPE declaration at all, 705 706 then startDoctypeDeclHandler and endDoctypeDeclHandler will not 706 707 be called, despite an external subset being parsed. 707 708 Note: If XML_DTD is not defined when Expat is compiled, returns 708 709 XML_ERROR_FEATURE_REQUIRES_XML_DTD. 710 + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. 709 711 */ 710 712 XMLPARSEAPI(enum XML_Error) 711 713 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); 712 714 713 715 714 716 /* Sets the base to be used for resolving relative URIs in system 715 717 identifiers in declarations. Resolving relative identifiers is ................................................................................ 725 727 XMLPARSEAPI(const XML_Char *) 726 728 XML_GetBase(XML_Parser parser); 727 729 728 730 /* Returns the number of the attribute/value pairs passed in last call 729 731 to the XML_StartElementHandler that were specified in the start-tag 730 732 rather than defaulted. Each attribute/value pair counts as 2; thus 731 733 this correspondds to an index into the atts array passed to the 732 - XML_StartElementHandler. 734 + XML_StartElementHandler. Returns -1 if parser == NULL. 733 735 */ 734 736 XMLPARSEAPI(int) 735 737 XML_GetSpecifiedAttributeCount(XML_Parser parser); 736 738 737 739 /* Returns the index of the ID attribute passed in the last call to 738 - XML_StartElementHandler, or -1 if there is no ID attribute. Each 739 - attribute/value pair counts as 2; thus this correspondds to an 740 - index into the atts array passed to the XML_StartElementHandler. 740 + XML_StartElementHandler, or -1 if there is no ID attribute or 741 + parser == NULL. Each attribute/value pair counts as 2; thus this 742 + correspondds to an index into the atts array passed to the 743 + XML_StartElementHandler. 741 744 */ 742 745 XMLPARSEAPI(int) 743 746 XML_GetIdAttributeIndex(XML_Parser parser); 744 747 745 748 #ifdef XML_ATTR_INFO 746 749 /* Source file byte offsets for the start and end of attribute names and values. 747 750 The value indices are exclusive of surrounding quotes; thus in a UTF-8 source ................................................................................ 897 900 XML_ParserFree has been called on the newly created parser. 898 901 If the library has been compiled without support for parameter 899 902 entity parsing (ie without XML_DTD being defined), then 900 903 XML_SetParamEntityParsing will return 0 if parsing of parameter 901 904 entities is requested; otherwise it will return non-zero. 902 905 Note: If XML_SetParamEntityParsing is called after XML_Parse or 903 906 XML_ParseBuffer, then it has no effect and will always return 0. 907 + Note: If parser == NULL, the function will do nothing and return 0. 904 908 */ 905 909 XMLPARSEAPI(int) 906 910 XML_SetParamEntityParsing(XML_Parser parser, 907 911 enum XML_ParamEntityParsing parsing); 908 912 909 913 /* Sets the hash salt to use for internal hash calculations. 910 914 Helps in preventing DoS attacks based on predicting hash 911 915 function behavior. This must be called before parsing is started. 912 916 Returns 1 if successful, 0 when called after parsing has started. 917 + Note: If parser == NULL, the function will do nothing and return 0. 913 918 */ 914 919 XMLPARSEAPI(int) 915 920 XML_SetHashSalt(XML_Parser parser, 916 921 unsigned long hash_salt); 917 922 918 923 /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then 919 924 XML_GetErrorCode returns information about the error. ................................................................................ 932 937 event (regardless of whether there was an associated callback). 933 938 934 939 They may also be called after returning from a call to XML_Parse 935 940 or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then 936 941 the location is the location of the character at which the error 937 942 was detected; otherwise the location is the location of the last 938 943 parse event, as described above. 944 + 945 + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber 946 + return 0 to indicate an error. 947 + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. 939 948 */ 940 949 XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); 941 950 XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); 942 951 XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); 943 952 944 953 /* Return the number of bytes in the current event. 945 954 Returns 0 if the event is in an internal entity. ................................................................................ 1035 1044 1036 1045 1037 1046 /* Expat follows the semantic versioning convention. 1038 1047 See http://semver.org. 1039 1048 */ 1040 1049 #define XML_MAJOR_VERSION 2 1041 1050 #define XML_MINOR_VERSION 2 1042 -#define XML_MICRO_VERSION 0 1051 +#define XML_MICRO_VERSION 3 1043 1052 1044 1053 #ifdef __cplusplus 1045 1054 } 1046 1055 #endif 1047 1056 1048 1057 #endif /* not Expat_INCLUDED */
Changes to expat/expat_external.h.
89 89 #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL 90 90 91 91 #ifdef __cplusplus 92 92 extern "C" { 93 93 #endif 94 94 95 95 #ifdef XML_UNICODE_WCHAR_T 96 -#define XML_UNICODE 96 +# define XML_UNICODE 97 +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) 98 +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" 99 +# endif 97 100 #endif 98 101 99 102 #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ 100 103 #ifdef XML_UNICODE_WCHAR_T 101 104 typedef wchar_t XML_Char; 102 105 typedef wchar_t XML_LChar; 103 106 #else
Changes to expat/winconfig.h.
12 12 13 13 #define WIN32_LEAN_AND_MEAN 14 14 #include <windows.h> 15 15 #undef WIN32_LEAN_AND_MEAN 16 16 17 17 #include <memory.h> 18 18 #include <string.h> 19 + 20 + 21 +#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ 22 +# include <expat_config.h> 23 +#else /* !defined(HAVE_EXPAT_CONFIG_H) */ 24 + 19 25 20 26 #define XML_NS 1 21 27 #define XML_DTD 1 22 28 #define XML_CONTEXT_BYTES 1024 23 29 24 30 /* we will assume all Windows platforms are little endian */ 25 31 #define BYTEORDER 1234 32 + 33 +/* Windows has memmove() available. */ 34 +#define HAVE_MEMMOVE 35 + 36 + 37 +#endif /* !defined(HAVE_EXPAT_CONFIG_H) */ 38 + 26 39 27 40 #endif /* ndef WINCONFIG_H */
Changes to expat/xmlparse.c.
1 1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd 2 2 See the file COPYING for copying permission. 3 + 4 + 101bfd65d1ff3d1511cf6671e6aae65f82cd97df6f4da137d46d510731830ad9 (2.2.3+) 3 5 */ 6 + 7 +#if !defined(_GNU_SOURCE) 8 +# define _GNU_SOURCE 1 /* syscall prototype */ 9 +#endif 4 10 5 11 #include <stddef.h> 6 12 #include <string.h> /* memset(), memcpy() */ 7 13 #include <assert.h> 8 14 #include <limits.h> /* UINT_MAX */ 15 +#include <stdio.h> /* fprintf */ 16 +#include <stdlib.h> /* getenv */ 9 17 10 -#ifdef WIN32 18 +#ifdef _WIN32 11 19 #define getpid GetCurrentProcessId 12 20 #else 13 21 #include <sys/time.h> /* gettimeofday() */ 14 22 #include <sys/types.h> /* getpid() */ 15 23 #include <unistd.h> /* getpid() */ 24 +#include <fcntl.h> /* O_RDONLY */ 25 +#include <errno.h> 16 26 #endif 17 27 18 28 #define XML_BUILDING_EXPAT 1 19 29 20 -#ifdef WIN32 30 +#ifdef _WIN32 21 31 #include "winconfig.h" 22 -#elif defined(MACOS_CLASSIC) 23 -#include "macconfig.h" 24 -#elif defined(__amigaos__) 25 -#include "amigaconfig.h" 26 -#elif defined(__WATCOMC__) 27 -#include "watcomconfig.h" 28 32 #elif defined(HAVE_EXPAT_CONFIG_H) 29 33 #include <expat_config.h> 30 -#endif /* ndef WIN32 */ 34 +#endif /* ndef _WIN32 */ 31 35 32 36 #include "ascii.h" 33 37 #include "expat.h" 38 +#include "siphash.h" 39 + 40 +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 41 +# if defined(HAVE_GETRANDOM) 42 +# include <sys/random.h> /* getrandom */ 43 +# else 44 +# include <unistd.h> /* syscall */ 45 +# include <sys/syscall.h> /* SYS_getrandom */ 46 +# endif 47 +# if ! defined(GRND_NONBLOCK) 48 +# define GRND_NONBLOCK 0x0001 49 +# endif /* defined(GRND_NONBLOCK) */ 50 +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 51 + 52 +#if defined(HAVE_LIBBSD) \ 53 + && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) 54 +# include <bsd/stdlib.h> 55 +#endif 56 + 57 +#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) 58 +# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 59 +#endif 60 + 61 +#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \ 62 + && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \ 63 + && !defined(XML_DEV_URANDOM) \ 64 + && !defined(_WIN32) \ 65 + && !defined(XML_POOR_ENTROPY) 66 +# error \ 67 + You do not have support for any sources of high quality entropy \ 68 + enabled. For end user security, that is probably not what you want. \ 69 + \ 70 + Your options include: \ 71 + * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ 72 + * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ 73 + * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ 74 + * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \ 75 + * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ 76 + * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ 77 + * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ 78 + * Windows (RtlGenRandom): _WIN32. \ 79 + \ 80 + If insist on not using any of these, bypass this error by defining \ 81 + XML_POOR_ENTROPY; you have been warned. \ 82 + \ 83 + For CMake, one way to pass the define is: \ 84 + cmake -DCMAKE_C_FLAGS="-pipe -O2 -DHAVE_SYSCALL_GETRANDOM" . \ 85 + \ 86 + If you have reasons to patch this detection code away or need changes \ 87 + to the build system, please open a bug. Thank you! 88 +#endif 89 + 34 90 35 91 #ifdef XML_UNICODE 36 92 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 37 93 #define XmlConvert XmlUtf16Convert 38 94 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 39 95 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 40 96 #define XmlEncode XmlUtf16Encode ................................................................................ 105 161 NAMED **v; 106 162 unsigned char power; 107 163 size_t size; 108 164 size_t used; 109 165 const XML_Memory_Handling_Suite *mem; 110 166 } HASH_TABLE; 111 167 112 -/* Basic character hash algorithm, taken from Python's string hash: 113 - h = h * 1000003 ^ character, the constant being a prime number. 168 +static size_t 169 +keylen(KEY s); 114 170 115 -*/ 116 -#ifdef XML_UNICODE 117 -#define CHAR_HASH(h, c) \ 118 - (((h) * 0xF4243) ^ (unsigned short)(c)) 119 -#else 120 -#define CHAR_HASH(h, c) \ 121 - (((h) * 0xF4243) ^ (unsigned char)(c)) 122 -#endif 171 +static void 172 +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); 123 173 124 174 /* For probing (after a collision) we need a step size relative prime 125 175 to the hash table size, which is a power of 2. We use double-hashing, 126 176 since we can calculate a second hash value cheaply by taking those bits 127 177 of the first hash value that were discarded (masked out) when the table 128 178 index was calculated: index = hash & mask, where mask = table->size - 1. 129 179 We limit the maximum step size to table->size / 4 (mask >> 2) and make ................................................................................ 351 401 const char *end, const char **nextPtr, XML_Bool haveMore); 352 402 #ifdef XML_DTD 353 403 static enum XML_Error 354 404 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, 355 405 const char *end, const char **nextPtr, XML_Bool haveMore); 356 406 #endif /* XML_DTD */ 357 407 408 +static void 409 +freeBindings(XML_Parser parser, BINDING *bindings); 358 410 static enum XML_Error 359 411 storeAtts(XML_Parser parser, const ENCODING *, const char *s, 360 412 TAG_NAME *tagNamePtr, BINDING **bindingsPtr); 361 413 static enum XML_Error 362 414 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 363 415 const XML_Char *uri, BINDING **bindingsPtr); 364 416 static int ................................................................................ 435 487 436 488 static int FASTCALL nextScaffoldPart(XML_Parser parser); 437 489 static XML_Content * build_model(XML_Parser parser); 438 490 static ELEMENT_TYPE * 439 491 getElementType(XML_Parser parser, const ENCODING *enc, 440 492 const char *ptr, const char *end); 441 493 494 +static XML_Char *copyString(const XML_Char *s, 495 + const XML_Memory_Handling_Suite *memsuite); 496 + 442 497 static unsigned long generate_hash_secret_salt(XML_Parser parser); 443 498 static XML_Bool startParsing(XML_Parser parser); 444 499 445 500 static XML_Parser 446 501 parserCreate(const XML_Char *encodingName, 447 502 const XML_Memory_Handling_Suite *memsuite, 448 503 const XML_Char *nameSep, ................................................................................ 693 748 ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 694 749 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, 695 750 ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, 696 751 ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, 697 752 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' 698 753 }; 699 754 755 + 756 +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 757 + 758 +/* Obtain entropy on Linux 3.17+ */ 759 +static int 760 +writeRandomBytes_getrandom_nonblock(void * target, size_t count) { 761 + int success = 0; /* full count bytes written? */ 762 + size_t bytesWrittenTotal = 0; 763 + const unsigned int getrandomFlags = GRND_NONBLOCK; 764 + 765 + do { 766 + void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); 767 + const size_t bytesToWrite = count - bytesWrittenTotal; 768 + 769 + const int bytesWrittenMore = 770 +#if defined(HAVE_GETRANDOM) 771 + getrandom(currentTarget, bytesToWrite, getrandomFlags); 772 +#else 773 + syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); 774 +#endif 775 + 776 + if (bytesWrittenMore > 0) { 777 + bytesWrittenTotal += bytesWrittenMore; 778 + if (bytesWrittenTotal >= count) 779 + success = 1; 780 + } 781 + } while (! success && (errno == EINTR)); 782 + 783 + return success; 784 +} 785 + 786 +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 787 + 788 + 789 +#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 790 + 791 +/* Extract entropy from /dev/urandom */ 792 +static int 793 +writeRandomBytes_dev_urandom(void * target, size_t count) { 794 + int success = 0; /* full count bytes written? */ 795 + size_t bytesWrittenTotal = 0; 796 + 797 + const int fd = open("/dev/urandom", O_RDONLY); 798 + if (fd < 0) { 799 + return 0; 800 + } 801 + 802 + do { 803 + void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); 804 + const size_t bytesToWrite = count - bytesWrittenTotal; 805 + 806 + const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); 807 + 808 + if (bytesWrittenMore > 0) { 809 + bytesWrittenTotal += bytesWrittenMore; 810 + if (bytesWrittenTotal >= count) 811 + success = 1; 812 + } 813 + } while (! success && (errno == EINTR)); 814 + 815 + close(fd); 816 + return success; 817 +} 818 + 819 +#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 820 + 821 + 822 +#if defined(HAVE_ARC4RANDOM) 823 + 824 +static void 825 +writeRandomBytes_arc4random(void * target, size_t count) { 826 + size_t bytesWrittenTotal = 0; 827 + 828 + while (bytesWrittenTotal < count) { 829 + const uint32_t random32 = arc4random(); 830 + size_t i = 0; 831 + 832 + for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); 833 + i++, bytesWrittenTotal++) { 834 + const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); 835 + ((uint8_t *)target)[bytesWrittenTotal] = random8; 836 + } 837 + } 838 +} 839 + 840 +#endif /* defined(HAVE_ARC4RANDOM) */ 841 + 842 + 843 +#ifdef _WIN32 844 + 845 +typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); 846 +HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */ 847 + 848 +/* Obtain entropy on Windows XP / Windows Server 2003 and later. 849 + * Hint on RtlGenRandom and the following article from libsodium. 850 + * 851 + * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI 852 + * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ 853 + */ 854 +static int 855 +writeRandomBytes_RtlGenRandom(void * target, size_t count) { 856 + int success = 0; /* full count bytes written? */ 857 + const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL")); 858 + 859 + if (advapi32) { 860 + const RTLGENRANDOM_FUNC RtlGenRandom 861 + = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); 862 + if (RtlGenRandom) { 863 + if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { 864 + success = 1; 865 + } 866 + } 867 + FreeLibrary(advapi32); 868 + } 869 + 870 + return success; 871 +} 872 + 873 +#endif /* _WIN32 */ 874 + 875 + 876 +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) 877 + 700 878 static unsigned long 701 879 gather_time_entropy(void) 702 880 { 703 -#ifdef WIN32 881 +#ifdef _WIN32 704 882 FILETIME ft; 705 883 GetSystemTimeAsFileTime(&ft); /* never fails */ 706 884 return ft.dwHighDateTime ^ ft.dwLowDateTime; 707 885 #else 708 886 struct timeval tv; 709 887 int gettimeofday_res; 710 888 711 889 gettimeofday_res = gettimeofday(&tv, NULL); 890 + 891 +#if defined(NDEBUG) 892 + (void)gettimeofday_res; 893 +#else 712 894 assert (gettimeofday_res == 0); 895 +#endif /* defined(NDEBUG) */ 713 896 714 897 /* Microseconds time is <20 bits entropy */ 715 898 return tv.tv_usec; 716 899 #endif 717 900 } 901 + 902 +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 903 + 904 + 905 +static unsigned long 906 +ENTROPY_DEBUG(const char * label, unsigned long entropy) { 907 + const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); 908 + if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { 909 + fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", 910 + label, 911 + (int)sizeof(entropy) * 2, entropy, 912 + (unsigned long)sizeof(entropy)); 913 + } 914 + return entropy; 915 +} 718 916 719 917 static unsigned long 720 918 generate_hash_secret_salt(XML_Parser parser) 721 919 { 722 - /* Process ID is 0 bits entropy if attacker has local access 723 - * XML_Parser address is few bits of entropy if attacker has local access */ 724 - const unsigned long entropy = 725 - gather_time_entropy() ^ getpid() ^ (unsigned long)parser; 920 + unsigned long entropy; 921 + (void)parser; 922 +#if defined(HAVE_ARC4RANDOM_BUF) 923 + arc4random_buf(&entropy, sizeof(entropy)); 924 + return ENTROPY_DEBUG("arc4random_buf", entropy); 925 +#elif defined(HAVE_ARC4RANDOM) 926 + writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); 927 + return ENTROPY_DEBUG("arc4random", entropy); 928 +#else 929 + /* Try high quality providers first .. */ 930 +#ifdef _WIN32 931 + if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { 932 + return ENTROPY_DEBUG("RtlGenRandom", entropy); 933 + } 934 +#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 935 + if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { 936 + return ENTROPY_DEBUG("getrandom", entropy); 937 + } 938 +#endif 939 +#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 940 + if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { 941 + return ENTROPY_DEBUG("/dev/urandom", entropy); 942 + } 943 +#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 944 + /* .. and self-made low quality for backup: */ 945 + 946 + /* Process ID is 0 bits entropy if attacker has local access */ 947 + entropy = gather_time_entropy() ^ getpid(); 726 948 727 949 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ 728 950 if (sizeof(unsigned long) == 4) { 729 - return entropy * 2147483647; 951 + return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); 730 952 } else { 731 - return entropy * (unsigned long)2305843009213693951; 953 + return ENTROPY_DEBUG("fallback(8)", 954 + entropy * (unsigned long)2305843009213693951ULL); 732 955 } 956 +#endif 957 +} 958 + 959 +static unsigned long 960 +get_hash_secret_salt(XML_Parser parser) { 961 + if (parser->m_parentParser != NULL) 962 + return get_hash_secret_salt(parser->m_parentParser); 963 + return parser->m_hash_secret_salt; 733 964 } 734 965 735 966 static XML_Bool /* only valid for root parser */ 736 967 startParsing(XML_Parser parser) 737 968 { 738 969 /* hash functions must be initialized before setContext() is called */ 739 970 if (hash_secret_salt == 0) ................................................................................ 844 1075 namespaceSeparator = ASCII_EXCL; 845 1076 ns = XML_FALSE; 846 1077 ns_triplets = XML_FALSE; 847 1078 848 1079 nsAtts = NULL; 849 1080 nsAttsVersion = 0; 850 1081 nsAttsPower = 0; 1082 + 1083 + protocolEncodingName = NULL; 851 1084 852 1085 poolInit(&tempPool, &(parser->m_mem)); 853 1086 poolInit(&temp2Pool, &(parser->m_mem)); 854 1087 parserInit(parser, encodingName); 855 1088 856 1089 if (encodingName && !protocolEncodingName) { 857 1090 XML_ParserFree(parser); ................................................................................ 871 1104 } 872 1105 873 1106 static void 874 1107 parserInit(XML_Parser parser, const XML_Char *encodingName) 875 1108 { 876 1109 processor = prologInitProcessor; 877 1110 XmlPrologStateInit(&prologState); 878 - protocolEncodingName = (encodingName != NULL 879 - ? poolCopyString(&tempPool, encodingName) 880 - : NULL); 1111 + if (encodingName != NULL) { 1112 + protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 1113 + } 881 1114 curBase = NULL; 882 1115 XmlInitEncoding(&initEncoding, &encoding, 0); 883 1116 userData = NULL; 884 1117 handlerArg = NULL; 885 1118 startElementHandler = NULL; 886 1119 endElementHandler = NULL; 887 1120 characterDataHandler = NULL; ................................................................................ 956 1189 } 957 1190 958 1191 XML_Bool XMLCALL 959 1192 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) 960 1193 { 961 1194 TAG *tStk; 962 1195 OPEN_INTERNAL_ENTITY *openEntityList; 1196 + 1197 + if (parser == NULL) 1198 + return XML_FALSE; 1199 + 963 1200 if (parentParser) 964 1201 return XML_FALSE; 965 1202 /* move tagStack to freeTagList */ 966 1203 tStk = tagStack; 967 1204 while (tStk) { 968 1205 TAG *tag = tStk; 969 1206 tStk = tStk->parent; ................................................................................ 982 1219 } 983 1220 moveToFreeBindingList(parser, inheritedBindings); 984 1221 FREE(unknownEncodingMem); 985 1222 if (unknownEncodingRelease) 986 1223 unknownEncodingRelease(unknownEncodingData); 987 1224 poolClear(&tempPool); 988 1225 poolClear(&temp2Pool); 1226 + FREE((void *)protocolEncodingName); 1227 + protocolEncodingName = NULL; 989 1228 parserInit(parser, encodingName); 990 1229 dtdReset(_dtd, &parser->m_mem); 991 1230 return XML_TRUE; 992 1231 } 993 1232 994 1233 enum XML_Status XMLCALL 995 1234 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) 996 1235 { 1236 + if (parser == NULL) 1237 + return XML_STATUS_ERROR; 997 1238 /* Block after XML_Parse()/XML_ParseBuffer() has been called. 998 1239 XXX There's no way for the caller to determine which of the 999 1240 XXX possible error cases caused the XML_STATUS_ERROR return. 1000 1241 */ 1001 1242 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 1002 1243 return XML_STATUS_ERROR; 1244 + 1245 + /* Get rid of any previous encoding name */ 1246 + FREE((void *)protocolEncodingName); 1247 + 1003 1248 if (encodingName == NULL) 1249 + /* No new encoding name */ 1004 1250 protocolEncodingName = NULL; 1005 1251 else { 1006 - protocolEncodingName = poolCopyString(&tempPool, encodingName); 1252 + /* Copy the new encoding name into allocated memory */ 1253 + protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 1007 1254 if (!protocolEncodingName) 1008 1255 return XML_STATUS_ERROR; 1009 1256 } 1010 1257 return XML_STATUS_OK; 1011 1258 } 1012 1259 1013 1260 XML_Parser XMLCALL 1014 1261 XML_ExternalEntityParserCreate(XML_Parser oldParser, 1015 1262 const XML_Char *context, 1016 1263 const XML_Char *encodingName) 1017 1264 { 1018 1265 XML_Parser parser = oldParser; 1019 1266 DTD *newDtd = NULL; 1020 - DTD *oldDtd = _dtd; 1021 - XML_StartElementHandler oldStartElementHandler = startElementHandler; 1022 - XML_EndElementHandler oldEndElementHandler = endElementHandler; 1023 - XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; 1024 - XML_ProcessingInstructionHandler oldProcessingInstructionHandler 1025 - = processingInstructionHandler; 1026 - XML_CommentHandler oldCommentHandler = commentHandler; 1027 - XML_StartCdataSectionHandler oldStartCdataSectionHandler 1028 - = startCdataSectionHandler; 1029 - XML_EndCdataSectionHandler oldEndCdataSectionHandler 1030 - = endCdataSectionHandler; 1031 - XML_DefaultHandler oldDefaultHandler = defaultHandler; 1032 - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler 1033 - = unparsedEntityDeclHandler; 1034 - XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; 1035 - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler 1036 - = startNamespaceDeclHandler; 1037 - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler 1038 - = endNamespaceDeclHandler; 1039 - XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; 1040 - XML_ExternalEntityRefHandler oldExternalEntityRefHandler 1041 - = externalEntityRefHandler; 1042 - XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; 1043 - XML_UnknownEncodingHandler oldUnknownEncodingHandler 1044 - = unknownEncodingHandler; 1045 - XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; 1046 - XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; 1047 - XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; 1048 - XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; 1049 - ELEMENT_TYPE * oldDeclElementType = declElementType; 1050 - 1051 - void *oldUserData = userData; 1052 - void *oldHandlerArg = handlerArg; 1053 - XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; 1054 - XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; 1055 -#ifdef XML_DTD 1056 - enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; 1057 - int oldInEntityValue = prologState.inEntityValue; 1058 -#endif 1059 - XML_Bool oldns_triplets = ns_triplets; 1267 + DTD *oldDtd; 1268 + XML_StartElementHandler oldStartElementHandler; 1269 + XML_EndElementHandler oldEndElementHandler; 1270 + XML_CharacterDataHandler oldCharacterDataHandler; 1271 + XML_ProcessingInstructionHandler oldProcessingInstructionHandler; 1272 + XML_CommentHandler oldCommentHandler; 1273 + XML_StartCdataSectionHandler oldStartCdataSectionHandler; 1274 + XML_EndCdataSectionHandler oldEndCdataSectionHandler; 1275 + XML_DefaultHandler oldDefaultHandler; 1276 + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; 1277 + XML_NotationDeclHandler oldNotationDeclHandler; 1278 + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; 1279 + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; 1280 + XML_NotStandaloneHandler oldNotStandaloneHandler; 1281 + XML_ExternalEntityRefHandler oldExternalEntityRefHandler; 1282 + XML_SkippedEntityHandler oldSkippedEntityHandler; 1283 + XML_UnknownEncodingHandler oldUnknownEncodingHandler; 1284 + XML_ElementDeclHandler oldElementDeclHandler; 1285 + XML_AttlistDeclHandler oldAttlistDeclHandler; 1286 + XML_EntityDeclHandler oldEntityDeclHandler; 1287 + XML_XmlDeclHandler oldXmlDeclHandler; 1288 + ELEMENT_TYPE * oldDeclElementType; 1289 + 1290 + void *oldUserData; 1291 + void *oldHandlerArg; 1292 + XML_Bool oldDefaultExpandInternalEntities; 1293 + XML_Parser oldExternalEntityRefHandlerArg; 1294 +#ifdef XML_DTD 1295 + enum XML_ParamEntityParsing oldParamEntityParsing; 1296 + int oldInEntityValue; 1297 +#endif 1298 + XML_Bool oldns_triplets; 1299 + /* Note that the new parser shares the same hash secret as the old 1300 + parser, so that dtdCopy and copyEntityTable can lookup values 1301 + from hash tables associated with either parser without us having 1302 + to worry which hash secrets each table has. 1303 + */ 1304 + unsigned long oldhash_secret_salt; 1305 + 1306 + /* Validate the oldParser parameter before we pull everything out of it */ 1307 + if (oldParser == NULL) 1308 + return NULL; 1309 + 1310 + /* Stash the original parser contents on the stack */ 1311 + oldDtd = _dtd; 1312 + oldStartElementHandler = startElementHandler; 1313 + oldEndElementHandler = endElementHandler; 1314 + oldCharacterDataHandler = characterDataHandler; 1315 + oldProcessingInstructionHandler = processingInstructionHandler; 1316 + oldCommentHandler = commentHandler; 1317 + oldStartCdataSectionHandler = startCdataSectionHandler; 1318 + oldEndCdataSectionHandler = endCdataSectionHandler; 1319 + oldDefaultHandler = defaultHandler; 1320 + oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; 1321 + oldNotationDeclHandler = notationDeclHandler; 1322 + oldStartNamespaceDeclHandler = startNamespaceDeclHandler; 1323 + oldEndNamespaceDeclHandler = endNamespaceDeclHandler; 1324 + oldNotStandaloneHandler = notStandaloneHandler; 1325 + oldExternalEntityRefHandler = externalEntityRefHandler; 1326 + oldSkippedEntityHandler = skippedEntityHandler; 1327 + oldUnknownEncodingHandler = unknownEncodingHandler; 1328 + oldElementDeclHandler = elementDeclHandler; 1329 + oldAttlistDeclHandler = attlistDeclHandler; 1330 + oldEntityDeclHandler = entityDeclHandler; 1331 + oldXmlDeclHandler = xmlDeclHandler; 1332 + oldDeclElementType = declElementType; 1333 + 1334 + oldUserData = userData; 1335 + oldHandlerArg = handlerArg; 1336 + oldDefaultExpandInternalEntities = defaultExpandInternalEntities; 1337 + oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; 1338 +#ifdef XML_DTD 1339 + oldParamEntityParsing = paramEntityParsing; 1340 + oldInEntityValue = prologState.inEntityValue; 1341 +#endif 1342 + oldns_triplets = ns_triplets; 1060 1343 /* Note that the new parser shares the same hash secret as the old 1061 1344 parser, so that dtdCopy and copyEntityTable can lookup values 1062 1345 from hash tables associated with either parser without us having 1063 1346 to worry which hash secrets each table has. 1064 1347 */ 1065 - unsigned long oldhash_secret_salt = hash_secret_salt; 1348 + oldhash_secret_salt = hash_secret_salt; 1066 1349 1067 1350 #ifdef XML_DTD 1068 1351 if (!context) 1069 1352 newDtd = oldDtd; 1070 1353 #endif /* XML_DTD */ 1071 1354 1072 1355 /* Note that the magical uses of the pre-processor to make field ................................................................................ 1198 1481 FREE(openEntity); 1199 1482 } 1200 1483 1201 1484 destroyBindings(freeBindingList, parser); 1202 1485 destroyBindings(inheritedBindings, parser); 1203 1486 poolDestroy(&tempPool); 1204 1487 poolDestroy(&temp2Pool); 1488 + FREE((void *)protocolEncodingName); 1205 1489 #ifdef XML_DTD 1206 1490 /* external parameter entity parsers share the DTD structure 1207 1491 parser->m_dtd with the root parser, so we must not destroy it 1208 1492 */ 1209 1493 if (!isParamEntity && _dtd) 1210 1494 #else 1211 1495 if (_dtd) ................................................................................ 1224 1508 unknownEncodingRelease(unknownEncodingData); 1225 1509 FREE(parser); 1226 1510 } 1227 1511 1228 1512 void XMLCALL 1229 1513 XML_UseParserAsHandlerArg(XML_Parser parser) 1230 1514 { 1231 - handlerArg = parser; 1515 + if (parser != NULL) 1516 + handlerArg = parser; 1232 1517 } 1233 1518 1234 1519 enum XML_Error XMLCALL 1235 1520 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) 1236 1521 { 1522 + if (parser == NULL) 1523 + return XML_ERROR_INVALID_ARGUMENT; 1237 1524 #ifdef XML_DTD 1238 1525 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1239 1526 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 1240 1527 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; 1241 1528 useForeignDTD = useDTD; 1242 1529 return XML_ERROR_NONE; 1243 1530 #else ................................................................................ 1244 1531 return XML_ERROR_FEATURE_REQUIRES_XML_DTD; 1245 1532 #endif 1246 1533 } 1247 1534 1248 1535 void XMLCALL 1249 1536 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) 1250 1537 { 1538 + if (parser == NULL) 1539 + return; 1251 1540 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1252 1541 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 1253 1542 return; 1254 1543 ns_triplets = do_nst ? XML_TRUE : XML_FALSE; 1255 1544 } 1256 1545 1257 1546 void XMLCALL 1258 1547 XML_SetUserData(XML_Parser parser, void *p) 1259 1548 { 1549 + if (parser == NULL) 1550 + return; 1260 1551 if (handlerArg == userData) 1261 1552 handlerArg = userData = p; 1262 1553 else 1263 1554 userData = p; 1264 1555 } 1265 1556 1266 1557 enum XML_Status XMLCALL 1267 1558 XML_SetBase(XML_Parser parser, const XML_Char *p) 1268 1559 { 1560 + if (parser == NULL) 1561 + return XML_STATUS_ERROR; 1269 1562 if (p) { 1270 1563 p = poolCopyString(&_dtd->pool, p); 1271 1564 if (!p) 1272 1565 return XML_STATUS_ERROR; 1273 1566 curBase = p; 1274 1567 } 1275 1568 else ................................................................................ 1276 1569 curBase = NULL; 1277 1570 return XML_STATUS_OK; 1278 1571 } 1279 1572 1280 1573 const XML_Char * XMLCALL 1281 1574 XML_GetBase(XML_Parser parser) 1282 1575 { 1576 + if (parser == NULL) 1577 + return NULL; 1283 1578 return curBase; 1284 1579 } 1285 1580 1286 1581 int XMLCALL 1287 1582 XML_GetSpecifiedAttributeCount(XML_Parser parser) 1288 1583 { 1584 + if (parser == NULL) 1585 + return -1; 1289 1586 return nSpecifiedAtts; 1290 1587 } 1291 1588 1292 1589 int XMLCALL 1293 1590 XML_GetIdAttributeIndex(XML_Parser parser) 1294 1591 { 1592 + if (parser == NULL) 1593 + return -1; 1295 1594 return idAttIndex; 1296 1595 } 1297 1596 1298 1597 #ifdef XML_ATTR_INFO 1299 1598 const XML_AttrInfo * XMLCALL 1300 1599 XML_GetAttributeInfo(XML_Parser parser) 1301 1600 { 1601 + if (parser == NULL) 1602 + return NULL; 1302 1603 return attInfo; 1303 1604 } 1304 1605 #endif 1305 1606 1306 1607 void XMLCALL 1307 1608 XML_SetElementHandler(XML_Parser parser, 1308 1609 XML_StartElementHandler start, 1309 1610 XML_EndElementHandler end) 1310 1611 { 1612 + if (parser == NULL) 1613 + return; 1311 1614 startElementHandler = start; 1312 1615 endElementHandler = end; 1313 1616 } 1314 1617 1315 1618 void XMLCALL 1316 1619 XML_SetStartElementHandler(XML_Parser parser, 1317 1620 XML_StartElementHandler start) { 1318 - startElementHandler = start; 1621 + if (parser != NULL) 1622 + startElementHandler = start; 1319 1623 } 1320 1624 1321 1625 void XMLCALL 1322 1626 XML_SetEndElementHandler(XML_Parser parser, 1323 1627 XML_EndElementHandler end) { 1324 - endElementHandler = end; 1628 + if (parser != NULL) 1629 + endElementHandler = end; 1325 1630 } 1326 1631 1327 1632 void XMLCALL 1328 1633 XML_SetCharacterDataHandler(XML_Parser parser, 1329 1634 XML_CharacterDataHandler handler) 1330 1635 { 1331 - characterDataHandler = handler; 1636 + if (parser != NULL) 1637 + characterDataHandler = handler; 1332 1638 } 1333 1639 1334 1640 void XMLCALL 1335 1641 XML_SetProcessingInstructionHandler(XML_Parser parser, 1336 1642 XML_ProcessingInstructionHandler handler) 1337 1643 { 1338 - processingInstructionHandler = handler; 1644 + if (parser != NULL) 1645 + processingInstructionHandler = handler; 1339 1646 } 1340 1647 1341 1648 void XMLCALL 1342 1649 XML_SetCommentHandler(XML_Parser parser, 1343 1650 XML_CommentHandler handler) 1344 1651 { 1345 - commentHandler = handler; 1652 + if (parser != NULL) 1653 + commentHandler = handler; 1346 1654 } 1347 1655 1348 1656 void XMLCALL 1349 1657 XML_SetCdataSectionHandler(XML_Parser parser, 1350 1658 XML_StartCdataSectionHandler start, 1351 1659 XML_EndCdataSectionHandler end) 1352 1660 { 1661 + if (parser == NULL) 1662 + return; 1353 1663 startCdataSectionHandler = start; 1354 1664 endCdataSectionHandler = end; 1355 1665 } 1356 1666 1357 1667 void XMLCALL 1358 1668 XML_SetStartCdataSectionHandler(XML_Parser parser, 1359 1669 XML_StartCdataSectionHandler start) { 1360 - startCdataSectionHandler = start; 1670 + if (parser != NULL) 1671 + startCdataSectionHandler = start; 1361 1672 } 1362 1673 1363 1674 void XMLCALL 1364 1675 XML_SetEndCdataSectionHandler(XML_Parser parser, 1365 1676 XML_EndCdataSectionHandler end) { 1366 - endCdataSectionHandler = end; 1677 + if (parser != NULL) 1678 + endCdataSectionHandler = end; 1367 1679 } 1368 1680 1369 1681 void XMLCALL 1370 1682 XML_SetDefaultHandler(XML_Parser parser, 1371 1683 XML_DefaultHandler handler) 1372 1684 { 1685 + if (parser == NULL) 1686 + return; 1373 1687 defaultHandler = handler; 1374 1688 defaultExpandInternalEntities = XML_FALSE; 1375 1689 } 1376 1690 1377 1691 void XMLCALL 1378 1692 XML_SetDefaultHandlerExpand(XML_Parser parser, 1379 1693 XML_DefaultHandler handler) 1380 1694 { 1695 + if (parser == NULL) 1696 + return; 1381 1697 defaultHandler = handler; 1382 1698 defaultExpandInternalEntities = XML_TRUE; 1383 1699 } 1384 1700 1385 1701 void XMLCALL 1386 1702 XML_SetDoctypeDeclHandler(XML_Parser parser, 1387 1703 XML_StartDoctypeDeclHandler start, 1388 1704 XML_EndDoctypeDeclHandler end) 1389 1705 { 1706 + if (parser == NULL) 1707 + return; 1390 1708 startDoctypeDeclHandler = start; 1391 1709 endDoctypeDeclHandler = end; 1392 1710 } 1393 1711 1394 1712 void XMLCALL 1395 1713 XML_SetStartDoctypeDeclHandler(XML_Parser parser, 1396 1714 XML_StartDoctypeDeclHandler start) { 1397 - startDoctypeDeclHandler = start; 1715 + if (parser != NULL) 1716 + startDoctypeDeclHandler = start; 1398 1717 } 1399 1718 1400 1719 void XMLCALL 1401 1720 XML_SetEndDoctypeDeclHandler(XML_Parser parser, 1402 1721 XML_EndDoctypeDeclHandler end) { 1403 - endDoctypeDeclHandler = end; 1722 + if (parser != NULL) 1723 + endDoctypeDeclHandler = end; 1404 1724 } 1405 1725 1406 1726 void XMLCALL 1407 1727 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, 1408 1728 XML_UnparsedEntityDeclHandler handler) 1409 1729 { 1410 - unparsedEntityDeclHandler = handler; 1730 + if (parser != NULL) 1731 + unparsedEntityDeclHandler = handler; 1411 1732 } 1412 1733 1413 1734 void XMLCALL 1414 1735 XML_SetNotationDeclHandler(XML_Parser parser, 1415 1736 XML_NotationDeclHandler handler) 1416 1737 { 1417 - notationDeclHandler = handler; 1738 + if (parser != NULL) 1739 + notationDeclHandler = handler; 1418 1740 } 1419 1741 1420 1742 void XMLCALL 1421 1743 XML_SetNamespaceDeclHandler(XML_Parser parser, 1422 1744 XML_StartNamespaceDeclHandler start, 1423 1745 XML_EndNamespaceDeclHandler end) 1424 1746 { 1747 + if (parser == NULL) 1748 + return; 1425 1749 startNamespaceDeclHandler = start; 1426 1750 endNamespaceDeclHandler = end; 1427 1751 } 1428 1752 1429 1753 void XMLCALL 1430 1754 XML_SetStartNamespaceDeclHandler(XML_Parser parser, 1431 1755 XML_StartNamespaceDeclHandler start) { 1432 - startNamespaceDeclHandler = start; 1756 + if (parser != NULL) 1757 + startNamespaceDeclHandler = start; 1433 1758 } 1434 1759 1435 1760 void XMLCALL 1436 1761 XML_SetEndNamespaceDeclHandler(XML_Parser parser, 1437 1762 XML_EndNamespaceDeclHandler end) { 1438 - endNamespaceDeclHandler = end; 1763 + if (parser != NULL) 1764 + endNamespaceDeclHandler = end; 1439 1765 } 1440 1766 1441 1767 void XMLCALL 1442 1768 XML_SetNotStandaloneHandler(XML_Parser parser, 1443 1769 XML_NotStandaloneHandler handler) 1444 1770 { 1445 - notStandaloneHandler = handler; 1771 + if (parser != NULL) 1772 + notStandaloneHandler = handler; 1446 1773 } 1447 1774 1448 1775 void XMLCALL 1449 1776 XML_SetExternalEntityRefHandler(XML_Parser parser, 1450 1777 XML_ExternalEntityRefHandler handler) 1451 1778 { 1452 - externalEntityRefHandler = handler; 1779 + if (parser != NULL) 1780 + externalEntityRefHandler = handler; 1453 1781 } 1454 1782 1455 1783 void XMLCALL 1456 1784 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) 1457 1785 { 1786 + if (parser == NULL) 1787 + return; 1458 1788 if (arg) 1459 1789 externalEntityRefHandlerArg = (XML_Parser)arg; 1460 1790 else 1461 1791 externalEntityRefHandlerArg = parser; 1462 1792 } 1463 1793 1464 1794 void XMLCALL 1465 1795 XML_SetSkippedEntityHandler(XML_Parser parser, 1466 1796 XML_SkippedEntityHandler handler) 1467 1797 { 1468 - skippedEntityHandler = handler; 1798 + if (parser != NULL) 1799 + skippedEntityHandler = handler; 1469 1800 } 1470 1801 1471 1802 void XMLCALL 1472 1803 XML_SetUnknownEncodingHandler(XML_Parser parser, 1473 1804 XML_UnknownEncodingHandler handler, 1474 1805 void *data) 1475 1806 { 1807 + if (parser == NULL) 1808 + return; 1476 1809 unknownEncodingHandler = handler; 1477 1810 unknownEncodingHandlerData = data; 1478 1811 } 1479 1812 1480 1813 void XMLCALL 1481 1814 XML_SetElementDeclHandler(XML_Parser parser, 1482 1815 XML_ElementDeclHandler eldecl) 1483 1816 { 1484 - elementDeclHandler = eldecl; 1817 + if (parser != NULL) 1818 + elementDeclHandler = eldecl; 1485 1819 } 1486 1820 1487 1821 void XMLCALL 1488 1822 XML_SetAttlistDeclHandler(XML_Parser parser, 1489 1823 XML_AttlistDeclHandler attdecl) 1490 1824 { 1491 - attlistDeclHandler = attdecl; 1825 + if (parser != NULL) 1826 + attlistDeclHandler = attdecl; 1492 1827 } 1493 1828 1494 1829 void XMLCALL 1495 1830 XML_SetEntityDeclHandler(XML_Parser parser, 1496 1831 XML_EntityDeclHandler handler) 1497 1832 { 1498 - entityDeclHandler = handler; 1833 + if (parser != NULL) 1834 + entityDeclHandler = handler; 1499 1835 } 1500 1836 1501 1837 void XMLCALL 1502 1838 XML_SetXmlDeclHandler(XML_Parser parser, 1503 1839 XML_XmlDeclHandler handler) { 1504 - xmlDeclHandler = handler; 1840 + if (parser != NULL) 1841 + xmlDeclHandler = handler; 1505 1842 } 1506 1843 1507 1844 int XMLCALL 1508 1845 XML_SetParamEntityParsing(XML_Parser parser, 1509 1846 enum XML_ParamEntityParsing peParsing) 1510 1847 { 1848 + if (parser == NULL) 1849 + return 0; 1511 1850 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1512 1851 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 1513 1852 return 0; 1514 1853 #ifdef XML_DTD 1515 1854 paramEntityParsing = peParsing; 1516 1855 return 1; 1517 1856 #else ................................................................................ 1519 1858 #endif 1520 1859 } 1521 1860 1522 1861 int XMLCALL 1523 1862 XML_SetHashSalt(XML_Parser parser, 1524 1863 unsigned long hash_salt) 1525 1864 { 1865 + if (parser == NULL) 1866 + return 0; 1867 + if (parser->m_parentParser) 1868 + return XML_SetHashSalt(parser->m_parentParser, hash_salt); 1526 1869 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1527 1870 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 1528 1871 return 0; 1529 1872 hash_secret_salt = hash_salt; 1530 1873 return 1; 1531 1874 } 1532 1875 1533 1876 enum XML_Status XMLCALL 1534 1877 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) 1535 1878 { 1879 + if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { 1880 + if (parser != NULL) 1881 + parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; 1882 + return XML_STATUS_ERROR; 1883 + } 1536 1884 switch (ps_parsing) { 1537 1885 case XML_SUSPENDED: 1538 1886 errorCode = XML_ERROR_SUSPENDED; 1539 1887 return XML_STATUS_ERROR; 1540 1888 case XML_FINISHED: 1541 1889 errorCode = XML_ERROR_FINISHED; 1542 1890 return XML_STATUS_ERROR; ................................................................................ 1561 1909 to detect errors based on that fact. 1562 1910 */ 1563 1911 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); 1564 1912 1565 1913 if (errorCode == XML_ERROR_NONE) { 1566 1914 switch (ps_parsing) { 1567 1915 case XML_SUSPENDED: 1916 + /* It is hard to be certain, but it seems that this case 1917 + * cannot occur. This code is cleaning up a previous parse 1918 + * with no new data (since len == 0). Changing the parsing 1919 + * state requires getting to execute a handler function, and 1920 + * there doesn't seem to be an opportunity for that while in 1921 + * this circumstance. 1922 + * 1923 + * Given the uncertainty, we retain the code but exclude it 1924 + * from coverage tests. 1925 + * 1926 + * LCOV_EXCL_START 1927 + */ 1568 1928 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 1569 1929 positionPtr = bufferPtr; 1570 1930 return XML_STATUS_SUSPENDED; 1931 + /* LCOV_EXCL_STOP */ 1571 1932 case XML_INITIALIZED: 1572 1933 case XML_PARSING: 1573 1934 ps_parsing = XML_FINISHED; 1574 1935 /* fall through */ 1575 1936 default: 1576 1937 return XML_STATUS_OK; 1577 1938 } ................................................................................ 1581 1942 return XML_STATUS_ERROR; 1582 1943 } 1583 1944 #ifndef XML_CONTEXT_BYTES 1584 1945 else if (bufferPtr == bufferEnd) { 1585 1946 const char *end; 1586 1947 int nLeftOver; 1587 1948 enum XML_Status result; 1949 + /* Detect overflow (a+b > MAX <==> b > MAX-a) */ 1950 + if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) { 1951 + errorCode = XML_ERROR_NO_MEMORY; 1952 + eventPtr = eventEndPtr = NULL; 1953 + processor = errorProcessor; 1954 + return XML_STATUS_ERROR; 1955 + } 1588 1956 parseEndByteIndex += len; 1589 1957 positionPtr = s; 1590 1958 ps_finalBuffer = (XML_Bool)isFinal; 1591 1959 1592 1960 errorCode = processor(parser, s, parseEndPtr = s + len, &end); 1593 1961 1594 1962 if (errorCode != XML_ERROR_NONE) { ................................................................................ 1613 1981 } 1614 1982 } 1615 1983 1616 1984 XmlUpdatePosition(encoding, positionPtr, end, &position); 1617 1985 nLeftOver = s + len - end; 1618 1986 if (nLeftOver) { 1619 1987 if (buffer == NULL || nLeftOver > bufferLim - buffer) { 1620 - /* FIXME avoid integer overflow */ 1621 - char *temp; 1622 - temp = (buffer == NULL 1623 - ? (char *)MALLOC(len * 2) 1624 - : (char *)REALLOC(buffer, len * 2)); 1988 + /* avoid _signed_ integer overflow */ 1989 + char *temp = NULL; 1990 + const int bytesToAllocate = (int)((unsigned)len * 2U); 1991 + if (bytesToAllocate > 0) { 1992 + temp = (buffer == NULL 1993 + ? (char *)MALLOC(bytesToAllocate) 1994 + : (char *)REALLOC(buffer, bytesToAllocate)); 1995 + } 1625 1996 if (temp == NULL) { 1626 1997 errorCode = XML_ERROR_NO_MEMORY; 1627 1998 eventPtr = eventEndPtr = NULL; 1628 1999 processor = errorProcessor; 1629 2000 return XML_STATUS_ERROR; 1630 2001 } 1631 2002 buffer = temp; 1632 - bufferLim = buffer + len * 2; 2003 + bufferLim = buffer + bytesToAllocate; 1633 2004 } 1634 2005 memcpy(buffer, end, nLeftOver); 1635 2006 } 1636 2007 bufferPtr = buffer; 1637 2008 bufferEnd = buffer + nLeftOver; 1638 2009 positionPtr = bufferPtr; 1639 2010 parseEndPtr = bufferEnd; ................................................................................ 1655 2026 1656 2027 enum XML_Status XMLCALL 1657 2028 XML_ParseBuffer(XML_Parser parser, int len, int isFinal) 1658 2029 { 1659 2030 const char *start; 1660 2031 enum XML_Status result = XML_STATUS_OK; 1661 2032 2033 + if (parser == NULL) 2034 + return XML_STATUS_ERROR; 1662 2035 switch (ps_parsing) { 1663 2036 case XML_SUSPENDED: 1664 2037 errorCode = XML_ERROR_SUSPENDED; 1665 2038 return XML_STATUS_ERROR; 1666 2039 case XML_FINISHED: 1667 2040 errorCode = XML_ERROR_FINISHED; 1668 2041 return XML_STATUS_ERROR; ................................................................................ 1708 2081 positionPtr = bufferPtr; 1709 2082 return result; 1710 2083 } 1711 2084 1712 2085 void * XMLCALL 1713 2086 XML_GetBuffer(XML_Parser parser, int len) 1714 2087 { 2088 + if (parser == NULL) 2089 + return NULL; 1715 2090 if (len < 0) { 1716 2091 errorCode = XML_ERROR_NO_MEMORY; 1717 2092 return NULL; 1718 2093 } 1719 2094 switch (ps_parsing) { 1720 2095 case XML_SUSPENDED: 1721 2096 errorCode = XML_ERROR_SUSPENDED; ................................................................................ 1804 2179 } 1805 2180 return bufferEnd; 1806 2181 } 1807 2182 1808 2183 enum XML_Status XMLCALL 1809 2184 XML_StopParser(XML_Parser parser, XML_Bool resumable) 1810 2185 { 2186 + if (parser == NULL) 2187 + return XML_STATUS_ERROR; 1811 2188 switch (ps_parsing) { 1812 2189 case XML_SUSPENDED: 1813 2190 if (resumable) { 1814 2191 errorCode = XML_ERROR_SUSPENDED; 1815 2192 return XML_STATUS_ERROR; 1816 2193 } 1817 2194 ps_parsing = XML_FINISHED; ................................................................................ 1836 2213 } 1837 2214 1838 2215 enum XML_Status XMLCALL 1839 2216 XML_ResumeParser(XML_Parser parser) 1840 2217 { 1841 2218 enum XML_Status result = XML_STATUS_OK; 1842 2219 2220 + if (parser == NULL) 2221 + return XML_STATUS_ERROR; 1843 2222 if (ps_parsing != XML_SUSPENDED) { 1844 2223 errorCode = XML_ERROR_NOT_SUSPENDED; 1845 2224 return XML_STATUS_ERROR; 1846 2225 } 1847 2226 ps_parsing = XML_PARSING; 1848 2227 1849 2228 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); ................................................................................ 1872 2251 positionPtr = bufferPtr; 1873 2252 return result; 1874 2253 } 1875 2254 1876 2255 void XMLCALL 1877 2256 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) 1878 2257 { 2258 + if (parser == NULL) 2259 + return; 1879 2260 assert(status != NULL); 1880 2261 *status = parser->m_parsingStatus; 1881 2262 } 1882 2263 1883 2264 enum XML_Error XMLCALL 1884 2265 XML_GetErrorCode(XML_Parser parser) 1885 2266 { 2267 + if (parser == NULL) 2268 + return XML_ERROR_INVALID_ARGUMENT; 1886 2269 return errorCode; 1887 2270 } 1888 2271 1889 2272 XML_Index XMLCALL 1890 2273 XML_GetCurrentByteIndex(XML_Parser parser) 1891 2274 { 2275 + if (parser == NULL) 2276 + return -1; 1892 2277 if (eventPtr) 1893 2278 return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); 1894 2279 return -1; 1895 2280 } 1896 2281 1897 2282 int XMLCALL 1898 2283 XML_GetCurrentByteCount(XML_Parser parser) 1899 2284 { 2285 + if (parser == NULL) 2286 + return 0; 1900 2287 if (eventEndPtr && eventPtr) 1901 2288 return (int)(eventEndPtr - eventPtr); 1902 2289 return 0; 1903 2290 } 1904 2291 1905 2292 const char * XMLCALL 1906 2293 XML_GetInputContext(XML_Parser parser, int *offset, int *size) 1907 2294 { 1908 2295 #ifdef XML_CONTEXT_BYTES 2296 + if (parser == NULL) 2297 + return NULL; 1909 2298 if (eventPtr && buffer) { 1910 - *offset = (int)(eventPtr - buffer); 1911 - *size = (int)(bufferEnd - buffer); 2299 + if (offset != NULL) 2300 + *offset = (int)(eventPtr - buffer); 2301 + if (size != NULL) 2302 + *size = (int)(bufferEnd - buffer); 1912 2303 return buffer; 1913 2304 } 2305 +#else 2306 + (void)parser; 2307 + (void)offset; 2308 + (void)size; 1914 2309 #endif /* defined XML_CONTEXT_BYTES */ 1915 2310 return (char *) 0; 1916 2311 } 1917 2312 1918 2313 XML_Size XMLCALL 1919 2314 XML_GetCurrentLineNumber(XML_Parser parser) 1920 2315 { 2316 + if (parser == NULL) 2317 + return 0; 1921 2318 if (eventPtr && eventPtr >= positionPtr) { 1922 2319 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1923 2320 positionPtr = eventPtr; 1924 2321 } 1925 2322 return position.lineNumber + 1; 1926 2323 } 1927 2324 1928 2325 XML_Size XMLCALL 1929 2326 XML_GetCurrentColumnNumber(XML_Parser parser) 1930 2327 { 2328 + if (parser == NULL) 2329 + return 0; 1931 2330 if (eventPtr && eventPtr >= positionPtr) { 1932 2331 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1933 2332 positionPtr = eventPtr; 1934 2333 } 1935 2334 return position.columnNumber; 1936 2335 } 1937 2336 1938 2337 void XMLCALL 1939 2338 XML_FreeContentModel(XML_Parser parser, XML_Content *model) 1940 2339 { 1941 - FREE(model); 2340 + if (parser != NULL) 2341 + FREE(model); 1942 2342 } 1943 2343 1944 2344 void * XMLCALL 1945 2345 XML_MemMalloc(XML_Parser parser, size_t size) 1946 2346 { 2347 + if (parser == NULL) 2348 + return NULL; 1947 2349 return MALLOC(size); 1948 2350 } 1949 2351 1950 2352 void * XMLCALL 1951 2353 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) 1952 2354 { 2355 + if (parser == NULL) 2356 + return NULL; 1953 2357 return REALLOC(ptr, size); 1954 2358 } 1955 2359 1956 2360 void XMLCALL 1957 2361 XML_MemFree(XML_Parser parser, void *ptr) 1958 2362 { 1959 - FREE(ptr); 2363 + if (parser != NULL) 2364 + FREE(ptr); 1960 2365 } 1961 2366 1962 2367 void XMLCALL 1963 2368 XML_DefaultCurrent(XML_Parser parser) 1964 2369 { 2370 + if (parser == NULL) 2371 + return; 1965 2372 if (defaultHandler) { 1966 2373 if (openInternalEntities) 1967 2374 reportDefault(parser, 1968 2375 internalEncoding, 1969 2376 openInternalEntities->internalEventPtr, 1970 2377 openInternalEntities->internalEventEndPtr); 1971 2378 else ................................................................................ 2464 2871 for (;;) { 2465 2872 int bufSize; 2466 2873 int convLen; 2467 2874 const enum XML_Convert_Result convert_res = XmlConvert(enc, 2468 2875 &fromPtr, rawNameEnd, 2469 2876 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); 2470 2877 convLen = (int)(toPtr - (XML_Char *)tag->buf); 2471 - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { 2878 + if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { 2472 2879 tag->name.strLen = convLen; 2473 2880 break; 2474 2881 } 2475 2882 bufSize = (int)(tag->bufEnd - tag->buf) << 1; 2476 2883 { 2477 2884 char *temp = (char *)REALLOC(tag->buf, bufSize); 2478 2885 if (temp == NULL) ................................................................................ 2507 2914 TAG_NAME name; 2508 2915 name.str = poolStoreString(&tempPool, enc, rawName, 2509 2916 rawName + XmlNameLength(enc, rawName)); 2510 2917 if (!name.str) 2511 2918 return XML_ERROR_NO_MEMORY; 2512 2919 poolFinish(&tempPool); 2513 2920 result = storeAtts(parser, enc, s, &name, &bindings); 2514 - if (result) 2921 + if (result != XML_ERROR_NONE) { 2922 + freeBindings(parser, bindings); 2515 2923 return result; 2924 + } 2516 2925 poolFinish(&tempPool); 2517 2926 if (startElementHandler) { 2518 2927 startElementHandler(handlerArg, name.str, (const XML_Char **)atts); 2519 2928 noElmHandlers = XML_FALSE; 2520 2929 } 2521 2930 if (endElementHandler) { 2522 2931 if (startElementHandler) ................................................................................ 2523 2932 *eventPP = *eventEndPP; 2524 2933 endElementHandler(handlerArg, name.str); 2525 2934 noElmHandlers = XML_FALSE; 2526 2935 } 2527 2936 if (noElmHandlers && defaultHandler) 2528 2937 reportDefault(parser, enc, s, next); 2529 2938 poolClear(&tempPool); 2530 - while (bindings) { 2531 - BINDING *b = bindings; 2532 - if (endNamespaceDeclHandler) 2533 - endNamespaceDeclHandler(handlerArg, b->prefix->name); 2534 - bindings = bindings->nextTagBinding; 2535 - b->nextTagBinding = freeBindingList; 2536 - freeBindingList = b; 2537 - b->prefix->binding = b->prevPrefixBinding; 2538 - } 2939 + freeBindings(parser, bindings); 2539 2940 } 2540 2941 if (tagLevel == 0) 2541 2942 return epilogProcessor(parser, next, end, nextPtr); 2542 2943 break; 2543 2944 case XML_TOK_END_TAG: 2544 2945 if (tagLevel == startTagLevel) 2545 2946 return XML_ERROR_ASYNC_ENTITY; ................................................................................ 2712 3113 return XML_ERROR_NO_MEMORY; 2713 3114 break; 2714 3115 case XML_TOK_COMMENT: 2715 3116 if (!reportComment(parser, enc, s, next)) 2716 3117 return XML_ERROR_NO_MEMORY; 2717 3118 break; 2718 3119 default: 3120 + /* All of the tokens produced by XmlContentTok() have their own 3121 + * explicit cases, so this default is not strictly necessary. 3122 + * However it is a useful safety net, so we retain the code and 3123 + * simply exclude it from the coverage tests. 3124 + * 3125 + * LCOV_EXCL_START 3126 + */ 2719 3127 if (defaultHandler) 2720 3128 reportDefault(parser, enc, s, next); 2721 3129 break; 3130 + /* LCOV_EXCL_STOP */ 2722 3131 } 2723 3132 *eventPP = s = next; 2724 3133 switch (ps_parsing) { 2725 3134 case XML_SUSPENDED: 2726 3135 *nextPtr = next; 2727 3136 return XML_ERROR_NONE; 2728 3137 case XML_FINISHED: 2729 3138 return XML_ERROR_ABORTED; 2730 3139 default: ; 2731 3140 } 2732 3141 } 2733 3142 /* not reached */ 2734 3143 } 3144 + 3145 +/* This function does not call free() on the allocated memory, merely 3146 + * moving it to the parser's freeBindingList where it can be freed or 3147 + * reused as appropriate. 3148 + */ 3149 +static void 3150 +freeBindings(XML_Parser parser, BINDING *bindings) 3151 +{ 3152 + while (bindings) { 3153 + BINDING *b = bindings; 3154 + 3155 + /* startNamespaceDeclHandler will have been called for this 3156 + * binding in addBindings(), so call the end handler now. 3157 + */ 3158 + if (endNamespaceDeclHandler) 3159 + endNamespaceDeclHandler(handlerArg, b->prefix->name); 3160 + 3161 + bindings = bindings->nextTagBinding; 3162 + b->nextTagBinding = freeBindingList; 3163 + freeBindingList = b; 3164 + b->prefix->binding = b->prevPrefixBinding; 3165 + } 3166 +} 2735 3167 2736 3168 /* Precondition: all arguments must be non-NULL; 2737 3169 Purpose: 2738 3170 - normalize attributes 2739 3171 - check attributes for well-formedness 2740 3172 - generate namespace aware attribute names (URI, prefix) 2741 3173 - build list of attributes for startElementHandler ................................................................................ 2782 3214 int oldAttsSize = attsSize; 2783 3215 ATTRIBUTE *temp; 2784 3216 #ifdef XML_ATTR_INFO 2785 3217 XML_AttrInfo *temp2; 2786 3218 #endif 2787 3219 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 2788 3220 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); 2789 - if (temp == NULL) 3221 + if (temp == NULL) { 3222 + attsSize = oldAttsSize; 2790 3223 return XML_ERROR_NO_MEMORY; 3224 + } 2791 3225 atts = temp; 2792 3226 #ifdef XML_ATTR_INFO 2793 3227 temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo)); 2794 - if (temp2 == NULL) 3228 + if (temp2 == NULL) { 3229 + attsSize = oldAttsSize; 2795 3230 return XML_ERROR_NO_MEMORY; 3231 + } 2796 3232 attInfo = temp2; 2797 3233 #endif 2798 3234 if (n > oldAttsSize) 2799 3235 XmlGetAttributes(enc, attStr, n, atts); 2800 3236 } 2801 3237 2802 3238 appAtts = (const XML_Char **)atts; ................................................................................ 2925 3361 /* expand prefixed attribute names, check for duplicates, 2926 3362 and clear flags that say whether attributes were specified */ 2927 3363 i = 0; 2928 3364 if (nPrefixes) { 2929 3365 int j; /* hash table index */ 2930 3366 unsigned long version = nsAttsVersion; 2931 3367 int nsAttsSize = (int)1 << nsAttsPower; 3368 + unsigned char oldNsAttsPower = nsAttsPower; 2932 3369 /* size of hash table must be at least 2 * (# of prefixed attributes) */ 2933 3370 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */ 2934 3371 NS_ATT *temp; 2935 3372 /* hash table size must also be a power of 2 and >= 8 */ 2936 3373 while (nPrefixes >> nsAttsPower++); 2937 3374 if (nsAttsPower < 3) 2938 3375 nsAttsPower = 3; 2939 3376 nsAttsSize = (int)1 << nsAttsPower; 2940 3377 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); 2941 - if (!temp) 3378 + if (!temp) { 3379 + /* Restore actual size of memory in nsAtts */ 3380 + nsAttsPower = oldNsAttsPower; 2942 3381 return XML_ERROR_NO_MEMORY; 3382 + } 2943 3383 nsAtts = temp; 2944 3384 version = 0; /* force re-initialization of nsAtts hash table */ 2945 3385 } 2946 3386 /* using a version flag saves us from initializing nsAtts every time */ 2947 3387 if (!version) { /* initialize version flags when version wraps around */ 2948 3388 version = INIT_ATTS_VERSION; 2949 3389 for (j = nsAttsSize; j != 0; ) ................................................................................ 2953 3393 2954 3394 /* expand prefixed names and check for duplicates */ 2955 3395 for (; i < attIndex; i += 2) { 2956 3396 const XML_Char *s = appAtts[i]; 2957 3397 if (s[-1] == 2) { /* prefixed */ 2958 3398 ATTRIBUTE_ID *id; 2959 3399 const BINDING *b; 2960 - unsigned long uriHash = hash_secret_salt; 3400 + unsigned long uriHash; 3401 + struct siphash sip_state; 3402 + struct sipkey sip_key; 3403 + 3404 + copy_salt_to_sipkey(parser, &sip_key); 3405 + sip24_init(&sip_state, &sip_key); 3406 + 2961 3407 ((XML_Char *)s)[-1] = 0; /* clear flag */ 2962 3408 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); 2963 - if (!id || !id->prefix) 2964 - return XML_ERROR_NO_MEMORY; 3409 + if (!id || !id->prefix) { 3410 + /* This code is walking through the appAtts array, dealing 3411 + * with (in this case) a prefixed attribute name. To be in 3412 + * the array, the attribute must have already been bound, so 3413 + * has to have passed through the hash table lookup once 3414 + * already. That implies that an entry for it already 3415 + * exists, so the lookup above will return a pointer to 3416 + * already allocated memory. There is no opportunaity for 3417 + * the allocator to fail, so the condition above cannot be 3418 + * fulfilled. 3419 + * 3420 + * Since it is difficult to be certain that the above 3421 + * analysis is complete, we retain the test and merely 3422 + * remove the code from coverage tests. 3423 + */ 3424 + return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 3425 + } 2965 3426 b = id->prefix->binding; 2966 3427 if (!b) 2967 3428 return XML_ERROR_UNBOUND_PREFIX; 2968 3429 2969 - /* as we expand the name we also calculate its hash value */ 2970 3430 for (j = 0; j < b->uriLen; j++) { 2971 3431 const XML_Char c = b->uri[j]; 2972 3432 if (!poolAppendChar(&tempPool, c)) 2973 3433 return XML_ERROR_NO_MEMORY; 2974 - uriHash = CHAR_HASH(uriHash, c); 2975 3434 } 3435 + 3436 + sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); 3437 + 2976 3438 while (*s++ != XML_T(ASCII_COLON)) 2977 3439 ; 3440 + 3441 + sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); 3442 + 2978 3443 do { /* copies null terminator */ 2979 - const XML_Char c = *s; 2980 3444 if (!poolAppendChar(&tempPool, *s)) 2981 3445 return XML_ERROR_NO_MEMORY; 2982 - uriHash = CHAR_HASH(uriHash, c); 2983 3446 } while (*s++); 3447 + 3448 + uriHash = (unsigned long)sip24_final(&sip_state); 2984 3449 2985 3450 { /* Check hash table for duplicate of expanded name (uriName). 2986 3451 Derived from code in lookup(parser, HASH_TABLE *table, ...). 2987 3452 */ 2988 3453 unsigned char step = 0; 2989 3454 unsigned long mask = nsAttsSize - 1; 2990 3455 j = uriHash & mask; /* index into hash table */ ................................................................................ 3330 3795 case XML_TOK_NONE: 3331 3796 if (haveMore) { 3332 3797 *nextPtr = s; 3333 3798 return XML_ERROR_NONE; 3334 3799 } 3335 3800 return XML_ERROR_UNCLOSED_CDATA_SECTION; 3336 3801 default: 3802 + /* Every token returned by XmlCdataSectionTok() has its own 3803 + * explicit case, so this default case will never be executed. 3804 + * We retain it as a safety net and exclude it from the coverage 3805 + * statistics. 3806 + * 3807 + * LCOV_EXCL_START 3808 + */ 3337 3809 *eventPP = next; 3338 3810 return XML_ERROR_UNEXPECTED_STATE; 3811 + /* LCOV_EXCL_STOP */ 3339 3812 } 3340 3813 3341 3814 *eventPP = s = next; 3342 3815 switch (ps_parsing) { 3343 3816 case XML_SUSPENDED: 3344 3817 *nextPtr = next; 3345 3818 return XML_ERROR_NONE; ................................................................................ 3391 3864 const char **eventEndPP; 3392 3865 if (enc == encoding) { 3393 3866 eventPP = &eventPtr; 3394 3867 *eventPP = s; 3395 3868 eventEndPP = &eventEndPtr; 3396 3869 } 3397 3870 else { 3871 + /* It's not entirely clear, but it seems the following two lines 3872 + * of code cannot be executed. The only occasions on which 'enc' 3873 + * is not 'parser->m_encoding' are when this function is called 3874 + * from the internal entity processing, and IGNORE sections are an 3875 + * error in internal entities. 3876 + * 3877 + * Since it really isn't clear that this is true, we keep the code 3878 + * and just remove it from our coverage tests. 3879 + * 3880 + * LCOV_EXCL_START 3881 + */ 3398 3882 eventPP = &(openInternalEntities->internalEventPtr); 3399 3883 eventEndPP = &(openInternalEntities->internalEventEndPtr); 3884 + /* LCOV_EXCL_STOP */ 3400 3885 } 3401 3886 *eventPP = s; 3402 3887 *startPtr = NULL; 3403 3888 tok = XmlIgnoreSectionTok(enc, s, end, &next); 3404 3889 *eventEndPP = next; 3405 3890 switch (tok) { 3406 3891 case XML_TOK_IGNORE_SECT: ................................................................................ 3425 3910 case XML_TOK_NONE: 3426 3911 if (haveMore) { 3427 3912 *nextPtr = s; 3428 3913 return XML_ERROR_NONE; 3429 3914 } 3430 3915 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 3431 3916 default: 3917 + /* All of the tokens that XmlIgnoreSectionTok() returns have 3918 + * explicit cases to handle them, so this default case is never 3919 + * executed. We keep it as a safety net anyway, and remove it 3920 + * from our test coverage statistics. 3921 + * 3922 + * LCOV_EXCL_START 3923 + */ 3432 3924 *eventPP = next; 3433 3925 return XML_ERROR_UNEXPECTED_STATE; 3926 + /* LCOV_EXCL_STOP */ 3434 3927 } 3435 3928 /* not reached */ 3436 3929 } 3437 3930 3438 3931 #endif /* XML_DTD */ 3439 3932 3440 3933 static enum XML_Error 3441 3934 initializeEncoding(XML_Parser parser) 3442 3935 { 3443 3936 const char *s; 3444 3937 #ifdef XML_UNICODE 3445 3938 char encodingBuf[128]; 3939 + /* See comments abount `protoclEncodingName` in parserInit() */ 3446 3940 if (!protocolEncodingName) 3447 3941 s = NULL; 3448 3942 else { 3449 3943 int i; 3450 3944 for (i = 0; protocolEncodingName[i]; i++) { 3451 3945 if (i == sizeof(encodingBuf) - 1 3452 3946 || (protocolEncodingName[i] & ~0x7f) != 0) { ................................................................................ 3522 4016 } 3523 4017 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); 3524 4018 } 3525 4019 else if (defaultHandler) 3526 4020 reportDefault(parser, encoding, s, next); 3527 4021 if (protocolEncodingName == NULL) { 3528 4022 if (newEncoding) { 3529 - if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { 4023 + /* Check that the specified encoding does not conflict with what 4024 + * the parser has already deduced. Do we have the same number 4025 + * of bytes in the smallest representation of a character? If 4026 + * this is UTF-16, is it the same endianness? 4027 + */ 4028 + if (newEncoding->minBytesPerChar != encoding->minBytesPerChar 4029 + || (newEncoding->minBytesPerChar == 2 && 4030 + newEncoding != encoding)) { 3530 4031 eventPtr = encodingName; 3531 4032 return XML_ERROR_INCORRECT_ENCODING; 3532 4033 } 3533 4034 encoding = newEncoding; 3534 4035 } 3535 4036 else if (encodingName) { 3536 4037 enum XML_Error result; ................................................................................ 3667 4168 return storeEntityValue(parser, encoding, s, end); 3668 4169 } 3669 4170 else if (tok == XML_TOK_XML_DECL) { 3670 4171 enum XML_Error result; 3671 4172 result = processXmlDecl(parser, 0, start, next); 3672 4173 if (result != XML_ERROR_NONE) 3673 4174 return result; 3674 - switch (ps_parsing) { 3675 - case XML_SUSPENDED: 3676 - *nextPtr = next; 3677 - return XML_ERROR_NONE; 3678 - case XML_FINISHED: 4175 + /* At this point, ps_parsing cannot be XML_SUSPENDED. For that 4176 + * to happen, a parameter entity parsing handler must have 4177 + * attempted to suspend the parser, which fails and raises an 4178 + * error. The parser can be aborted, but can't be suspended. 4179 + */ 4180 + if (ps_parsing == XML_FINISHED) 3679 4181 return XML_ERROR_ABORTED; 3680 - default: 3681 - *nextPtr = next; 3682 - } 4182 + *nextPtr = next; 3683 4183 /* stop scanning for text declaration - we found one */ 3684 4184 processor = entityValueProcessor; 3685 4185 return entityValueProcessor(parser, next, end, nextPtr); 3686 4186 } 3687 4187 /* If we are at the end of the buffer, this would cause XmlPrologTok to 3688 4188 return XML_TOK_NONE on the next call, which would then cause the 3689 4189 function to exit with *nextPtr set to s - that is what we want for other ................................................................................ 3690 4190 tokens, but not for the BOM - we would rather like to skip it; 3691 4191 then, when this routine is entered the next time, XmlPrologTok will 3692 4192 return XML_TOK_INVALID, since the BOM is still in the buffer 3693 4193 */ 3694 4194 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { 3695 4195 *nextPtr = next; 3696 4196 return XML_ERROR_NONE; 4197 + } 4198 + /* If we get this token, we have the start of what might be a 4199 + normal tag, but not a declaration (i.e. it doesn't begin with 4200 + "<!"). In a DTD context, that isn't legal. 4201 + */ 4202 + else if (tok == XML_TOK_INSTANCE_START) { 4203 + *nextPtr = next; 4204 + return XML_ERROR_SYNTAX; 3697 4205 } 3698 4206 start = next; 3699 4207 eventPtr = start; 3700 4208 } 3701 4209 } 3702 4210 3703 4211 static enum XML_Error PTRCALL ................................................................................ 3990 4498 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 3991 4499 dtd->hasParamEntityRefs = XML_TRUE; 3992 4500 if (paramEntityParsing && externalEntityRefHandler) { 3993 4501 ENTITY *entity = (ENTITY *)lookup(parser, 3994 4502 &dtd->paramEntities, 3995 4503 externalSubsetName, 3996 4504 sizeof(ENTITY)); 3997 - if (!entity) 3998 - return XML_ERROR_NO_MEMORY; 4505 + if (!entity) { 4506 + /* The external subset name "#" will have already been 4507 + * inserted into the hash table at the start of the 4508 + * external entity parsing, so no allocation will happen 4509 + * and lookup() cannot fail. 4510 + */ 4511 + return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 4512 + } 3999 4513 if (useForeignDTD) 4000 4514 entity->base = curBase; 4001 4515 dtd->paramEntityRead = XML_FALSE; 4002 4516 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 4003 4517 0, 4004 4518 entity->base, 4005 4519 entity->systemId, ................................................................................ 4470 4984 } 4471 4985 break; 4472 4986 #endif /* XML_DTD */ 4473 4987 case XML_ROLE_GROUP_OPEN: 4474 4988 if (prologState.level >= groupSize) { 4475 4989 if (groupSize) { 4476 4990 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); 4477 - if (temp == NULL) 4991 + if (temp == NULL) { 4992 + groupSize /= 2; 4478 4993 return XML_ERROR_NO_MEMORY; 4994 + } 4479 4995 groupConnector = temp; 4480 4996 if (dtd->scaffIndex) { 4481 4997 int *temp = (int *)REALLOC(dtd->scaffIndex, 4482 4998 groupSize * sizeof(int)); 4483 4999 if (temp == NULL) 4484 5000 return XML_ERROR_NO_MEMORY; 4485 5001 dtd->scaffIndex = temp; 4486 5002 } 4487 5003 } 4488 5004 else { 4489 5005 groupConnector = (char *)MALLOC(groupSize = 32); 4490 - if (!groupConnector) 5006 + if (!groupConnector) { 5007 + groupSize = 0; 4491 5008 return XML_ERROR_NO_MEMORY; 5009 + } 4492 5010 } 4493 5011 } 4494 5012 groupConnector[prologState.level] = 0; 4495 5013 if (dtd->in_eldecl) { 4496 5014 int myindex = nextScaffoldPart(parser); 4497 5015 if (myindex < 0) 4498 5016 return XML_ERROR_NO_MEMORY; ................................................................................ 4547 5065 */ 4548 5066 if (prologState.documentEntity && 4549 5067 (dtd->standalone 4550 5068 ? !openInternalEntities 4551 5069 : !dtd->hasParamEntityRefs)) { 4552 5070 if (!entity) 4553 5071 return XML_ERROR_UNDEFINED_ENTITY; 4554 - else if (!entity->is_internal) 4555 - return XML_ERROR_ENTITY_DECLARED_IN_PE; 5072 + else if (!entity->is_internal) { 5073 + /* It's hard to exhaustively search the code to be sure, 5074 + * but there doesn't seem to be a way of executing the 5075 + * following line. There are two cases: 5076 + * 5077 + * If 'standalone' is false, the DTD must have no 5078 + * parameter entities or we wouldn't have passed the outer 5079 + * 'if' statement. That measn the only entity in the hash 5080 + * table is the external subset name "#" which cannot be 5081 + * given as a parameter entity name in XML syntax, so the 5082 + * lookup must have returned NULL and we don't even reach 5083 + * the test for an internal entity. 5084 + * 5085 + * If 'standalone' is true, it does not seem to be 5086 + * possible to create entities taking this code path that 5087 + * are not internal entities, so fail the test above. 5088 + * 5089 + * Because this analysis is very uncertain, the code is 5090 + * being left in place and merely removed from the 5091 + * coverage test statistics. 5092 + */ 5093 + return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ 5094 + } 4556 5095 } 4557 5096 else if (!entity) { 4558 5097 dtd->keepProcessing = dtd->standalone; 4559 5098 /* cannot report skipped entities in declarations */ 4560 5099 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { 4561 5100 skippedEntityHandler(handlerArg, name, 1); 4562 5101 handleDefault = XML_FALSE; ................................................................................ 4867 5406 openEntity->entity = entity; 4868 5407 openEntity->startTagLevel = tagLevel; 4869 5408 openEntity->betweenDecl = betweenDecl; 4870 5409 openEntity->internalEventPtr = NULL; 4871 5410 openEntity->internalEventEndPtr = NULL; 4872 5411 textStart = (char *)entity->textPtr; 4873 5412 textEnd = (char *)(entity->textPtr + entity->textLen); 5413 + /* Set a safe default value in case 'next' does not get set */ 5414 + next = textStart; 4874 5415 4875 5416 #ifdef XML_DTD 4876 5417 if (entity->is_param) { 4877 5418 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 4878 5419 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 4879 5420 next, &next, XML_FALSE); 4880 5421 } ................................................................................ 4912 5453 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; 4913 5454 if (!openEntity) 4914 5455 return XML_ERROR_UNEXPECTED_STATE; 4915 5456 4916 5457 entity = openEntity->entity; 4917 5458 textStart = ((char *)entity->textPtr) + entity->processed; 4918 5459 textEnd = (char *)(entity->textPtr + entity->textLen); 5460 + /* Set a safe default value in case 'next' does not get set */ 5461 + next = textStart; 4919 5462 4920 5463 #ifdef XML_DTD 4921 5464 if (entity->is_param) { 4922 5465 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 4923 5466 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 4924 5467 next, &next, XML_FALSE); 4925 5468 } ................................................................................ 5016 5559 return XML_ERROR_BAD_CHAR_REF; 5017 5560 } 5018 5561 if (!isCdata 5019 5562 && n == 0x20 /* space */ 5020 5563 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 5021 5564 break; 5022 5565 n = XmlEncode(n, (ICHAR *)buf); 5023 - if (!n) { 5024 - if (enc == encoding) 5025 - eventPtr = ptr; 5026 - return XML_ERROR_BAD_CHAR_REF; 5027 - } 5566 + /* The XmlEncode() functions can never return 0 here. That 5567 + * error return happens if the code point passed in is either 5568 + * negative or greater than or equal to 0x110000. The 5569 + * XmlCharRefNumber() functions will all return a number 5570 + * strictly less than 0x110000 or a negative value if an error 5571 + * occurred. The negative value is intercepted above, so 5572 + * XmlEncode() is never passed a value it might return an 5573 + * error for. 5574 + */ 5028 5575 for (i = 0; i < n; i++) { 5029 5576 if (!poolAppendChar(pool, buf[i])) 5030 5577 return XML_ERROR_NO_MEMORY; 5031 5578 } 5032 5579 } 5033 5580 break; 5034 5581 case XML_TOK_DATA_CHARS: ................................................................................ 5094 5641 out of sync with the call to the startElementHandler. 5095 5642 if ((pool == &tempPool) && defaultHandler) 5096 5643 reportDefault(parser, enc, ptr, next); 5097 5644 */ 5098 5645 break; 5099 5646 } 5100 5647 if (entity->open) { 5101 - if (enc == encoding) 5102 - eventPtr = ptr; 5648 + if (enc == encoding) { 5649 + /* It does not appear that this line can be executed. 5650 + * 5651 + * The "if (entity->open)" check catches recursive entity 5652 + * definitions. In order to be called with an open 5653 + * entity, it must have gone through this code before and 5654 + * been through the recursive call to 5655 + * appendAttributeValue() some lines below. That call 5656 + * sets the local encoding ("enc") to the parser's 5657 + * internal encoding (internal_utf8 or internal_utf16), 5658 + * which can never be the same as the principle encoding. 5659 + * It doesn't appear there is another code path that gets 5660 + * here with entity->open being TRUE. 5661 + * 5662 + * Since it is not certain that this logic is watertight, 5663 + * we keep the line and merely exclude it from coverage 5664 + * tests. 5665 + */ 5666 + eventPtr = ptr; /* LCOV_EXCL_LINE */ 5667 + } 5103 5668 return XML_ERROR_RECURSIVE_ENTITY_REF; 5104 5669 } 5105 5670 if (entity->notation) { 5106 5671 if (enc == encoding) 5107 5672 eventPtr = ptr; 5108 5673 return XML_ERROR_BINARY_ENTITY_REF; 5109 5674 } ................................................................................ 5122 5687 entity->open = XML_FALSE; 5123 5688 if (result) 5124 5689 return result; 5125 5690 } 5126 5691 } 5127 5692 break; 5128 5693 default: 5694 + /* The only token returned by XmlAttributeValueTok() that does 5695 + * not have an explicit case here is XML_TOK_PARTIAL_CHAR. 5696 + * Getting that would require an entity name to contain an 5697 + * incomplete XML character (e.g. \xE2\x82); however previous 5698 + * tokenisers will have already recognised and rejected such 5699 + * names before XmlAttributeValueTok() gets a look-in. This 5700 + * default case should be retained as a safety net, but the code 5701 + * excluded from coverage tests. 5702 + * 5703 + * LCOV_EXCL_START 5704 + */ 5129 5705 if (enc == encoding) 5130 5706 eventPtr = ptr; 5131 5707 return XML_ERROR_UNEXPECTED_STATE; 5708 + /* LCOV_EXCL_STOP */ 5132 5709 } 5133 5710 ptr = next; 5134 5711 } 5135 5712 /* not reached */ 5136 5713 } 5137 5714 5138 5715 static enum XML_Error ................................................................................ 5257 5834 if (n < 0) { 5258 5835 if (enc == encoding) 5259 5836 eventPtr = entityTextPtr; 5260 5837 result = XML_ERROR_BAD_CHAR_REF; 5261 5838 goto endEntityValue; 5262 5839 } 5263 5840 n = XmlEncode(n, (ICHAR *)buf); 5264 - if (!n) { 5265 - if (enc == encoding) 5266 - eventPtr = entityTextPtr; 5267 - result = XML_ERROR_BAD_CHAR_REF; 5268 - goto endEntityValue; 5269 - } 5841 + /* The XmlEncode() functions can never return 0 here. That 5842 + * error return happens if the code point passed in is either 5843 + * negative or greater than or equal to 0x110000. The 5844 + * XmlCharRefNumber() functions will all return a number 5845 + * strictly less than 0x110000 or a negative value if an error 5846 + * occurred. The negative value is intercepted above, so 5847 + * XmlEncode() is never passed a value it might return an 5848 + * error for. 5849 + */ 5270 5850 for (i = 0; i < n; i++) { 5271 5851 if (pool->end == pool->ptr && !poolGrow(pool)) { 5272 5852 result = XML_ERROR_NO_MEMORY; 5273 5853 goto endEntityValue; 5274 5854 } 5275 5855 *(pool->ptr)++ = buf[i]; 5276 5856 } ................................................................................ 5283 5863 goto endEntityValue; 5284 5864 case XML_TOK_INVALID: 5285 5865 if (enc == encoding) 5286 5866 eventPtr = next; 5287 5867 result = XML_ERROR_INVALID_TOKEN; 5288 5868 goto endEntityValue; 5289 5869 default: 5870 + /* This default case should be unnecessary -- all the tokens 5871 + * that XmlEntityValueTok() can return have their own explicit 5872 + * cases -- but should be retained for safety. We do however 5873 + * exclude it from the coverage statistics. 5874 + * 5875 + * LCOV_EXCL_START 5876 + */ 5290 5877 if (enc == encoding) 5291 5878 eventPtr = entityTextPtr; 5292 5879 result = XML_ERROR_UNEXPECTED_STATE; 5293 5880 goto endEntityValue; 5881 + /* LCOV_EXCL_STOP */ 5294 5882 } 5295 5883 entityTextPtr = next; 5296 5884 } 5297 5885 endEntityValue: 5298 5886 #ifdef XML_DTD 5299 5887 prologState.inEntityValue = oldInEntityValue; 5300 5888 #endif /* XML_DTD */ ................................................................................ 5384 5972 const char **eventPP; 5385 5973 const char **eventEndPP; 5386 5974 if (enc == encoding) { 5387 5975 eventPP = &eventPtr; 5388 5976 eventEndPP = &eventEndPtr; 5389 5977 } 5390 5978 else { 5979 + /* To get here, two things must be true; the parser must be 5980 + * using a character encoding that is not the same as the 5981 + * encoding passed in, and the encoding passed in must need 5982 + * conversion to the internal format (UTF-8 unless XML_UNICODE 5983 + * is defined). The only occasions on which the encoding passed 5984 + * in is not the same as the parser's encoding are when it is 5985 + * the internal encoding (e.g. a previously defined parameter 5986 + * entity, already converted to internal format). This by 5987 + * definition doesn't need conversion, so the whole branch never 5988 + * gets executed. 5989 + * 5990 + * For safety's sake we don't delete these lines and merely 5991 + * exclude them from coverage statistics. 5992 + * 5993 + * LCOV_EXCL_START 5994 + */ 5391 5995 eventPP = &(openInternalEntities->internalEventPtr); 5392 5996 eventEndPP = &(openInternalEntities->internalEventEndPtr); 5997 + /* LCOV_EXCL_STOP */ 5393 5998 } 5394 5999 do { 5395 6000 ICHAR *dataPtr = (ICHAR *)dataBuf; 5396 6001 convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 5397 6002 *eventEndPP = s; 5398 6003 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); 5399 6004 *eventPP = s; ................................................................................ 5554 6159 int i; 5555 6160 int len; 5556 6161 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) 5557 6162 return NULL; 5558 6163 len = dtd->defaultPrefix.binding->uriLen; 5559 6164 if (namespaceSeparator) 5560 6165 len--; 5561 - for (i = 0; i < len; i++) 5562 - if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) 5563 - return NULL; 6166 + for (i = 0; i < len; i++) { 6167 + if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) { 6168 + /* Because of memory caching, I don't believe this line can be 6169 + * executed. 6170 + * 6171 + * This is part of a loop copying the default prefix binding 6172 + * URI into the parser's temporary string pool. Previously, 6173 + * that URI was copied into the same string pool, with a 6174 + * terminating NUL character, as part of setContext(). When 6175 + * the pool was cleared, that leaves a block definitely big 6176 + * enough to hold the URI on the free block list of the pool. 6177 + * The URI copy in getContext() therefore cannot run out of 6178 + * memory. 6179 + * 6180 + * If the pool is used between the setContext() and 6181 + * getContext() calls, the worst it can do is leave a bigger 6182 + * block on the front of the free list. Given that this is 6183 + * all somewhat inobvious and program logic can be changed, we 6184 + * don't delete the line but we do exclude it from the test 6185 + * coverage statistics. 6186 + */ 6187 + return NULL; /* LCOV_EXCL_LINE */ 6188 + } 6189 + } 5564 6190 needSep = XML_TRUE; 5565 6191 } 5566 6192 5567 6193 hashTableIterInit(&iter, &(dtd->prefixes)); 5568 6194 for (;;) { 5569 6195 int i; 5570 6196 int len; 5571 6197 const XML_Char *s; 5572 6198 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); 5573 6199 if (!prefix) 5574 6200 break; 5575 - if (!prefix->binding) 5576 - continue; 6201 + if (!prefix->binding) { 6202 + /* This test appears to be (justifiable) paranoia. There does 6203 + * not seem to be a way of injecting a prefix without a binding 6204 + * that doesn't get errored long before this function is called. 6205 + * The test should remain for safety's sake, so we instead 6206 + * exclude the following line from the coverage statistics. 6207 + */ 6208 + continue; /* LCOV_EXCL_LINE */ 6209 + } 5577 6210 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) 5578 6211 return NULL; 5579 6212 for (s = prefix->name; *s; s++) 5580 6213 if (!poolAppendChar(&tempPool, *s)) 5581 6214 return NULL; 5582 6215 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) 5583 6216 return NULL; ................................................................................ 5872 6505 sizeof(ELEMENT_TYPE)); 5873 6506 if (!newE) 5874 6507 return 0; 5875 6508 if (oldE->nDefaultAtts) { 5876 6509 newE->defaultAtts = (DEFAULT_ATTRIBUTE *) 5877 6510 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 5878 6511 if (!newE->defaultAtts) { 5879 - ms->free_fcn(newE); 5880 6512 return 0; 5881 6513 } 5882 6514 } 5883 6515 if (oldE->idAtt) 5884 6516 newE->idAtt = (ATTRIBUTE_ID *) 5885 6517 lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); 5886 6518 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; ................................................................................ 6006 6638 keyeq(KEY s1, KEY s2) 6007 6639 { 6008 6640 for (; *s1 == *s2; s1++, s2++) 6009 6641 if (*s1 == 0) 6010 6642 return XML_TRUE; 6011 6643 return XML_FALSE; 6012 6644 } 6645 + 6646 +static size_t 6647 +keylen(KEY s) 6648 +{ 6649 + size_t len = 0; 6650 + for (; *s; s++, len++); 6651 + return len; 6652 +} 6653 + 6654 +static void 6655 +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key) 6656 +{ 6657 + key->k[0] = 0; 6658 + key->k[1] = get_hash_secret_salt(parser); 6659 +} 6013 6660 6014 6661 static unsigned long FASTCALL 6015 6662 hash(XML_Parser parser, KEY s) 6016 6663 { 6017 - unsigned long h = hash_secret_salt; 6018 - while (*s) 6019 - h = CHAR_HASH(h, *s++); 6020 - return h; 6664 + struct siphash state; 6665 + struct sipkey key; 6666 + (void)sip_tobin; 6667 + (void)sip24_valid; 6668 + copy_salt_to_sipkey(parser, &key); 6669 + sip24_init(&state, &key); 6670 + sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); 6671 + return (unsigned long)sip24_final(&state); 6021 6672 } 6022 6673 6023 6674 static NAMED * 6024 6675 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) 6025 6676 { 6026 6677 size_t i; 6027 6678 if (table->size == 0) { ................................................................................ 6222 6873 poolFinish(pool); 6223 6874 return s; 6224 6875 } 6225 6876 6226 6877 static const XML_Char * 6227 6878 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) 6228 6879 { 6229 - if (!pool->ptr && !poolGrow(pool)) 6230 - return NULL; 6880 + if (!pool->ptr && !poolGrow(pool)) { 6881 + /* The following line is unreachable given the current usage of 6882 + * poolCopyStringN(). Currently it is called from exactly one 6883 + * place to copy the text of a simple general entity. By that 6884 + * point, the name of the entity is already stored in the pool, so 6885 + * pool->ptr cannot be NULL. 6886 + * 6887 + * If poolCopyStringN() is used elsewhere as it well might be, 6888 + * this line may well become executable again. Regardless, this 6889 + * sort of check shouldn't be removed lightly, so we just exclude 6890 + * it from the coverage statistics. 6891 + */ 6892 + return NULL; /* LCOV_EXCL_LINE */ 6893 + } 6231 6894 for (; n > 0; --n, s++) { 6232 6895 if (!poolAppendChar(pool, *s)) 6233 6896 return NULL; 6234 6897 } 6235 6898 s = pool->start; 6236 6899 poolFinish(pool); 6237 6900 return s; ................................................................................ 6255 6918 if (!poolAppend(pool, enc, ptr, end)) 6256 6919 return NULL; 6257 6920 if (pool->ptr == pool->end && !poolGrow(pool)) 6258 6921 return NULL; 6259 6922 *(pool->ptr)++ = 0; 6260 6923 return pool->start; 6261 6924 } 6925 + 6926 +static size_t 6927 +poolBytesToAllocateFor(int blockSize) 6928 +{ 6929 + /* Unprotected math would be: 6930 + ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); 6931 + ** 6932 + ** Detect overflow, avoiding _signed_ overflow undefined behavior 6933 + ** For a + b * c we check b * c in isolation first, so that addition of a 6934 + ** on top has no chance of making us accept a small non-negative number 6935 + */ 6936 + const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ 6937 + 6938 + if (blockSize <= 0) 6939 + return 0; 6940 + 6941 + if (blockSize > (int)(INT_MAX / stretch)) 6942 + return 0; 6943 + 6944 + { 6945 + const int stretchedBlockSize = blockSize * (int)stretch; 6946 + const int bytesToAllocate = (int)( 6947 + offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); 6948 + if (bytesToAllocate < 0) 6949 + return 0; 6950 + 6951 + return (size_t)bytesToAllocate; 6952 + } 6953 +} 6262 6954 6263 6955 static XML_Bool FASTCALL 6264 6956 poolGrow(STRING_POOL *pool) 6265 6957 { 6266 6958 if (pool->freeBlocks) { 6267 6959 if (pool->start == 0) { 6268 6960 pool->blocks = pool->freeBlocks; ................................................................................ 6285 6977 pool->end = pool->start + pool->blocks->size; 6286 6978 return XML_TRUE; 6287 6979 } 6288 6980 } 6289 6981 if (pool->blocks && pool->start == pool->blocks->s) { 6290 6982 BLOCK *temp; 6291 6983 int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); 6984 + size_t bytesToAllocate; 6292 6985 6293 - if (blockSize < 0) 6986 + // NOTE: Needs to be calculated prior to calling `realloc` 6987 + // to avoid dangling pointers: 6988 + const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; 6989 + 6990 + if (blockSize < 0) { 6991 + /* This condition traps a situation where either more than 6992 + * INT_MAX/2 bytes have already been allocated. This isn't 6993 + * readily testable, since it is unlikely that an average 6994 + * machine will have that much memory, so we exclude it from the 6995 + * coverage statistics. 6996 + */ 6997 + return XML_FALSE; /* LCOV_EXCL_LINE */ 6998 + } 6999 + 7000 + bytesToAllocate = poolBytesToAllocateFor(blockSize); 7001 + if (bytesToAllocate == 0) 6294 7002 return XML_FALSE; 6295 7003 6296 7004 temp = (BLOCK *) 6297 - pool->mem->realloc_fcn(pool->blocks, 6298 - (offsetof(BLOCK, s) 6299 - + blockSize * sizeof(XML_Char))); 7005 + pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); 6300 7006 if (temp == NULL) 6301 7007 return XML_FALSE; 6302 7008 pool->blocks = temp; 6303 7009 pool->blocks->size = blockSize; 6304 - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 7010 + pool->ptr = pool->blocks->s + offsetInsideBlock; 6305 7011 pool->start = pool->blocks->s; 6306 7012 pool->end = pool->start + blockSize; 6307 7013 } 6308 7014 else { 6309 7015 BLOCK *tem; 6310 7016 int blockSize = (int)(pool->end - pool->start); 7017 + size_t bytesToAllocate; 6311 7018 6312 - if (blockSize < 0) 6313 - return XML_FALSE; 7019 + if (blockSize < 0) { 7020 + /* This condition traps a situation where either more than 7021 + * INT_MAX bytes have already been allocated (which is prevented 7022 + * by various pieces of program logic, not least this one, never 7023 + * mind the unlikelihood of actually having that much memory) or 7024 + * the pool control fields have been corrupted (which could 7025 + * conceivably happen in an extremely buggy user handler 7026 + * function). Either way it isn't readily testable, so we 7027 + * exclude it from the coverage statistics. 7028 + */ 7029 + return XML_FALSE; /* LCOV_EXCL_LINE */ 7030 + } 6314 7031 6315 7032 if (blockSize < INIT_BLOCK_SIZE) 6316 7033 blockSize = INIT_BLOCK_SIZE; 6317 - else 7034 + else { 7035 + /* Detect overflow, avoiding _signed_ overflow undefined behavior */ 7036 + if ((int)((unsigned)blockSize * 2U) < 0) { 7037 + return XML_FALSE; 7038 + } 6318 7039 blockSize *= 2; 6319 - tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) 6320 - + blockSize * sizeof(XML_Char)); 7040 + } 7041 + 7042 + bytesToAllocate = poolBytesToAllocateFor(blockSize); 7043 + if (bytesToAllocate == 0) 7044 + return XML_FALSE; 7045 + 7046 + tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); 6321 7047 if (!tem) 6322 7048 return XML_FALSE; 6323 7049 tem->size = blockSize; 6324 7050 tem->next = pool->blocks; 6325 7051 pool->blocks = tem; 6326 7052 if (pool->ptr != pool->start) 6327 7053 memcpy(tem->s, pool->start, ................................................................................ 6460 7186 else { 6461 7187 poolFinish(&dtd->pool); 6462 7188 if (!setElementTypePrefix(parser, ret)) 6463 7189 return NULL; 6464 7190 } 6465 7191 return ret; 6466 7192 } 7193 + 7194 +static XML_Char * 7195 +copyString(const XML_Char *s, 7196 + const XML_Memory_Handling_Suite *memsuite) 7197 +{ 7198 + int charsRequired = 0; 7199 + XML_Char *result; 7200 + 7201 + /* First determine how long the string is */ 7202 + while (s[charsRequired] != 0) { 7203 + charsRequired++; 7204 + } 7205 + /* Include the terminator */ 7206 + charsRequired++; 7207 + 7208 + /* Now allocate space for the copy */ 7209 + result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); 7210 + if (result == NULL) 7211 + return NULL; 7212 + /* Copy the original into place */ 7213 + memcpy(result, s, charsRequired * sizeof(XML_Char)); 7214 + return result; 7215 +}
Changes to expat/xmlrole.c.
1 1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd 2 2 See the file COPYING for copying permission. 3 3 */ 4 4 5 5 #include <stddef.h> 6 6 7 -#ifdef WIN32 7 +#ifdef _WIN32 8 8 #include "winconfig.h" 9 -#elif defined(MACOS_CLASSIC) 10 -#include "macconfig.h" 11 -#elif defined(__amigaos__) 12 -#include "amigaconfig.h" 13 -#elif defined(__WATCOMC__) 14 -#include "watcomconfig.h" 15 9 #else 16 10 #ifdef HAVE_EXPAT_CONFIG_H 17 11 #include <expat_config.h> 18 12 #endif 19 -#endif /* ndef WIN32 */ 13 +#endif /* ndef _WIN32 */ 20 14 21 15 #include "expat_external.h" 22 16 #include "internal.h" 23 17 #include "xmlrole.h" 24 18 #include "ascii.h" 25 19 26 20 /* Doesn't check: ................................................................................ 172 166 case XML_TOK_PROLOG_S: 173 167 return XML_ROLE_NONE; 174 168 case XML_TOK_PI: 175 169 return XML_ROLE_PI; 176 170 case XML_TOK_COMMENT: 177 171 return XML_ROLE_COMMENT; 178 172 case XML_TOK_BOM: 179 - return XML_ROLE_NONE; 173 + /* This case can never arise. To reach this role function, the 174 + * parse must have passed through prolog0 and therefore have had 175 + * some form of input, even if only a space. At that point, a 176 + * byte order mark is no longer a valid character (though 177 + * technically it should be interpreted as a non-breaking space), 178 + * so will be rejected by the tokenizing stages. 179 + */ 180 + return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ 180 181 case XML_TOK_DECL_OPEN: 181 182 if (!XmlNameMatchesAscii(enc, 182 183 ptr + 2 * MIN_BYTES_PER_CHAR(enc), 183 184 end, 184 185 KW_DOCTYPE)) 185 186 break; 186 187 state->handler = doctype0; ................................................................................ 1287 1288 case XML_TOK_DECL_CLOSE: 1288 1289 setTopLevel(state); 1289 1290 return state->role_none; 1290 1291 } 1291 1292 return common(state, tok); 1292 1293 } 1293 1294 1295 +/* This function will only be invoked if the internal logic of the 1296 + * parser has broken down. It is used in two cases: 1297 + * 1298 + * 1: When the XML prolog has been finished. At this point the 1299 + * processor (the parser level above these role handlers) should 1300 + * switch from prologProcessor to contentProcessor and reinitialise 1301 + * the handler function. 1302 + * 1303 + * 2: When an error has been detected (via common() below). At this 1304 + * point again the processor should be switched to errorProcessor, 1305 + * which will never call a handler. 1306 + * 1307 + * The result of this is that error() can only be called if the 1308 + * processor switch failed to happen, which is an internal error and 1309 + * therefore we shouldn't be able to provoke it simply by using the 1310 + * library. It is a necessary backstop, however, so we merely exclude 1311 + * it from the coverage statistics. 1312 + * 1313 + * LCOV_EXCL_START 1314 + */ 1294 1315 static int PTRCALL 1295 1316 error(PROLOG_STATE *UNUSED_P(state), 1296 1317 int UNUSED_P(tok), 1297 1318 const char *UNUSED_P(ptr), 1298 1319 const char *UNUSED_P(end), 1299 1320 const ENCODING *UNUSED_P(enc)) 1300 1321 { 1301 1322 return XML_ROLE_NONE; 1302 1323 } 1324 +/* LCOV_EXCL_STOP */ 1303 1325 1304 1326 static int FASTCALL 1305 1327 common(PROLOG_STATE *state, int tok) 1306 1328 { 1307 1329 #ifdef XML_DTD 1308 1330 if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) 1309 1331 return XML_ROLE_INNER_PARAM_ENTITY_REF;
Changes to expat/xmltok.c.
1 1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd 2 2 See the file COPYING for copying permission. 3 3 */ 4 4 5 5 #include <stddef.h> 6 6 7 -#ifdef WIN32 7 +#ifdef _WIN32 8 8 #include "winconfig.h" 9 -#elif defined(MACOS_CLASSIC) 10 -#include "macconfig.h" 11 -#elif defined(__amigaos__) 12 -#include "amigaconfig.h" 13 -#elif defined(__WATCOMC__) 14 -#include "watcomconfig.h" 15 9 #else 16 10 #ifdef HAVE_EXPAT_CONFIG_H 17 11 #include <expat_config.h> 18 12 #endif 19 -#endif /* ndef WIN32 */ 13 +#endif /* ndef _WIN32 */ 20 14 21 15 #include "expat_external.h" 22 16 #include "internal.h" 23 17 #include "xmltok.h" 24 18 #include "nametab.h" 25 19 26 20 #ifdef XML_DTD ................................................................................ 365 359 } 366 360 367 361 static enum XML_Convert_Result PTRCALL 368 362 utf8_toUtf8(const ENCODING *UNUSED_P(enc), 369 363 const char **fromP, const char *fromLim, 370 364 char **toP, const char *toLim) 371 365 { 372 - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; 373 366 char *to; 374 367 const char *from; 375 - if (fromLim - *fromP > toLim - *toP) { 376 - /* Avoid copying partial characters. */ 377 - res = XML_CONVERT_OUTPUT_EXHAUSTED; 378 - fromLim = *fromP + (toLim - *toP); 379 - align_limit_to_full_utf8_characters(*fromP, &fromLim); 380 - } 368 + const char *fromLimInitial = fromLim; 369 + 370 + /* Avoid copying partial characters. */ 371 + align_limit_to_full_utf8_characters(*fromP, &fromLim); 372 + 381 373 for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) 382 374 *to = *from; 383 375 *fromP = from; 384 376 *toP = to; 385 377 386 - if ((to == toLim) && (from < fromLim)) 378 + if (fromLim < fromLimInitial) 379 + return XML_CONVERT_INPUT_INCOMPLETE; 380 + else if ((to == toLim) && (from < fromLim)) 387 381 return XML_CONVERT_OUTPUT_EXHAUSTED; 388 382 else 389 - return res; 383 + return XML_CONVERT_COMPLETED; 390 384 } 391 385 392 386 static enum XML_Convert_Result PTRCALL 393 387 utf8_toUtf16(const ENCODING *enc, 394 388 const char **fromP, const char *fromLim, 395 389 unsigned short **toP, const unsigned short *toLim) 396 390 { ................................................................................ 398 392 unsigned short *to = *toP; 399 393 const char *from = *fromP; 400 394 while (from < fromLim && to < toLim) { 401 395 switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { 402 396 case BT_LEAD2: 403 397 if (fromLim - from < 2) { 404 398 res = XML_CONVERT_INPUT_INCOMPLETE; 405 - break; 399 + goto after; 406 400 } 407 401 *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); 408 402 from += 2; 409 403 break; 410 404 case BT_LEAD3: 411 405 if (fromLim - from < 3) { 412 406 res = XML_CONVERT_INPUT_INCOMPLETE; 413 - break; 407 + goto after; 414 408 } 415 409 *to++ = (unsigned short)(((from[0] & 0xf) << 12) 416 410 | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); 417 411 from += 3; 418 412 break; 419 413 case BT_LEAD4: 420 414 { ................................................................................ 437 431 } 438 432 break; 439 433 default: 440 434 *to++ = *from++; 441 435 break; 442 436 } 443 437 } 438 + if (from < fromLim) 439 + res = XML_CONVERT_OUTPUT_EXHAUSTED; 444 440 after: 445 441 *fromP = from; 446 442 *toP = to; 447 443 return res; 448 444 } 449 445 450 446 #ifdef XML_NS ................................................................................ 1019 1015 { 1020 1016 for (;;) { 1021 1017 char c1 = *s1++; 1022 1018 char c2 = *s2++; 1023 1019 if (ASCII_a <= c1 && c1 <= ASCII_z) 1024 1020 c1 += ASCII_A - ASCII_a; 1025 1021 if (ASCII_a <= c2 && c2 <= ASCII_z) 1026 - c2 += ASCII_A - ASCII_a; 1022 + /* The following line will never get executed. streqci() is 1023 + * only called from two places, both of which guarantee to put 1024 + * upper-case strings into s2. 1025 + */ 1026 + c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ 1027 1027 if (c1 != c2) 1028 1028 return 0; 1029 1029 if (!c1) 1030 1030 break; 1031 1031 } 1032 1032 return 1; 1033 1033 } ................................................................................ 1291 1291 /* minN is minimum legal resulting value for N byte sequence */ 1292 1292 min2 = 0x80, 1293 1293 min3 = 0x800, 1294 1294 min4 = 0x10000 1295 1295 }; 1296 1296 1297 1297 if (c < 0) 1298 - return 0; 1298 + return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ 1299 1299 if (c < min2) { 1300 1300 buf[0] = (char)(c | UTF8_cval1); 1301 1301 return 1; 1302 1302 } 1303 1303 if (c < min3) { 1304 1304 buf[0] = (char)((c >> 6) | UTF8_cval2); 1305 1305 buf[1] = (char)((c & 0x3f) | 0x80); ................................................................................ 1314 1314 if (c < 0x110000) { 1315 1315 buf[0] = (char)((c >> 18) | UTF8_cval4); 1316 1316 buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); 1317 1317 buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); 1318 1318 buf[3] = (char)((c & 0x3f) | 0x80); 1319 1319 return 4; 1320 1320 } 1321 - return 0; 1321 + return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ 1322 1322 } 1323 1323 1324 1324 int FASTCALL 1325 1325 XmlUtf16Encode(int charNum, unsigned short *buf) 1326 1326 { 1327 1327 if (charNum < 0) 1328 1328 return 0; ................................................................................ 1464 1464 /* This shouldn't really get used. */ 1465 1465 e->utf16[i] = 0xFFFF; 1466 1466 e->utf8[i][0] = 1; 1467 1467 e->utf8[i][1] = 0; 1468 1468 } 1469 1469 else if (c < 0) { 1470 1470 if (c < -4) 1471 + return 0; 1472 + /* Multi-byte sequences need a converter function */ 1473 + if (!convert) 1471 1474 return 0; 1472 1475 e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); 1473 1476 e->utf8[i][0] = 0; 1474 1477 e->utf16[i] = 0; 1475 1478 } 1476 1479 else if (c < 0x80) { 1477 1480 if (latin1_encoding.type[c] != BT_OTHER
Changes to expat/xmltok_impl.c.
1194 1194 static int PTRCALL 1195 1195 PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, 1196 1196 const char *end, const char **nextTokPtr) 1197 1197 { 1198 1198 const char *start; 1199 1199 if (ptr >= end) 1200 1200 return XML_TOK_NONE; 1201 - else if (! HAS_CHAR(enc, ptr, end)) 1202 - return XML_TOK_PARTIAL; 1201 + else if (! HAS_CHAR(enc, ptr, end)) { 1202 + /* This line cannot be executed. The incoming data has already 1203 + * been tokenized once, so incomplete characters like this have 1204 + * already been eliminated from the input. Retaining the paranoia 1205 + * check is still valuable, however. 1206 + */ 1207 + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ 1208 + } 1203 1209 start = ptr; 1204 1210 while (HAS_CHAR(enc, ptr, end)) { 1205 1211 switch (BYTE_TYPE(enc, ptr)) { 1206 1212 #define LEAD_CASE(n) \ 1207 1213 case BT_LEAD ## n: ptr += n; break; 1208 1214 LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) 1209 1215 #undef LEAD_CASE ................................................................................ 1254 1260 static int PTRCALL 1255 1261 PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, 1256 1262 const char *end, const char **nextTokPtr) 1257 1263 { 1258 1264 const char *start; 1259 1265 if (ptr >= end) 1260 1266 return XML_TOK_NONE; 1261 - else if (! HAS_CHAR(enc, ptr, end)) 1262 - return XML_TOK_PARTIAL; 1267 + else if (! HAS_CHAR(enc, ptr, end)) { 1268 + /* This line cannot be executed. The incoming data has already 1269 + * been tokenized once, so incomplete characters like this have 1270 + * already been eliminated from the input. Retaining the paranoia 1271 + * check is still valuable, however. 1272 + */ 1273 + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ 1274 + } 1263 1275 start = ptr; 1264 1276 while (HAS_CHAR(enc, ptr, end)) { 1265 1277 switch (BYTE_TYPE(enc, ptr)) { 1266 1278 #define LEAD_CASE(n) \ 1267 1279 case BT_LEAD ## n: ptr += n; break; 1268 1280 LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) 1269 1281 #undef LEAD_CASE ................................................................................ 1610 1622 } 1611 1623 break; 1612 1624 } 1613 1625 } 1614 1626 return 0; 1615 1627 } 1616 1628 1629 +/* This function does not appear to be called from anywhere within the 1630 + * library code. It is used via the macro XmlSameName(), which is 1631 + * defined but never used. Since it appears in the encoding function 1632 + * table, removing it is not a thing to be undertaken lightly. For 1633 + * the moment, we simply exclude it from coverage tests. 1634 + * 1635 + * LCOV_EXCL_START 1636 + */ 1617 1637 static int PTRCALL 1618 1638 PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) 1619 1639 { 1620 1640 for (;;) { 1621 1641 switch (BYTE_TYPE(enc, ptr1)) { 1622 1642 #define LEAD_CASE(n) \ 1623 1643 case BT_LEAD ## n: \ ................................................................................ 1673 1693 default: 1674 1694 return 1; 1675 1695 } 1676 1696 } 1677 1697 } 1678 1698 /* not reached */ 1679 1699 } 1700 +/* LCOV_EXCL_STOP */ 1680 1701 1681 1702 static int PTRCALL 1682 1703 PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, 1683 1704 const char *end1, const char *ptr2) 1684 1705 { 1685 1706 for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { 1686 - if (end1 - ptr1 < MINBPC(enc)) 1687 - return 0; 1707 + if (end1 - ptr1 < MINBPC(enc)) { 1708 + /* This line cannot be executed. THe incoming data has already 1709 + * been tokenized once, so imcomplete characters like this have 1710 + * already been eliminated from the input. Retaining the 1711 + * paranoia check is still valuable, however. 1712 + */ 1713 + return 0; /* LCOV_EXCL_LINE */ 1714 + } 1688 1715 if (!CHAR_MATCHES(enc, ptr1, *ptr2)) 1689 1716 return 0; 1690 1717 } 1691 1718 return ptr1 == end1; 1692 1719 } 1693 1720 1694 1721 static int PTRFASTCALL
Changes to tdom.m4.
356 356 ]) 357 357 if test x"${ac_cv_c_expat}" = x ; then 358 358 AC_MSG_RESULT([Using bundled expat distribution]) 359 359 TEA_ADD_SOURCES([expat/xmlrole.c \ 360 360 expat/xmltok.c \ 361 361 expat/xmlparse.c]) 362 362 TEA_ADD_INCLUDES([-I${srcdir}/expat]) 363 + AC_DEFINE([XML_POOR_ENTROPY], 1, 364 + [Define to use poor entropy in lack of better source.]) 363 365 else 364 366 AC_MSG_RESULT([Using shared expat found in ${ac_cv_c_expat}]) 365 367 TEA_ADD_INCLUDES(-I${ac_cv_c_expat}/include) 366 368 TEA_ADD_LIBS([-lexpat]) 367 369 fi 368 370 ]) 369 371
Changes to win/makefile.vc.
268 268 !if !$(STATIC_BUILD) 269 269 cflags = $(cflags) -DUSE_TCL_STUBS 270 270 !if defined(TKSTUBLIB) 271 271 cflags = $(cflags) -DUSE_TK_STUBS 272 272 !endif 273 273 !endif 274 274 275 -DEFS =-DHAVE_MEMMOVE=1 -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 275 +DEFS =-DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 276 276 DEFS_EXPAT =-DXMLIMPORT=__declspec(dllexport) 277 277 INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" $(TCL_INCLUDES) 278 278 !if "$(GUMBODIR)" != "" 279 279 DEFS = $(DEFS) -DTDOM_HAVE_GUMBO=1 280 280 INCLUDES = $(INCLUDES) -I"$(GUMBODIR)\src" 281 281 !endif 282 282 BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES)