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)