Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch expat-update Excluding Merge-Ins
This is equivalent to a diff from 6fcae124ae to f540486a07
2022-01-27
| ||
13:37 | Fixed memory leak in case of dom parsing w/ a -validateCmd which is in use. check-in: 436f9b8957 user: rolf tags: trunk | |
2022-01-15
| ||
16:39 | Start integrate new BillionLaughsAttackProtection featurs. Closed-Leaf check-in: f540486a07 user: rolf tags: expat-update | |
16:29 | Expat 2.4.2 check-in: 3c331ee575 user: rolf tags: expat-update | |
2022-01-10
| ||
01:35 | Fixed argument check of a few schema commands. check-in: 6fcae124ae user: rolf tags: trunk | |
01:07 | Fixed possible bufffer overrun because of too small buffer for a sprintf. check-in: c18371f74a user: rolf tags: trunk | |
Changes to expat/VERSION.
1 -expat-2.3.0 1 +expat-2.4.2
Changes to expat/ascii.h.
2 2 __ __ _ 3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 9 + Copyright (c) 1999-2000 Thai Open Source Software Center Ltd 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2007 Karl Waclawek <karl@waclawek.net> 13 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 14 Licensed under the MIT license: 12 15 13 16 Permission is hereby granted, free of charge, to any person obtaining 14 17 a copy of this software and associated documentation files (the 15 18 "Software"), to deal in the Software without restriction, including 16 19 without limitation the rights to use, copy, modify, merge, publish, 17 20 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/asciitab.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 13 Licensed under the MIT license: 12 14 13 15 Permission is hereby granted, free of charge, to any person obtaining 14 16 a copy of this software and associated documentation files (the 15 17 "Software"), to deal in the Software without restriction, including 16 18 without limitation the rights to use, copy, modify, merge, publish, 17 19 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/expat.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> 13 + Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 14 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 15 + Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org> 16 + Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> 17 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 11 18 Licensed under the MIT license: 12 19 13 20 Permission is hereby granted, free of charge, to any person obtaining 14 21 a copy of this software and associated documentation files (the 15 22 "Software"), to deal in the Software without restriction, including 16 23 without limitation the rights to use, copy, modify, merge, publish, 17 24 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 113 120 /* Added in 2.0. */ 114 121 XML_ERROR_RESERVED_PREFIX_XML, 115 122 XML_ERROR_RESERVED_PREFIX_XMLNS, 116 123 XML_ERROR_RESERVED_NAMESPACE_URI, 117 124 /* Added in 2.2.1. */ 118 125 XML_ERROR_INVALID_ARGUMENT, 119 126 /* Added in 2.3.0. */ 120 - XML_ERROR_NO_BUFFER 127 + XML_ERROR_NO_BUFFER, 128 + /* Added in 2.4.0. */ 129 + XML_ERROR_AMPLIFICATION_LIMIT_BREACH 121 130 }; 122 131 123 132 enum XML_Content_Type { 124 133 XML_CTYPE_EMPTY = 1, 125 134 XML_CTYPE_ANY, 126 135 XML_CTYPE_MIXED, 127 136 XML_CTYPE_NAME, ................................................................................ 995 1004 XML_FEATURE_DTD, 996 1005 XML_FEATURE_CONTEXT_BYTES, 997 1006 XML_FEATURE_MIN_SIZE, 998 1007 XML_FEATURE_SIZEOF_XML_CHAR, 999 1008 XML_FEATURE_SIZEOF_XML_LCHAR, 1000 1009 XML_FEATURE_NS, 1001 1010 XML_FEATURE_LARGE_SIZE, 1002 - XML_FEATURE_ATTR_INFO 1011 + XML_FEATURE_ATTR_INFO, 1012 + /* Added in Expat 2.4.0. */ 1013 + XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, 1014 + XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT 1003 1015 /* Additional features must be added to the end of this enum. */ 1004 1016 }; 1005 1017 1006 1018 typedef struct { 1007 1019 enum XML_FeatureEnum feature; 1008 1020 const XML_LChar *name; 1009 1021 long int value; 1010 1022 } XML_Feature; 1011 1023 1012 1024 XMLPARSEAPI(const XML_Feature *) 1013 1025 XML_GetFeatureList(void); 1026 + 1027 +#ifdef XML_DTD 1028 +/* Added in Expat 2.4.0. */ 1029 +XMLPARSEAPI(XML_Bool) 1030 +XML_SetBillionLaughsAttackProtectionMaximumAmplification( 1031 + XML_Parser parser, float maximumAmplificationFactor); 1032 + 1033 +/* Added in Expat 2.4.0. */ 1034 +XMLPARSEAPI(XML_Bool) 1035 +XML_SetBillionLaughsAttackProtectionActivationThreshold( 1036 + XML_Parser parser, unsigned long long activationThresholdBytes); 1037 +#endif 1014 1038 1015 1039 /* Expat follows the semantic versioning convention. 1016 1040 See http://semver.org. 1017 1041 */ 1018 1042 #define XML_MAJOR_VERSION 2 1019 -#define XML_MINOR_VERSION 3 1020 -#define XML_MICRO_VERSION 0 1043 +#define XML_MINOR_VERSION 4 1044 +#define XML_MICRO_VERSION 2 1021 1045 1022 1046 #ifdef __cplusplus 1023 1047 } 1024 1048 #endif 1025 1049 1026 1050 #endif /* not Expat_INCLUDED */
Changes to expat/expat_external.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> 13 + Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> 14 + Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org> 15 + Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org> 16 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 17 + Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> 11 18 Licensed under the MIT license: 12 19 13 20 Permission is hereby granted, free of charge, to any person obtaining 14 21 a copy of this software and associated documentation files (the 15 22 "Software"), to deal in the Software without restriction, including 16 23 without limitation the rights to use, copy, modify, merge, publish, 17 24 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/iasciitab.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 13 Licensed under the MIT license: 12 14 13 15 Permission is hereby granted, free of charge, to any person obtaining 14 16 a copy of this software and associated documentation files (the 15 17 "Software"), to deal in the Software without restriction, including 16 18 without limitation the rights to use, copy, modify, merge, publish, 17 19 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/internal.h.
21 21 __ __ _ 22 22 ___\ \/ /_ __ __ _| |_ 23 23 / _ \\ /| '_ \ / _` | __| 24 24 | __// \| |_) | (_| | |_ 25 25 \___/_/\_\ .__/ \__,_|\__| 26 26 |_| XML parser 27 27 28 - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 29 - Copyright (c) 2000-2017 Expat development team 28 + Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 29 + Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> 30 + Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> 31 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 32 + Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> 33 + Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 30 34 Licensed under the MIT license: 31 35 32 36 Permission is hereby granted, free of charge, to any person obtaining 33 37 a copy of this software and associated documentation files (the 34 38 "Software"), to deal in the Software without restriction, including 35 39 without limitation the rights to use, copy, modify, merge, publish, 36 40 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 96 100 #ifdef __cplusplus 97 101 # define inline inline 98 102 #else 99 103 # ifndef inline 100 104 # define inline 101 105 # endif 102 106 #endif 107 + 108 +#include <limits.h> // ULONG_MAX 109 + 110 +#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO) 111 +# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u" 112 +# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW 113 +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d" 114 +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u" 115 +# else 116 +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" 117 +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" 118 +# endif 119 +#else 120 +# define EXPAT_FMT_ULL(midpart) "%" midpart "llu" 121 +# if ! defined(ULONG_MAX) 122 +# error Compiler did not define ULONG_MAX for us 123 +# elif ULONG_MAX == 18446744073709551615u // 2^64-1 124 +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" 125 +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu" 126 +# else 127 +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" 128 +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" 129 +# endif 130 +#endif 103 131 104 132 #ifndef UNUSED_P 105 133 # define UNUSED_P(p) (void)p 106 134 #endif 135 + 136 +/* NOTE BEGIN If you ever patch these defaults to greater values 137 + for non-attack XML payload in your environment, 138 + please file a bug report with libexpat. Thank you! 139 +*/ 140 +#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \ 141 + 100.0f 142 +#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \ 143 + 8388608 // 8 MiB, 2^23 144 +/* NOTE END */ 145 + 146 +#include "expat.h" // so we can use type XML_Parser below 107 147 108 148 #ifdef __cplusplus 109 149 extern "C" { 110 150 #endif 111 151 112 -#ifdef XML_ENABLE_VISIBILITY 113 -# if XML_ENABLE_VISIBILITY 114 -__attribute__((visibility("default"))) 115 -# endif 152 +void _INTERNAL_trim_to_complete_utf8_characters(const char *from, 153 + const char **fromLimRef); 154 + 155 +#if defined(XML_DTD) 156 +unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser); 157 +unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); 158 +const char *unsignedCharToPrintable(unsigned char c); 116 159 #endif 117 -void 118 -_INTERNAL_trim_to_complete_utf8_characters(const char *from, 119 - const char **fromLimRef); 120 160 121 161 #ifdef __cplusplus 122 162 } 123 163 #endif
Changes to expat/latin1tab.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 13 Licensed under the MIT license: 12 14 13 15 Permission is hereby granted, free of charge, to any person obtaining 14 16 a copy of this software and associated documentation files (the 15 17 "Software"), to deal in the Software without restriction, including 16 18 without limitation the rights to use, copy, modify, merge, publish, 17 19 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/nametab.h.
2 2 __ __ _ 3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 9 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 10 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 11 Licensed under the MIT license: 12 12 13 13 Permission is hereby granted, free of charge, to any person obtaining 14 14 a copy of this software and associated documentation files (the 15 15 "Software"), to deal in the Software without restriction, including 16 16 without limitation the rights to use, copy, modify, merge, publish, 17 17 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/utf8tab.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 13 Licensed under the MIT license: 12 14 13 15 Permission is hereby granted, free of charge, to any person obtaining 14 16 a copy of this software and associated documentation files (the 15 17 "Software"), to deal in the Software without restriction, including 16 18 without limitation the rights to use, copy, modify, merge, publish, 17 19 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/winconfig.h.
2 2 __ __ _ 3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 9 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 10 + Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> 11 + Copyright (c) 2005 Karl Waclawek <karl@waclawek.net> 12 + Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org> 11 13 Licensed under the MIT license: 12 14 13 15 Permission is hereby granted, free of charge, to any person obtaining 14 16 a copy of this software and associated documentation files (the 15 17 "Software"), to deal in the Software without restriction, including 16 18 without limitation the rights to use, copy, modify, merge, publish, 17 19 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 36 38 #define WIN32_LEAN_AND_MEAN 37 39 #include <windows.h> 38 40 #undef WIN32_LEAN_AND_MEAN 39 41 40 42 #include <memory.h> 41 43 #include <string.h> 42 44 43 -#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ 44 -# include <expat_config.h> 45 -#else /* !defined(HAVE_EXPAT_CONFIG_H) */ 46 - 47 -# define XML_NS 1 48 -# define XML_DTD 1 49 -# define XML_CONTEXT_BYTES 1024 50 - 51 -/* we will assume all Windows platforms are little endian */ 52 -# define BYTEORDER 1234 53 - 54 -#endif /* !defined(HAVE_EXPAT_CONFIG_H) */ 55 - 56 45 #endif /* ndef WINCONFIG_H */
Changes to expat/xmlparse.c.
1 -/* d667b5f8e56e24fdfaf5e38596d419d924a9fadceb987d81d5613ecb7ca51b0e (2.3.0+) 1 +/* 0550bc9a27b099d462d8d1007271cfeaa39852f20cd0d5d2caeadaeb39516fbe (2.4.2+) 2 2 __ __ _ 3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> 13 + Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 14 + Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net> 15 + Copyright (c) 2016 Eric Rahm <erahm@mozilla.com> 16 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 17 + Copyright (c) 2016 Gaurav <g.gupta@samsung.com> 18 + Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> 19 + Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr> 20 + Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> 21 + Copyright (c) 2016 Ed Schouten <ed@nuxi.nl> 22 + Copyright (c) 2017-2018 Rhodri James <rhodri@wildebeest.org.uk> 23 + Copyright (c) 2017 Václav Slavík <vaclav@slavik.io> 24 + Copyright (c) 2017 Viktor Szakats <commit@vsz.me> 25 + Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com> 26 + Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de> 27 + Copyright (c) 2017 Hans Wennborg <hans@chromium.org> 28 + Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com> 29 + Copyright (c) 2018 Benjamin Peterson <benjamin@python.org> 30 + Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> 31 + Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org> 32 + Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 33 + Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org> 34 + Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org> 35 + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> 11 36 Licensed under the MIT license: 12 37 13 38 Permission is hereby granted, free of charge, to any person obtaining 14 39 a copy of this software and associated documentation files (the 15 40 "Software"), to deal in the Software without restriction, including 16 41 without limitation the rights to use, copy, modify, merge, publish, 17 42 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 25 50 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 51 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 52 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 53 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 54 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 55 USE OR OTHER DEALINGS IN THE SOFTWARE. 31 56 */ 57 + 58 +#define XML_BUILDING_EXPAT 1 59 + 60 +#include <expat_config.h> 32 61 33 62 #if ! defined(_GNU_SOURCE) 34 63 # define _GNU_SOURCE 1 /* syscall prototype */ 35 64 #endif 36 65 37 66 #ifdef _WIN32 38 67 /* force stdlib to define rand_s() */ ................................................................................ 44 73 #include <stddef.h> 45 74 #include <string.h> /* memset(), memcpy() */ 46 75 #include <assert.h> 47 76 #include <limits.h> /* UINT_MAX */ 48 77 #include <stdio.h> /* fprintf */ 49 78 #include <stdlib.h> /* getenv, rand_s */ 50 79 #include <stdint.h> /* uintptr_t */ 80 +#include <math.h> /* isnan */ 51 81 52 82 #ifdef _WIN32 53 83 # define getpid GetCurrentProcessId 54 84 #else 55 85 # include <sys/time.h> /* gettimeofday() */ 56 86 # include <sys/types.h> /* getpid() */ 57 87 # include <unistd.h> /* getpid() */ 58 88 # include <fcntl.h> /* O_RDONLY */ 59 89 # include <errno.h> 60 90 #endif 61 91 62 -#define XML_BUILDING_EXPAT 1 63 - 64 92 #ifdef _WIN32 65 93 # include "winconfig.h" 66 -#elif defined(HAVE_EXPAT_CONFIG_H) 67 -# include <expat_config.h> 68 -#endif /* ndef _WIN32 */ 94 +#endif 69 95 70 96 #include "ascii.h" 71 97 #include "expat.h" 72 98 #include "siphash.h" 73 99 74 100 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 75 101 # if defined(HAVE_GETRANDOM) ................................................................................ 368 394 const char *internalEventEndPtr; 369 395 struct open_internal_entity *next; 370 396 ENTITY *entity; 371 397 int startTagLevel; 372 398 XML_Bool betweenDecl; /* WFC: PE Between Declarations */ 373 399 } OPEN_INTERNAL_ENTITY; 374 400 401 +enum XML_Account { 402 + XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */ 403 + XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity 404 + expansion */ 405 + XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */ 406 +}; 407 + 408 +#ifdef XML_DTD 409 +typedef unsigned long long XmlBigCount; 410 +typedef struct accounting { 411 + XmlBigCount countBytesDirect; 412 + XmlBigCount countBytesIndirect; 413 + int debugLevel; 414 + float maximumAmplificationFactor; // >=1.0 415 + unsigned long long activationThresholdBytes; 416 +} ACCOUNTING; 417 + 418 +typedef struct entity_stats { 419 + unsigned int countEverOpened; 420 + unsigned int currentDepth; 421 + unsigned int maximumDepthSeen; 422 + int debugLevel; 423 +} ENTITY_STATS; 424 +#endif /* XML_DTD */ 425 + 375 426 typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, 376 427 const char *end, const char **endPtr); 377 428 378 429 static Processor prologProcessor; 379 430 static Processor prologInitProcessor; 380 431 static Processor contentProcessor; 381 432 static Processor cdataSectionProcessor; ................................................................................ 398 449 const XML_Char *encodingName); 399 450 static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 400 451 const char *s, const char *next); 401 452 static enum XML_Error initializeEncoding(XML_Parser parser); 402 453 static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, 403 454 const char *s, const char *end, int tok, 404 455 const char *next, const char **nextPtr, 405 - XML_Bool haveMore, XML_Bool allowClosingDoctype); 456 + XML_Bool haveMore, XML_Bool allowClosingDoctype, 457 + enum XML_Account account); 406 458 static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, 407 459 XML_Bool betweenDecl); 408 460 static enum XML_Error doContent(XML_Parser parser, int startTagLevel, 409 461 const ENCODING *enc, const char *start, 410 462 const char *end, const char **endPtr, 411 - XML_Bool haveMore); 463 + XML_Bool haveMore, enum XML_Account account); 412 464 static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, 413 465 const char **startPtr, const char *end, 414 - const char **nextPtr, XML_Bool haveMore); 466 + const char **nextPtr, XML_Bool haveMore, 467 + enum XML_Account account); 415 468 #ifdef XML_DTD 416 469 static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, 417 470 const char **startPtr, const char *end, 418 471 const char **nextPtr, XML_Bool haveMore); 419 472 #endif /* XML_DTD */ 420 473 421 474 static void freeBindings(XML_Parser parser, BINDING *bindings); 422 475 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, 423 476 const char *s, TAG_NAME *tagNamePtr, 424 - BINDING **bindingsPtr); 477 + BINDING **bindingsPtr, 478 + enum XML_Account account); 425 479 static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, 426 480 const ATTRIBUTE_ID *attId, const XML_Char *uri, 427 481 BINDING **bindingsPtr); 428 482 static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 429 483 XML_Bool isId, const XML_Char *dfltValue, 430 484 XML_Parser parser); 431 485 static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, 432 486 XML_Bool isCdata, const char *, 433 - const char *, STRING_POOL *); 487 + const char *, STRING_POOL *, 488 + enum XML_Account account); 434 489 static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, 435 490 XML_Bool isCdata, const char *, 436 - const char *, STRING_POOL *); 491 + const char *, STRING_POOL *, 492 + enum XML_Account account); 437 493 static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, 438 494 const char *start, const char *end); 439 495 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); 440 496 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, 441 - const char *start, const char *end); 497 + const char *start, const char *end, 498 + enum XML_Account account); 442 499 static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 443 500 const char *start, const char *end); 444 501 static int reportComment(XML_Parser parser, const ENCODING *enc, 445 502 const char *start, const char *end); 446 503 static void reportDefault(XML_Parser parser, const ENCODING *enc, 447 504 const char *start, const char *end); 448 505 ................................................................................ 498 555 499 556 static XML_Parser parserCreate(const XML_Char *encodingName, 500 557 const XML_Memory_Handling_Suite *memsuite, 501 558 const XML_Char *nameSep, DTD *dtd); 502 559 503 560 static void parserInit(XML_Parser parser, const XML_Char *encodingName); 504 561 562 +#ifdef XML_DTD 563 +static float accountingGetCurrentAmplification(XML_Parser rootParser); 564 +static void accountingReportStats(XML_Parser originParser, const char *epilog); 565 +static void accountingOnAbort(XML_Parser originParser); 566 +static void accountingReportDiff(XML_Parser rootParser, 567 + unsigned int levelsAwayFromRootParser, 568 + const char *before, const char *after, 569 + ptrdiff_t bytesMore, int source_line, 570 + enum XML_Account account); 571 +static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, 572 + const char *before, const char *after, 573 + int source_line, 574 + enum XML_Account account); 575 + 576 +static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity, 577 + const char *action, int sourceLine); 578 +static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity, 579 + int sourceLine); 580 +static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity, 581 + int sourceLine); 582 + 583 +static XML_Parser getRootParserOf(XML_Parser parser, 584 + unsigned int *outLevelDiff); 585 +#endif /* XML_DTD */ 586 + 587 +static unsigned long getDebugLevel(const char *variableName, 588 + unsigned long defaultDebugLevel); 589 + 505 590 #define poolStart(pool) ((pool)->start) 506 591 #define poolEnd(pool) ((pool)->ptr) 507 592 #define poolLength(pool) ((pool)->ptr - (pool)->start) 508 593 #define poolChop(pool) ((void)--(pool->ptr)) 509 594 #define poolLastChar(pool) (((pool)->ptr)[-1]) 510 595 #define poolDiscard(pool) ((pool)->ptr = (pool)->start) 511 596 #define poolFinish(pool) ((pool)->start = (pool)->ptr) ................................................................................ 611 696 XML_ParsingStatus m_parsingStatus; 612 697 #ifdef XML_DTD 613 698 XML_Bool m_isParamEntity; 614 699 XML_Bool m_useForeignDTD; 615 700 enum XML_ParamEntityParsing m_paramEntityParsing; 616 701 #endif 617 702 unsigned long m_hash_secret_salt; 703 +#ifdef XML_DTD 704 + ACCOUNTING m_accounting; 705 + ENTITY_STATS m_entity_stats; 706 +#endif 618 707 }; 619 708 620 709 #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) 621 710 #define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) 622 711 #define FREE(parser, p) (parser->m_mem.free_fcn((p))) 623 712 624 713 XML_Parser XMLCALL ................................................................................ 795 884 # endif 796 885 } 797 886 798 887 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 799 888 800 889 static unsigned long 801 890 ENTROPY_DEBUG(const char *label, unsigned long entropy) { 802 - const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); 803 - if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { 804 - fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, 891 + if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) { 892 + fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, 805 893 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); 806 894 } 807 895 return entropy; 808 896 } 809 897 810 898 static unsigned long 811 899 generate_hash_secret_salt(XML_Parser parser) { ................................................................................ 1059 1147 parser->m_parsingStatus.parsing = XML_INITIALIZED; 1060 1148 #ifdef XML_DTD 1061 1149 parser->m_isParamEntity = XML_FALSE; 1062 1150 parser->m_useForeignDTD = XML_FALSE; 1063 1151 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 1064 1152 #endif 1065 1153 parser->m_hash_secret_salt = 0; 1154 + 1155 +#ifdef XML_DTD 1156 + memset(&parser->m_accounting, 0, sizeof(ACCOUNTING)); 1157 + parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u); 1158 + parser->m_accounting.maximumAmplificationFactor 1159 + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT; 1160 + parser->m_accounting.activationThresholdBytes 1161 + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT; 1162 + 1163 + memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS)); 1164 + parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u); 1165 +#endif 1066 1166 } 1067 1167 1068 1168 /* moves list of bindings to m_freeBindingList */ 1069 1169 static void FASTCALL 1070 1170 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { 1071 1171 while (bindings) { 1072 1172 BINDING *b = bindings; ................................................................................ 2333 2433 /* Added in 2.2.5. */ 2334 2434 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ 2335 2435 return XML_L("invalid argument"); 2336 2436 /* Added in 2.3.0. */ 2337 2437 case XML_ERROR_NO_BUFFER: 2338 2438 return XML_L( 2339 2439 "a successful prior call to function XML_GetBuffer is required"); 2440 + /* Added in 2.4.0. */ 2441 + case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: 2442 + return XML_L( 2443 + "limit on input amplification factor (from DTD and entities) breached"); 2340 2444 } 2341 2445 return NULL; 2342 2446 } 2343 2447 2344 2448 const XML_LChar *XMLCALL 2345 2449 XML_ExpatVersion(void) { 2346 2450 /* V1 is used to string-ize the version number. However, it would ................................................................................ 2369 2473 version.micro = XML_MICRO_VERSION; 2370 2474 2371 2475 return version; 2372 2476 } 2373 2477 2374 2478 const XML_Feature *XMLCALL 2375 2479 XML_GetFeatureList(void) { 2376 - static const XML_Feature features[] 2377 - = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 2378 - sizeof(XML_Char)}, 2379 - {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 2380 - sizeof(XML_LChar)}, 2480 + static const XML_Feature features[] = { 2481 + {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 2482 + sizeof(XML_Char)}, 2483 + {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 2484 + sizeof(XML_LChar)}, 2381 2485 #ifdef XML_UNICODE 2382 - {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 2486 + {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 2383 2487 #endif 2384 2488 #ifdef XML_UNICODE_WCHAR_T 2385 - {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 2489 + {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 2386 2490 #endif 2387 2491 #ifdef XML_DTD 2388 - {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 2492 + {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 2389 2493 #endif 2390 2494 #ifdef XML_CONTEXT_BYTES 2391 - {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 2392 - XML_CONTEXT_BYTES}, 2495 + {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 2496 + XML_CONTEXT_BYTES}, 2393 2497 #endif 2394 2498 #ifdef XML_MIN_SIZE 2395 - {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 2499 + {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 2396 2500 #endif 2397 2501 #ifdef XML_NS 2398 - {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 2502 + {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 2399 2503 #endif 2400 2504 #ifdef XML_LARGE_SIZE 2401 - {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, 2505 + {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, 2402 2506 #endif 2403 2507 #ifdef XML_ATTR_INFO 2404 - {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, 2508 + {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, 2405 2509 #endif 2406 - {XML_FEATURE_END, NULL, 0}}; 2510 +#ifdef XML_DTD 2511 + /* Added in Expat 2.4.0. */ 2512 + {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, 2513 + XML_L("XML_BLAP_MAX_AMP"), 2514 + (long int) 2515 + EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT}, 2516 + {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, 2517 + XML_L("XML_BLAP_ACT_THRES"), 2518 + EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT}, 2519 +#endif 2520 + {XML_FEATURE_END, NULL, 0}}; 2407 2521 2408 2522 return features; 2409 2523 } 2410 2524 2525 +#ifdef XML_DTD 2526 +XML_Bool XMLCALL 2527 +XML_SetBillionLaughsAttackProtectionMaximumAmplification( 2528 + XML_Parser parser, float maximumAmplificationFactor) { 2529 + if ((parser == NULL) || (parser->m_parentParser != NULL) 2530 + || isnan(maximumAmplificationFactor) 2531 + || (maximumAmplificationFactor < 1.0f)) { 2532 + return XML_FALSE; 2533 + } 2534 + parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor; 2535 + return XML_TRUE; 2536 +} 2537 + 2538 +XML_Bool XMLCALL 2539 +XML_SetBillionLaughsAttackProtectionActivationThreshold( 2540 + XML_Parser parser, unsigned long long activationThresholdBytes) { 2541 + if ((parser == NULL) || (parser->m_parentParser != NULL)) { 2542 + return XML_FALSE; 2543 + } 2544 + parser->m_accounting.activationThresholdBytes = activationThresholdBytes; 2545 + return XML_TRUE; 2546 +} 2547 +#endif /* XML_DTD */ 2548 + 2411 2549 /* Initially tag->rawName always points into the parse buffer; 2412 2550 for those TAG instances opened while the current parse buffer was 2413 2551 processed, and not yet closed, we need to store tag->rawName in a more 2414 2552 permanent location, since the parse buffer is about to be discarded. 2415 2553 */ 2416 2554 static XML_Bool 2417 2555 storeRawNames(XML_Parser parser) { ................................................................................ 2456 2594 } 2457 2595 return XML_TRUE; 2458 2596 } 2459 2597 2460 2598 static enum XML_Error PTRCALL 2461 2599 contentProcessor(XML_Parser parser, const char *start, const char *end, 2462 2600 const char **endPtr) { 2463 - enum XML_Error result 2464 - = doContent(parser, 0, parser->m_encoding, start, end, endPtr, 2465 - (XML_Bool)! parser->m_parsingStatus.finalBuffer); 2601 + enum XML_Error result = doContent( 2602 + parser, 0, parser->m_encoding, start, end, endPtr, 2603 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 2466 2604 if (result == XML_ERROR_NONE) { 2467 2605 if (! storeRawNames(parser)) 2468 2606 return XML_ERROR_NO_MEMORY; 2469 2607 } 2470 2608 return result; 2471 2609 } 2472 2610 ................................................................................ 2483 2621 static enum XML_Error PTRCALL 2484 2622 externalEntityInitProcessor2(XML_Parser parser, const char *start, 2485 2623 const char *end, const char **endPtr) { 2486 2624 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2487 2625 int tok = XmlContentTok(parser->m_encoding, start, end, &next); 2488 2626 switch (tok) { 2489 2627 case XML_TOK_BOM: 2628 +#ifdef XML_DTD 2629 + if (! accountingDiffTolerated(parser, tok, start, next, __LINE__, 2630 + XML_ACCOUNT_DIRECT)) { 2631 + accountingOnAbort(parser); 2632 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 2633 + } 2634 +#endif /* XML_DTD */ 2635 + 2490 2636 /* If we are at the end of the buffer, this would cause the next stage, 2491 2637 i.e. externalEntityInitProcessor3, to pass control directly to 2492 2638 doContent (by detecting XML_TOK_NONE) without processing any xml text 2493 2639 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 2494 2640 */ 2495 2641 if (next == end && ! parser->m_parsingStatus.finalBuffer) { 2496 2642 *endPtr = next; ................................................................................ 2520 2666 static enum XML_Error PTRCALL 2521 2667 externalEntityInitProcessor3(XML_Parser parser, const char *start, 2522 2668 const char *end, const char **endPtr) { 2523 2669 int tok; 2524 2670 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2525 2671 parser->m_eventPtr = start; 2526 2672 tok = XmlContentTok(parser->m_encoding, start, end, &next); 2673 + /* Note: These bytes are accounted later in: 2674 + - processXmlDecl 2675 + - externalEntityContentProcessor 2676 + */ 2527 2677 parser->m_eventEndPtr = next; 2528 2678 2529 2679 switch (tok) { 2530 2680 case XML_TOK_XML_DECL: { 2531 2681 enum XML_Error result; 2532 2682 result = processXmlDecl(parser, 1, start, next); 2533 2683 if (result != XML_ERROR_NONE) ................................................................................ 2561 2711 } 2562 2712 2563 2713 static enum XML_Error PTRCALL 2564 2714 externalEntityContentProcessor(XML_Parser parser, const char *start, 2565 2715 const char *end, const char **endPtr) { 2566 2716 enum XML_Error result 2567 2717 = doContent(parser, 1, parser->m_encoding, start, end, endPtr, 2568 - (XML_Bool)! parser->m_parsingStatus.finalBuffer); 2718 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, 2719 + XML_ACCOUNT_ENTITY_EXPANSION); 2569 2720 if (result == XML_ERROR_NONE) { 2570 2721 if (! storeRawNames(parser)) 2571 2722 return XML_ERROR_NO_MEMORY; 2572 2723 } 2573 2724 return result; 2574 2725 } 2575 2726 2576 2727 static enum XML_Error 2577 2728 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, 2578 2729 const char *s, const char *end, const char **nextPtr, 2579 - XML_Bool haveMore) { 2730 + XML_Bool haveMore, enum XML_Account account) { 2580 2731 /* save one level of indirection */ 2581 2732 DTD *const dtd = parser->m_dtd; 2582 2733 2583 2734 const char **eventPP; 2584 2735 const char **eventEndPP; 2585 2736 if (enc == parser->m_encoding) { 2586 2737 eventPP = &parser->m_eventPtr; ................................................................................ 2590 2741 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 2591 2742 } 2592 2743 *eventPP = s; 2593 2744 2594 2745 for (;;) { 2595 2746 const char *next = s; /* XmlContentTok doesn't always set the last arg */ 2596 2747 int tok = XmlContentTok(enc, s, end, &next); 2748 +#ifdef XML_DTD 2749 + const char *accountAfter 2750 + = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR)) 2751 + ? (haveMore ? s /* i.e. 0 bytes */ : end) 2752 + : next; 2753 + if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__, 2754 + account)) { 2755 + accountingOnAbort(parser); 2756 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 2757 + } 2758 +#endif 2597 2759 *eventEndPP = next; 2598 2760 switch (tok) { 2599 2761 case XML_TOK_TRAILING_CR: 2600 2762 if (haveMore) { 2601 2763 *nextPtr = s; 2602 2764 return XML_ERROR_NONE; 2603 2765 } ................................................................................ 2645 2807 return XML_ERROR_PARTIAL_CHAR; 2646 2808 case XML_TOK_ENTITY_REF: { 2647 2809 const XML_Char *name; 2648 2810 ENTITY *entity; 2649 2811 XML_Char ch = (XML_Char)XmlPredefinedEntityName( 2650 2812 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); 2651 2813 if (ch) { 2814 +#ifdef XML_DTD 2815 + /* NOTE: We are replacing 4-6 characters original input for 1 character 2816 + * so there is no amplification and hence recording without 2817 + * protection. */ 2818 + accountingDiffTolerated(parser, tok, (char *)&ch, 2819 + ((char *)&ch) + sizeof(XML_Char), __LINE__, 2820 + XML_ACCOUNT_ENTITY_EXPANSION); 2821 +#endif /* XML_DTD */ 2652 2822 if (parser->m_characterDataHandler) 2653 2823 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); 2654 2824 else if (parser->m_defaultHandler) 2655 2825 reportDefault(parser, enc, s, next); 2656 2826 break; 2657 2827 } 2658 2828 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, ................................................................................ 2763 2933 tag->bufEnd = temp + bufSize; 2764 2934 toPtr = (XML_Char *)temp + convLen; 2765 2935 } 2766 2936 } 2767 2937 } 2768 2938 tag->name.str = (XML_Char *)tag->buf; 2769 2939 *toPtr = XML_T('\0'); 2770 - result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); 2940 + result 2941 + = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); 2771 2942 if (result) 2772 2943 return result; 2773 2944 if (parser->m_startElementHandler) 2774 2945 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, 2775 2946 (const XML_Char **)parser->m_atts); 2776 2947 else if (parser->m_defaultHandler) 2777 2948 reportDefault(parser, enc, s, next); ................................................................................ 2787 2958 XML_Bool noElmHandlers = XML_TRUE; 2788 2959 TAG_NAME name; 2789 2960 name.str = poolStoreString(&parser->m_tempPool, enc, rawName, 2790 2961 rawName + XmlNameLength(enc, rawName)); 2791 2962 if (! name.str) 2792 2963 return XML_ERROR_NO_MEMORY; 2793 2964 poolFinish(&parser->m_tempPool); 2794 - result = storeAtts(parser, enc, s, &name, &bindings); 2965 + result = storeAtts(parser, enc, s, &name, &bindings, 2966 + XML_ACCOUNT_NONE /* token spans whole start tag */); 2795 2967 if (result != XML_ERROR_NONE) { 2796 2968 freeBindings(parser, bindings); 2797 2969 return result; 2798 2970 } 2799 2971 poolFinish(&parser->m_tempPool); 2800 2972 if (parser->m_startElementHandler) { 2801 2973 parser->m_startElementHandler(parser->m_handlerArg, name.str, ................................................................................ 2922 3094 */ 2923 3095 else if (0 && parser->m_characterDataHandler) 2924 3096 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 2925 3097 0); 2926 3098 /* END disabled code */ 2927 3099 else if (parser->m_defaultHandler) 2928 3100 reportDefault(parser, enc, s, next); 2929 - result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); 3101 + result 3102 + = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account); 2930 3103 if (result != XML_ERROR_NONE) 2931 3104 return result; 2932 3105 else if (! next) { 2933 3106 parser->m_processor = cdataSectionProcessor; 2934 3107 return result; 2935 3108 } 2936 3109 } break; ................................................................................ 3051 3224 - build list of attributes for startElementHandler 3052 3225 - default attributes 3053 3226 - process namespace declarations (check and report them) 3054 3227 - generate namespace aware element name (URI, prefix) 3055 3228 */ 3056 3229 static enum XML_Error 3057 3230 storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, 3058 - TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { 3231 + TAG_NAME *tagNamePtr, BINDING **bindingsPtr, 3232 + enum XML_Account account) { 3059 3233 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 3060 3234 ELEMENT_TYPE *elementType; 3061 3235 int nDefaultAtts; 3062 3236 const XML_Char **appAtts; /* the attribute list for the application */ 3063 3237 int attIndex = 0; 3064 3238 int prefixLen; 3065 3239 int i; ................................................................................ 3161 3335 } 3162 3336 } 3163 3337 } 3164 3338 3165 3339 /* normalize the attribute value */ 3166 3340 result = storeAttributeValue( 3167 3341 parser, enc, isCdata, parser->m_atts[i].valuePtr, 3168 - parser->m_atts[i].valueEnd, &parser->m_tempPool); 3342 + parser->m_atts[i].valueEnd, &parser->m_tempPool, account); 3169 3343 if (result) 3170 3344 return result; 3171 3345 appAtts[attIndex] = poolStart(&parser->m_tempPool); 3172 3346 poolFinish(&parser->m_tempPool); 3173 3347 } else { 3174 3348 /* the value did not need normalizing */ 3175 3349 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, ................................................................................ 3550 3724 3551 3725 /* The idea here is to avoid using stack for each CDATA section when 3552 3726 the whole file is parsed with one call. 3553 3727 */ 3554 3728 static enum XML_Error PTRCALL 3555 3729 cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, 3556 3730 const char **endPtr) { 3557 - enum XML_Error result 3558 - = doCdataSection(parser, parser->m_encoding, &start, end, endPtr, 3559 - (XML_Bool)! parser->m_parsingStatus.finalBuffer); 3731 + enum XML_Error result = doCdataSection( 3732 + parser, parser->m_encoding, &start, end, endPtr, 3733 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 3560 3734 if (result != XML_ERROR_NONE) 3561 3735 return result; 3562 3736 if (start) { 3563 3737 if (parser->m_parentParser) { /* we are parsing an external entity */ 3564 3738 parser->m_processor = externalEntityContentProcessor; 3565 3739 return externalEntityContentProcessor(parser, start, end, endPtr); 3566 3740 } else { ................................................................................ 3572 3746 } 3573 3747 3574 3748 /* startPtr gets set to non-null if the section is closed, and to null if 3575 3749 the section is not yet closed. 3576 3750 */ 3577 3751 static enum XML_Error 3578 3752 doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, 3579 - const char *end, const char **nextPtr, XML_Bool haveMore) { 3753 + const char *end, const char **nextPtr, XML_Bool haveMore, 3754 + enum XML_Account account) { 3580 3755 const char *s = *startPtr; 3581 3756 const char **eventPP; 3582 3757 const char **eventEndPP; 3583 3758 if (enc == parser->m_encoding) { 3584 3759 eventPP = &parser->m_eventPtr; 3585 3760 *eventPP = s; 3586 3761 eventEndPP = &parser->m_eventEndPtr; ................................................................................ 3590 3765 } 3591 3766 *eventPP = s; 3592 3767 *startPtr = NULL; 3593 3768 3594 3769 for (;;) { 3595 3770 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ 3596 3771 int tok = XmlCdataSectionTok(enc, s, end, &next); 3772 +#ifdef XML_DTD 3773 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 3774 + accountingOnAbort(parser); 3775 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 3776 + } 3777 +#else 3778 + UNUSED_P(account); 3779 +#endif 3597 3780 *eventEndPP = next; 3598 3781 switch (tok) { 3599 3782 case XML_TOK_CDATA_SECT_CLOSE: 3600 3783 if (parser->m_endCdataSectionHandler) 3601 3784 parser->m_endCdataSectionHandler(parser->m_handlerArg); 3602 3785 /* BEGIN disabled code */ 3603 3786 /* see comment under XML_TOK_CDATA_SECT_OPEN */ ................................................................................ 3734 3917 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 3735 3918 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 3736 3919 /* LCOV_EXCL_STOP */ 3737 3920 } 3738 3921 *eventPP = s; 3739 3922 *startPtr = NULL; 3740 3923 tok = XmlIgnoreSectionTok(enc, s, end, &next); 3924 +# ifdef XML_DTD 3925 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 3926 + XML_ACCOUNT_DIRECT)) { 3927 + accountingOnAbort(parser); 3928 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 3929 + } 3930 +# endif 3741 3931 *eventEndPP = next; 3742 3932 switch (tok) { 3743 3933 case XML_TOK_IGNORE_SECT: 3744 3934 if (parser->m_defaultHandler) 3745 3935 reportDefault(parser, enc, s, next); 3746 3936 *startPtr = next; 3747 3937 *nextPtr = next; ................................................................................ 3818 4008 const char *encodingName = NULL; 3819 4009 const XML_Char *storedEncName = NULL; 3820 4010 const ENCODING *newEncoding = NULL; 3821 4011 const char *version = NULL; 3822 4012 const char *versionend; 3823 4013 const XML_Char *storedversion = NULL; 3824 4014 int standalone = -1; 4015 + 4016 +#ifdef XML_DTD 4017 + if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__, 4018 + XML_ACCOUNT_DIRECT)) { 4019 + accountingOnAbort(parser); 4020 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4021 + } 4022 +#endif 4023 + 3825 4024 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( 3826 4025 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, 3827 4026 &version, &versionend, &encodingName, &newEncoding, &standalone)) { 3828 4027 if (isGeneralTextEntity) 3829 4028 return XML_ERROR_TEXT_DECL; 3830 4029 else 3831 4030 return XML_ERROR_XML_DECL; ................................................................................ 3967 4166 int tok; 3968 4167 const char *start = s; 3969 4168 const char *next = start; 3970 4169 parser->m_eventPtr = start; 3971 4170 3972 4171 for (;;) { 3973 4172 tok = XmlPrologTok(parser->m_encoding, start, end, &next); 4173 + /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in: 4174 + - storeEntityValue 4175 + - processXmlDecl 4176 + */ 3974 4177 parser->m_eventEndPtr = next; 3975 4178 if (tok <= 0) { 3976 4179 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 3977 4180 *nextPtr = s; 3978 4181 return XML_ERROR_NONE; 3979 4182 } 3980 4183 switch (tok) { ................................................................................ 3985 4188 case XML_TOK_PARTIAL_CHAR: 3986 4189 return XML_ERROR_PARTIAL_CHAR; 3987 4190 case XML_TOK_NONE: /* start == end */ 3988 4191 default: 3989 4192 break; 3990 4193 } 3991 4194 /* found end of entity value - can store it now */ 3992 - return storeEntityValue(parser, parser->m_encoding, s, end); 4195 + return storeEntityValue(parser, parser->m_encoding, s, end, 4196 + XML_ACCOUNT_DIRECT); 3993 4197 } else if (tok == XML_TOK_XML_DECL) { 3994 4198 enum XML_Error result; 3995 4199 result = processXmlDecl(parser, 0, start, next); 3996 4200 if (result != XML_ERROR_NONE) 3997 4201 return result; 3998 4202 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For 3999 4203 * that to happen, a parameter entity parsing handler must have attempted ................................................................................ 4012 4216 function to exit with *nextPtr set to s - that is what we want for other 4013 4217 tokens, but not for the BOM - we would rather like to skip it; 4014 4218 then, when this routine is entered the next time, XmlPrologTok will 4015 4219 return XML_TOK_INVALID, since the BOM is still in the buffer 4016 4220 */ 4017 4221 else if (tok == XML_TOK_BOM && next == end 4018 4222 && ! parser->m_parsingStatus.finalBuffer) { 4223 +# ifdef XML_DTD 4224 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 4225 + XML_ACCOUNT_DIRECT)) { 4226 + accountingOnAbort(parser); 4227 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4228 + } 4229 +# endif 4230 + 4019 4231 *nextPtr = next; 4020 4232 return XML_ERROR_NONE; 4021 4233 } 4022 4234 /* If we get this token, we have the start of what might be a 4023 4235 normal tag, but not a declaration (i.e. it doesn't begin with 4024 4236 "<!"). In a DTD context, that isn't legal. 4025 4237 */ ................................................................................ 4054 4266 case XML_TOK_NONE: /* start == end */ 4055 4267 default: 4056 4268 break; 4057 4269 } 4058 4270 } 4059 4271 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 4060 4272 However, when parsing an external subset, doProlog will not accept a BOM 4061 - as valid, and report a syntax error, so we have to skip the BOM 4273 + as valid, and report a syntax error, so we have to skip the BOM, and 4274 + account for the BOM bytes. 4062 4275 */ 4063 4276 else if (tok == XML_TOK_BOM) { 4277 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 4278 + XML_ACCOUNT_DIRECT)) { 4279 + accountingOnAbort(parser); 4280 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4281 + } 4282 + 4064 4283 s = next; 4065 4284 tok = XmlPrologTok(parser->m_encoding, s, end, &next); 4066 4285 } 4067 4286 4068 4287 parser->m_processor = prologProcessor; 4069 4288 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 4070 - (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); 4289 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 4290 + XML_ACCOUNT_DIRECT); 4071 4291 } 4072 4292 4073 4293 static enum XML_Error PTRCALL 4074 4294 entityValueProcessor(XML_Parser parser, const char *s, const char *end, 4075 4295 const char **nextPtr) { 4076 4296 const char *start = s; 4077 4297 const char *next = s; 4078 4298 const ENCODING *enc = parser->m_encoding; 4079 4299 int tok; 4080 4300 4081 4301 for (;;) { 4082 4302 tok = XmlPrologTok(enc, start, end, &next); 4303 + /* Note: These bytes are accounted later in: 4304 + - storeEntityValue 4305 + */ 4083 4306 if (tok <= 0) { 4084 4307 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 4085 4308 *nextPtr = s; 4086 4309 return XML_ERROR_NONE; 4087 4310 } 4088 4311 switch (tok) { 4089 4312 case XML_TOK_INVALID: ................................................................................ 4093 4316 case XML_TOK_PARTIAL_CHAR: 4094 4317 return XML_ERROR_PARTIAL_CHAR; 4095 4318 case XML_TOK_NONE: /* start == end */ 4096 4319 default: 4097 4320 break; 4098 4321 } 4099 4322 /* found end of entity value - can store it now */ 4100 - return storeEntityValue(parser, enc, s, end); 4323 + return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); 4101 4324 } 4102 4325 start = next; 4103 4326 } 4104 4327 } 4105 4328 4106 4329 #endif /* XML_DTD */ 4107 4330 4108 4331 static enum XML_Error PTRCALL 4109 4332 prologProcessor(XML_Parser parser, const char *s, const char *end, 4110 4333 const char **nextPtr) { 4111 4334 const char *next = s; 4112 4335 int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 4113 4336 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 4114 - (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); 4337 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 4338 + XML_ACCOUNT_DIRECT); 4115 4339 } 4116 4340 4117 4341 static enum XML_Error 4118 4342 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, 4119 4343 int tok, const char *next, const char **nextPtr, XML_Bool haveMore, 4120 - XML_Bool allowClosingDoctype) { 4344 + XML_Bool allowClosingDoctype, enum XML_Account account) { 4121 4345 #ifdef XML_DTD 4122 4346 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; 4123 4347 #endif /* XML_DTD */ 4124 4348 static const XML_Char atypeCDATA[] 4125 4349 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; 4126 4350 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; 4127 4351 static const XML_Char atypeIDREF[] ................................................................................ 4139 4363 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, 4140 4364 ASCII_E, ASCII_N, ASCII_S, '\0'}; 4141 4365 static const XML_Char notationPrefix[] 4142 4366 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, 4143 4367 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; 4144 4368 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; 4145 4369 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; 4370 + 4371 +#ifndef XML_DTD 4372 + UNUSED_P(account); 4373 +#endif 4146 4374 4147 4375 /* save one level of indirection */ 4148 4376 DTD *const dtd = parser->m_dtd; 4149 4377 4150 4378 const char **eventPP; 4151 4379 const char **eventEndPP; 4152 4380 enum XML_Content_Quant quant; ................................................................................ 4204 4432 default: 4205 4433 tok = -tok; 4206 4434 next = end; 4207 4435 break; 4208 4436 } 4209 4437 } 4210 4438 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); 4439 +#ifdef XML_DTD 4440 + switch (role) { 4441 + case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor 4442 + case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl 4443 + case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl 4444 + break; 4445 + default: 4446 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 4447 + accountingOnAbort(parser); 4448 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4449 + } 4450 + } 4451 +#endif 4211 4452 switch (role) { 4212 4453 case XML_ROLE_XML_DECL: { 4213 4454 enum XML_Error result = processXmlDecl(parser, 0, s, next); 4214 4455 if (result != XML_ERROR_NONE) 4215 4456 return result; 4216 4457 enc = parser->m_encoding; 4217 4458 handleDefault = XML_FALSE; ................................................................................ 4479 4720 break; 4480 4721 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 4481 4722 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 4482 4723 if (dtd->keepProcessing) { 4483 4724 const XML_Char *attVal; 4484 4725 enum XML_Error result = storeAttributeValue( 4485 4726 parser, enc, parser->m_declAttributeIsCdata, 4486 - s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool); 4727 + s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool, 4728 + XML_ACCOUNT_NONE); 4487 4729 if (result) 4488 4730 return result; 4489 4731 attVal = poolStart(&dtd->pool); 4490 4732 poolFinish(&dtd->pool); 4491 4733 /* ID attributes aren't allowed to have a default */ 4492 4734 if (! defineAttribute( 4493 4735 parser->m_declElementType, parser->m_declAttributeId, ................................................................................ 4512 4754 poolClear(&parser->m_tempPool); 4513 4755 handleDefault = XML_FALSE; 4514 4756 } 4515 4757 } 4516 4758 break; 4517 4759 case XML_ROLE_ENTITY_VALUE: 4518 4760 if (dtd->keepProcessing) { 4519 - enum XML_Error result = storeEntityValue( 4520 - parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); 4761 + enum XML_Error result 4762 + = storeEntityValue(parser, enc, s + enc->minBytesPerChar, 4763 + next - enc->minBytesPerChar, XML_ACCOUNT_NONE); 4521 4764 if (parser->m_declEntity) { 4522 4765 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); 4523 4766 parser->m_declEntity->textLen 4524 4767 = (int)(poolLength(&dtd->entityValuePool)); 4525 4768 poolFinish(&dtd->entityValuePool); 4526 4769 if (parser->m_entityDeclHandler) { 4527 4770 *eventEndPP = s; ................................................................................ 4903 5146 return result; 4904 5147 handleDefault = XML_FALSE; 4905 5148 break; 4906 5149 } 4907 5150 if (parser->m_externalEntityRefHandler) { 4908 5151 dtd->paramEntityRead = XML_FALSE; 4909 5152 entity->open = XML_TRUE; 5153 + entityTrackingOnOpen(parser, entity, __LINE__); 4910 5154 if (! parser->m_externalEntityRefHandler( 4911 5155 parser->m_externalEntityRefHandlerArg, 0, entity->base, 4912 5156 entity->systemId, entity->publicId)) { 5157 + entityTrackingOnClose(parser, entity, __LINE__); 4913 5158 entity->open = XML_FALSE; 4914 5159 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 4915 5160 } 5161 + entityTrackingOnClose(parser, entity, __LINE__); 4916 5162 entity->open = XML_FALSE; 4917 5163 handleDefault = XML_FALSE; 4918 5164 if (! dtd->paramEntityRead) { 4919 5165 dtd->keepProcessing = dtd->standalone; 4920 5166 break; 4921 5167 } 4922 5168 } else { ................................................................................ 5106 5352 epilogProcessor(XML_Parser parser, const char *s, const char *end, 5107 5353 const char **nextPtr) { 5108 5354 parser->m_processor = epilogProcessor; 5109 5355 parser->m_eventPtr = s; 5110 5356 for (;;) { 5111 5357 const char *next = NULL; 5112 5358 int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 5359 +#ifdef XML_DTD 5360 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 5361 + XML_ACCOUNT_DIRECT)) { 5362 + accountingOnAbort(parser); 5363 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 5364 + } 5365 +#endif 5113 5366 parser->m_eventEndPtr = next; 5114 5367 switch (tok) { 5115 5368 /* report partial linebreak - it might be the last token */ 5116 5369 case -XML_TOK_PROLOG_S: 5117 5370 if (parser->m_defaultHandler) { 5118 5371 reportDefault(parser, parser->m_encoding, s, next); 5119 5372 if (parser->m_parsingStatus.parsing == XML_FINISHED) ................................................................................ 5179 5432 } else { 5180 5433 openEntity 5181 5434 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); 5182 5435 if (! openEntity) 5183 5436 return XML_ERROR_NO_MEMORY; 5184 5437 } 5185 5438 entity->open = XML_TRUE; 5439 +#ifdef XML_DTD 5440 + entityTrackingOnOpen(parser, entity, __LINE__); 5441 +#endif 5186 5442 entity->processed = 0; 5187 5443 openEntity->next = parser->m_openInternalEntities; 5188 5444 parser->m_openInternalEntities = openEntity; 5189 5445 openEntity->entity = entity; 5190 5446 openEntity->startTagLevel = parser->m_tagLevel; 5191 5447 openEntity->betweenDecl = betweenDecl; 5192 5448 openEntity->internalEventPtr = NULL; ................................................................................ 5197 5453 next = textStart; 5198 5454 5199 5455 #ifdef XML_DTD 5200 5456 if (entity->is_param) { 5201 5457 int tok 5202 5458 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 5203 5459 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 5204 - tok, next, &next, XML_FALSE, XML_FALSE); 5460 + tok, next, &next, XML_FALSE, XML_FALSE, 5461 + XML_ACCOUNT_ENTITY_EXPANSION); 5205 5462 } else 5206 5463 #endif /* XML_DTD */ 5207 5464 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, 5208 - textStart, textEnd, &next, XML_FALSE); 5465 + textStart, textEnd, &next, XML_FALSE, 5466 + XML_ACCOUNT_ENTITY_EXPANSION); 5209 5467 5210 5468 if (result == XML_ERROR_NONE) { 5211 5469 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 5212 5470 entity->processed = (int)(next - textStart); 5213 5471 parser->m_processor = internalEntityProcessor; 5214 5472 } else { 5473 +#ifdef XML_DTD 5474 + entityTrackingOnClose(parser, entity, __LINE__); 5475 +#endif /* XML_DTD */ 5215 5476 entity->open = XML_FALSE; 5216 5477 parser->m_openInternalEntities = openEntity->next; 5217 5478 /* put openEntity back in list of free instances */ 5218 5479 openEntity->next = parser->m_freeInternalEntities; 5219 5480 parser->m_freeInternalEntities = openEntity; 5220 5481 } 5221 5482 } ................................................................................ 5240 5501 next = textStart; 5241 5502 5242 5503 #ifdef XML_DTD 5243 5504 if (entity->is_param) { 5244 5505 int tok 5245 5506 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 5246 5507 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 5247 - tok, next, &next, XML_FALSE, XML_TRUE); 5508 + tok, next, &next, XML_FALSE, XML_TRUE, 5509 + XML_ACCOUNT_ENTITY_EXPANSION); 5248 5510 } else 5249 5511 #endif /* XML_DTD */ 5250 5512 result = doContent(parser, openEntity->startTagLevel, 5251 5513 parser->m_internalEncoding, textStart, textEnd, &next, 5252 - XML_FALSE); 5514 + XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); 5253 5515 5254 5516 if (result != XML_ERROR_NONE) 5255 5517 return result; 5256 5518 else if (textEnd != next 5257 5519 && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 5258 5520 entity->processed = (int)(next - (const char *)entity->textPtr); 5259 5521 return result; 5260 5522 } else { 5523 +#ifdef XML_DTD 5524 + entityTrackingOnClose(parser, entity, __LINE__); 5525 +#endif 5261 5526 entity->open = XML_FALSE; 5262 5527 parser->m_openInternalEntities = openEntity->next; 5263 5528 /* put openEntity back in list of free instances */ 5264 5529 openEntity->next = parser->m_freeInternalEntities; 5265 5530 parser->m_freeInternalEntities = openEntity; 5266 5531 } 5267 5532 5268 5533 #ifdef XML_DTD 5269 5534 if (entity->is_param) { 5270 5535 int tok; 5271 5536 parser->m_processor = prologProcessor; 5272 5537 tok = XmlPrologTok(parser->m_encoding, s, end, &next); 5273 5538 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 5274 - (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); 5539 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 5540 + XML_ACCOUNT_DIRECT); 5275 5541 } else 5276 5542 #endif /* XML_DTD */ 5277 5543 { 5278 5544 parser->m_processor = contentProcessor; 5279 5545 /* see externalEntityContentProcessor vs contentProcessor */ 5280 5546 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, 5281 5547 s, end, nextPtr, 5282 - (XML_Bool)! parser->m_parsingStatus.finalBuffer); 5548 + (XML_Bool)! parser->m_parsingStatus.finalBuffer, 5549 + XML_ACCOUNT_DIRECT); 5283 5550 } 5284 5551 } 5285 5552 5286 5553 static enum XML_Error PTRCALL 5287 5554 errorProcessor(XML_Parser parser, const char *s, const char *end, 5288 5555 const char **nextPtr) { 5289 5556 UNUSED_P(s); ................................................................................ 5290 5557 UNUSED_P(end); 5291 5558 UNUSED_P(nextPtr); 5292 5559 return parser->m_errorCode; 5293 5560 } 5294 5561 5295 5562 static enum XML_Error 5296 5563 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 5297 - const char *ptr, const char *end, STRING_POOL *pool) { 5564 + const char *ptr, const char *end, STRING_POOL *pool, 5565 + enum XML_Account account) { 5298 5566 enum XML_Error result 5299 - = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); 5567 + = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account); 5300 5568 if (result) 5301 5569 return result; 5302 5570 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 5303 5571 poolChop(pool); 5304 5572 if (! poolAppendChar(pool, XML_T('\0'))) 5305 5573 return XML_ERROR_NO_MEMORY; 5306 5574 return XML_ERROR_NONE; 5307 5575 } 5308 5576 5309 5577 static enum XML_Error 5310 5578 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 5311 - const char *ptr, const char *end, STRING_POOL *pool) { 5579 + const char *ptr, const char *end, STRING_POOL *pool, 5580 + enum XML_Account account) { 5312 5581 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 5582 +#ifndef XML_DTD 5583 + UNUSED_P(account); 5584 +#endif 5585 + 5313 5586 for (;;) { 5314 - const char *next; 5587 + const char *next 5588 + = ptr; /* XmlAttributeValueTok doesn't always set the last arg */ 5315 5589 int tok = XmlAttributeValueTok(enc, ptr, end, &next); 5590 +#ifdef XML_DTD 5591 + if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) { 5592 + accountingOnAbort(parser); 5593 + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 5594 + } 5595 +#endif 5316 5596 switch (tok) { 5317 5597 case XML_TOK_NONE: 5318 5598 return XML_ERROR_NONE; 5319 5599 case XML_TOK_INVALID: 5320 5600 if (enc == parser->m_encoding) 5321 5601 parser->m_eventPtr = next; 5322 5602 return XML_ERROR_INVALID_TOKEN; ................................................................................ 5368 5648 case XML_TOK_ENTITY_REF: { 5369 5649 const XML_Char *name; 5370 5650 ENTITY *entity; 5371 5651 char checkEntityDecl; 5372 5652 XML_Char ch = (XML_Char)XmlPredefinedEntityName( 5373 5653 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); 5374 5654 if (ch) { 5655 +#ifdef XML_DTD 5656 + /* NOTE: We are replacing 4-6 characters original input for 1 character 5657 + * so there is no amplification and hence recording without 5658 + * protection. */ 5659 + accountingDiffTolerated(parser, tok, (char *)&ch, 5660 + ((char *)&ch) + sizeof(XML_Char), __LINE__, 5661 + XML_ACCOUNT_ENTITY_EXPANSION); 5662 +#endif /* XML_DTD */ 5375 5663 if (! poolAppendChar(pool, ch)) 5376 5664 return XML_ERROR_NO_MEMORY; 5377 5665 break; 5378 5666 } 5379 5667 name = poolStoreString(&parser->m_temp2Pool, enc, 5380 5668 ptr + enc->minBytesPerChar, 5381 5669 next - enc->minBytesPerChar); ................................................................................ 5445 5733 if (enc == parser->m_encoding) 5446 5734 parser->m_eventPtr = ptr; 5447 5735 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 5448 5736 } else { 5449 5737 enum XML_Error result; 5450 5738 const XML_Char *textEnd = entity->textPtr + entity->textLen; 5451 5739 entity->open = XML_TRUE; 5740 +#ifdef XML_DTD 5741 + entityTrackingOnOpen(parser, entity, __LINE__); 5742 +#endif 5452 5743 result = appendAttributeValue(parser, parser->m_internalEncoding, 5453 5744 isCdata, (const char *)entity->textPtr, 5454 - (const char *)textEnd, pool); 5745 + (const char *)textEnd, pool, 5746 + XML_ACCOUNT_ENTITY_EXPANSION); 5747 +#ifdef XML_DTD 5748 + entityTrackingOnClose(parser, entity, __LINE__); 5749 +#endif 5455 5750 entity->open = XML_FALSE; 5456 5751 if (result) 5457 5752 return result; 5458 5753 } 5459 5754 } break; 5460 5755 default: 5461 5756 /* The only token returned by XmlAttributeValueTok() that does ................................................................................ 5477 5772 ptr = next; 5478 5773 } 5479 5774 /* not reached */ 5480 5775 } 5481 5776 5482 5777 static enum XML_Error 5483 5778 storeEntityValue(XML_Parser parser, const ENCODING *enc, 5484 - const char *entityTextPtr, const char *entityTextEnd) { 5779 + const char *entityTextPtr, const char *entityTextEnd, 5780 + enum XML_Account account) { 5485 5781 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 5486 5782 STRING_POOL *pool = &(dtd->entityValuePool); 5487 5783 enum XML_Error result = XML_ERROR_NONE; 5488 5784 #ifdef XML_DTD 5489 5785 int oldInEntityValue = parser->m_prologState.inEntityValue; 5490 5786 parser->m_prologState.inEntityValue = 1; 5787 +#else 5788 + UNUSED_P(account); 5491 5789 #endif /* XML_DTD */ 5492 5790 /* never return Null for the value argument in EntityDeclHandler, 5493 5791 since this would indicate an external entity; therefore we 5494 5792 have to make sure that entityValuePool.start is not null */ 5495 5793 if (! pool->blocks) { 5496 5794 if (! poolGrow(pool)) 5497 5795 return XML_ERROR_NO_MEMORY; 5498 5796 } 5499 5797 5500 5798 for (;;) { 5501 - const char *next; 5799 + const char *next 5800 + = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ 5502 5801 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 5802 + 5803 +#ifdef XML_DTD 5804 + if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, 5805 + account)) { 5806 + accountingOnAbort(parser); 5807 + result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 5808 + goto endEntityValue; 5809 + } 5810 +#endif 5811 + 5503 5812 switch (tok) { 5504 5813 case XML_TOK_PARAM_ENTITY_REF: 5505 5814 #ifdef XML_DTD 5506 5815 if (parser->m_isParamEntity || enc != parser->m_encoding) { 5507 5816 const XML_Char *name; 5508 5817 ENTITY *entity; 5509 5818 name = poolStoreString(&parser->m_tempPool, enc, ................................................................................ 5531 5840 result = XML_ERROR_RECURSIVE_ENTITY_REF; 5532 5841 goto endEntityValue; 5533 5842 } 5534 5843 if (entity->systemId) { 5535 5844 if (parser->m_externalEntityRefHandler) { 5536 5845 dtd->paramEntityRead = XML_FALSE; 5537 5846 entity->open = XML_TRUE; 5847 + entityTrackingOnOpen(parser, entity, __LINE__); 5538 5848 if (! parser->m_externalEntityRefHandler( 5539 5849 parser->m_externalEntityRefHandlerArg, 0, entity->base, 5540 5850 entity->systemId, entity->publicId)) { 5851 + entityTrackingOnClose(parser, entity, __LINE__); 5541 5852 entity->open = XML_FALSE; 5542 5853 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; 5543 5854 goto endEntityValue; 5544 5855 } 5856 + entityTrackingOnClose(parser, entity, __LINE__); 5545 5857 entity->open = XML_FALSE; 5546 5858 if (! dtd->paramEntityRead) 5547 5859 dtd->keepProcessing = dtd->standalone; 5548 5860 } else 5549 5861 dtd->keepProcessing = dtd->standalone; 5550 5862 } else { 5551 5863 entity->open = XML_TRUE; 5864 + entityTrackingOnOpen(parser, entity, __LINE__); 5552 5865 result = storeEntityValue( 5553 5866 parser, parser->m_internalEncoding, (const char *)entity->textPtr, 5554 - (const char *)(entity->textPtr + entity->textLen)); 5867 + (const char *)(entity->textPtr + entity->textLen), 5868 + XML_ACCOUNT_ENTITY_EXPANSION); 5869 + entityTrackingOnClose(parser, entity, __LINE__); 5555 5870 entity->open = XML_FALSE; 5556 5871 if (result) 5557 5872 goto endEntityValue; 5558 5873 } 5559 5874 break; 5560 5875 } 5561 5876 #endif /* XML_DTD */ ................................................................................ 6908 7223 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); 6909 7224 if (result == NULL) 6910 7225 return NULL; 6911 7226 /* Copy the original into place */ 6912 7227 memcpy(result, s, charsRequired * sizeof(XML_Char)); 6913 7228 return result; 6914 7229 } 7230 + 7231 +#ifdef XML_DTD 7232 + 7233 +static float 7234 +accountingGetCurrentAmplification(XML_Parser rootParser) { 7235 + const XmlBigCount countBytesOutput 7236 + = rootParser->m_accounting.countBytesDirect 7237 + + rootParser->m_accounting.countBytesIndirect; 7238 + const float amplificationFactor 7239 + = rootParser->m_accounting.countBytesDirect 7240 + ? (countBytesOutput 7241 + / (float)(rootParser->m_accounting.countBytesDirect)) 7242 + : 1.0f; 7243 + assert(! rootParser->m_parentParser); 7244 + return amplificationFactor; 7245 +} 7246 + 7247 +static void 7248 +accountingReportStats(XML_Parser originParser, const char *epilog) { 7249 + const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7250 + assert(! rootParser->m_parentParser); 7251 + 7252 + if (rootParser->m_accounting.debugLevel < 1) { 7253 + return; 7254 + } 7255 + 7256 + const float amplificationFactor 7257 + = accountingGetCurrentAmplification(rootParser); 7258 + fprintf(stderr, 7259 + "expat: Accounting(%p): Direct " EXPAT_FMT_ULL( 7260 + "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s", 7261 + (void *)rootParser, rootParser->m_accounting.countBytesDirect, 7262 + rootParser->m_accounting.countBytesIndirect, 7263 + (double)amplificationFactor, epilog); 7264 +} 7265 + 7266 +static void 7267 +accountingOnAbort(XML_Parser originParser) { 7268 + accountingReportStats(originParser, " ABORTING\n"); 7269 +} 7270 + 7271 +static void 7272 +accountingReportDiff(XML_Parser rootParser, 7273 + unsigned int levelsAwayFromRootParser, const char *before, 7274 + const char *after, ptrdiff_t bytesMore, int source_line, 7275 + enum XML_Account account) { 7276 + assert(! rootParser->m_parentParser); 7277 + 7278 + fprintf(stderr, 7279 + " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", 7280 + bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", 7281 + levelsAwayFromRootParser, source_line, 10, ""); 7282 + 7283 + const char ellipis[] = "[..]"; 7284 + const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1; 7285 + const unsigned int contextLength = 10; 7286 + 7287 + /* Note: Performance is of no concern here */ 7288 + const char *walker = before; 7289 + if ((rootParser->m_accounting.debugLevel >= 3) 7290 + || (after - before) 7291 + <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) { 7292 + for (; walker < after; walker++) { 7293 + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7294 + } 7295 + } else { 7296 + for (; walker < before + contextLength; walker++) { 7297 + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7298 + } 7299 + fprintf(stderr, ellipis); 7300 + walker = after - contextLength; 7301 + for (; walker < after; walker++) { 7302 + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7303 + } 7304 + } 7305 + fprintf(stderr, "\"\n"); 7306 +} 7307 + 7308 +static XML_Bool 7309 +accountingDiffTolerated(XML_Parser originParser, int tok, const char *before, 7310 + const char *after, int source_line, 7311 + enum XML_Account account) { 7312 + /* Note: We need to check the token type *first* to be sure that 7313 + * we can even access variable <after>, safely. 7314 + * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */ 7315 + switch (tok) { 7316 + case XML_TOK_INVALID: 7317 + case XML_TOK_PARTIAL: 7318 + case XML_TOK_PARTIAL_CHAR: 7319 + case XML_TOK_NONE: 7320 + return XML_TRUE; 7321 + } 7322 + 7323 + if (account == XML_ACCOUNT_NONE) 7324 + return XML_TRUE; /* because these bytes have been accounted for, already */ 7325 + 7326 + unsigned int levelsAwayFromRootParser; 7327 + const XML_Parser rootParser 7328 + = getRootParserOf(originParser, &levelsAwayFromRootParser); 7329 + assert(! rootParser->m_parentParser); 7330 + 7331 + const int isDirect 7332 + = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser); 7333 + const ptrdiff_t bytesMore = after - before; 7334 + 7335 + XmlBigCount *const additionTarget 7336 + = isDirect ? &rootParser->m_accounting.countBytesDirect 7337 + : &rootParser->m_accounting.countBytesIndirect; 7338 + 7339 + /* Detect and avoid integer overflow */ 7340 + if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore) 7341 + return XML_FALSE; 7342 + *additionTarget += bytesMore; 7343 + 7344 + const XmlBigCount countBytesOutput 7345 + = rootParser->m_accounting.countBytesDirect 7346 + + rootParser->m_accounting.countBytesIndirect; 7347 + const float amplificationFactor 7348 + = accountingGetCurrentAmplification(rootParser); 7349 + const XML_Bool tolerated 7350 + = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes) 7351 + || (amplificationFactor 7352 + <= rootParser->m_accounting.maximumAmplificationFactor); 7353 + 7354 + if (rootParser->m_accounting.debugLevel >= 2) { 7355 + accountingReportStats(rootParser, ""); 7356 + accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after, 7357 + bytesMore, source_line, account); 7358 + } 7359 + 7360 + return tolerated; 7361 +} 7362 + 7363 +unsigned long long 7364 +testingAccountingGetCountBytesDirect(XML_Parser parser) { 7365 + if (! parser) 7366 + return 0; 7367 + return parser->m_accounting.countBytesDirect; 7368 +} 7369 + 7370 +unsigned long long 7371 +testingAccountingGetCountBytesIndirect(XML_Parser parser) { 7372 + if (! parser) 7373 + return 0; 7374 + return parser->m_accounting.countBytesIndirect; 7375 +} 7376 + 7377 +static void 7378 +entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, 7379 + const char *action, int sourceLine) { 7380 + assert(! rootParser->m_parentParser); 7381 + if (rootParser->m_entity_stats.debugLevel < 1) 7382 + return; 7383 + 7384 +# if defined(XML_UNICODE) 7385 + const char *const entityName = "[..]"; 7386 +# else 7387 + const char *const entityName = entity->name; 7388 +# endif 7389 + 7390 + fprintf( 7391 + stderr, 7392 + "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", 7393 + (void *)rootParser, rootParser->m_entity_stats.countEverOpened, 7394 + rootParser->m_entity_stats.currentDepth, 7395 + rootParser->m_entity_stats.maximumDepthSeen, 7396 + (rootParser->m_entity_stats.currentDepth - 1) * 2, "", 7397 + entity->is_param ? "%" : "&", entityName, action, entity->textLen, 7398 + sourceLine); 7399 +} 7400 + 7401 +static void 7402 +entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) { 7403 + const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7404 + assert(! rootParser->m_parentParser); 7405 + 7406 + rootParser->m_entity_stats.countEverOpened++; 7407 + rootParser->m_entity_stats.currentDepth++; 7408 + if (rootParser->m_entity_stats.currentDepth 7409 + > rootParser->m_entity_stats.maximumDepthSeen) { 7410 + rootParser->m_entity_stats.maximumDepthSeen++; 7411 + } 7412 + 7413 + entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine); 7414 +} 7415 + 7416 +static void 7417 +entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) { 7418 + const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7419 + assert(! rootParser->m_parentParser); 7420 + 7421 + entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine); 7422 + rootParser->m_entity_stats.currentDepth--; 7423 +} 7424 + 7425 +static XML_Parser 7426 +getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) { 7427 + XML_Parser rootParser = parser; 7428 + unsigned int stepsTakenUpwards = 0; 7429 + while (rootParser->m_parentParser) { 7430 + rootParser = rootParser->m_parentParser; 7431 + stepsTakenUpwards++; 7432 + } 7433 + assert(! rootParser->m_parentParser); 7434 + if (outLevelDiff != NULL) { 7435 + *outLevelDiff = stepsTakenUpwards; 7436 + } 7437 + return rootParser; 7438 +} 7439 + 7440 +const char * 7441 +unsignedCharToPrintable(unsigned char c) { 7442 + switch (c) { 7443 + case 0: 7444 + return "\\0"; 7445 + case 1: 7446 + return "\\x1"; 7447 + case 2: 7448 + return "\\x2"; 7449 + case 3: 7450 + return "\\x3"; 7451 + case 4: 7452 + return "\\x4"; 7453 + case 5: 7454 + return "\\x5"; 7455 + case 6: 7456 + return "\\x6"; 7457 + case 7: 7458 + return "\\x7"; 7459 + case 8: 7460 + return "\\x8"; 7461 + case 9: 7462 + return "\\t"; 7463 + case 10: 7464 + return "\\n"; 7465 + case 11: 7466 + return "\\xB"; 7467 + case 12: 7468 + return "\\xC"; 7469 + case 13: 7470 + return "\\r"; 7471 + case 14: 7472 + return "\\xE"; 7473 + case 15: 7474 + return "\\xF"; 7475 + case 16: 7476 + return "\\x10"; 7477 + case 17: 7478 + return "\\x11"; 7479 + case 18: 7480 + return "\\x12"; 7481 + case 19: 7482 + return "\\x13"; 7483 + case 20: 7484 + return "\\x14"; 7485 + case 21: 7486 + return "\\x15"; 7487 + case 22: 7488 + return "\\x16"; 7489 + case 23: 7490 + return "\\x17"; 7491 + case 24: 7492 + return "\\x18"; 7493 + case 25: 7494 + return "\\x19"; 7495 + case 26: 7496 + return "\\x1A"; 7497 + case 27: 7498 + return "\\x1B"; 7499 + case 28: 7500 + return "\\x1C"; 7501 + case 29: 7502 + return "\\x1D"; 7503 + case 30: 7504 + return "\\x1E"; 7505 + case 31: 7506 + return "\\x1F"; 7507 + case 32: 7508 + return " "; 7509 + case 33: 7510 + return "!"; 7511 + case 34: 7512 + return "\\\""; 7513 + case 35: 7514 + return "#"; 7515 + case 36: 7516 + return "$"; 7517 + case 37: 7518 + return "%"; 7519 + case 38: 7520 + return "&"; 7521 + case 39: 7522 + return "'"; 7523 + case 40: 7524 + return "("; 7525 + case 41: 7526 + return ")"; 7527 + case 42: 7528 + return "*"; 7529 + case 43: 7530 + return "+"; 7531 + case 44: 7532 + return ","; 7533 + case 45: 7534 + return "-"; 7535 + case 46: 7536 + return "."; 7537 + case 47: 7538 + return "/"; 7539 + case 48: 7540 + return "0"; 7541 + case 49: 7542 + return "1"; 7543 + case 50: 7544 + return "2"; 7545 + case 51: 7546 + return "3"; 7547 + case 52: 7548 + return "4"; 7549 + case 53: 7550 + return "5"; 7551 + case 54: 7552 + return "6"; 7553 + case 55: 7554 + return "7"; 7555 + case 56: 7556 + return "8"; 7557 + case 57: 7558 + return "9"; 7559 + case 58: 7560 + return ":"; 7561 + case 59: 7562 + return ";"; 7563 + case 60: 7564 + return "<"; 7565 + case 61: 7566 + return "="; 7567 + case 62: 7568 + return ">"; 7569 + case 63: 7570 + return "?"; 7571 + case 64: 7572 + return "@"; 7573 + case 65: 7574 + return "A"; 7575 + case 66: 7576 + return "B"; 7577 + case 67: 7578 + return "C"; 7579 + case 68: 7580 + return "D"; 7581 + case 69: 7582 + return "E"; 7583 + case 70: 7584 + return "F"; 7585 + case 71: 7586 + return "G"; 7587 + case 72: 7588 + return "H"; 7589 + case 73: 7590 + return "I"; 7591 + case 74: 7592 + return "J"; 7593 + case 75: 7594 + return "K"; 7595 + case 76: 7596 + return "L"; 7597 + case 77: 7598 + return "M"; 7599 + case 78: 7600 + return "N"; 7601 + case 79: 7602 + return "O"; 7603 + case 80: 7604 + return "P"; 7605 + case 81: 7606 + return "Q"; 7607 + case 82: 7608 + return "R"; 7609 + case 83: 7610 + return "S"; 7611 + case 84: 7612 + return "T"; 7613 + case 85: 7614 + return "U"; 7615 + case 86: 7616 + return "V"; 7617 + case 87: 7618 + return "W"; 7619 + case 88: 7620 + return "X"; 7621 + case 89: 7622 + return "Y"; 7623 + case 90: 7624 + return "Z"; 7625 + case 91: 7626 + return "["; 7627 + case 92: 7628 + return "\\\\"; 7629 + case 93: 7630 + return "]"; 7631 + case 94: 7632 + return "^"; 7633 + case 95: 7634 + return "_"; 7635 + case 96: 7636 + return "`"; 7637 + case 97: 7638 + return "a"; 7639 + case 98: 7640 + return "b"; 7641 + case 99: 7642 + return "c"; 7643 + case 100: 7644 + return "d"; 7645 + case 101: 7646 + return "e"; 7647 + case 102: 7648 + return "f"; 7649 + case 103: 7650 + return "g"; 7651 + case 104: 7652 + return "h"; 7653 + case 105: 7654 + return "i"; 7655 + case 106: 7656 + return "j"; 7657 + case 107: 7658 + return "k"; 7659 + case 108: 7660 + return "l"; 7661 + case 109: 7662 + return "m"; 7663 + case 110: 7664 + return "n"; 7665 + case 111: 7666 + return "o"; 7667 + case 112: 7668 + return "p"; 7669 + case 113: 7670 + return "q"; 7671 + case 114: 7672 + return "r"; 7673 + case 115: 7674 + return "s"; 7675 + case 116: 7676 + return "t"; 7677 + case 117: 7678 + return "u"; 7679 + case 118: 7680 + return "v"; 7681 + case 119: 7682 + return "w"; 7683 + case 120: 7684 + return "x"; 7685 + case 121: 7686 + return "y"; 7687 + case 122: 7688 + return "z"; 7689 + case 123: 7690 + return "{"; 7691 + case 124: 7692 + return "|"; 7693 + case 125: 7694 + return "}"; 7695 + case 126: 7696 + return "~"; 7697 + case 127: 7698 + return "\\x7F"; 7699 + case 128: 7700 + return "\\x80"; 7701 + case 129: 7702 + return "\\x81"; 7703 + case 130: 7704 + return "\\x82"; 7705 + case 131: 7706 + return "\\x83"; 7707 + case 132: 7708 + return "\\x84"; 7709 + case 133: 7710 + return "\\x85"; 7711 + case 134: 7712 + return "\\x86"; 7713 + case 135: 7714 + return "\\x87"; 7715 + case 136: 7716 + return "\\x88"; 7717 + case 137: 7718 + return "\\x89"; 7719 + case 138: 7720 + return "\\x8A"; 7721 + case 139: 7722 + return "\\x8B"; 7723 + case 140: 7724 + return "\\x8C"; 7725 + case 141: 7726 + return "\\x8D"; 7727 + case 142: 7728 + return "\\x8E"; 7729 + case 143: 7730 + return "\\x8F"; 7731 + case 144: 7732 + return "\\x90"; 7733 + case 145: 7734 + return "\\x91"; 7735 + case 146: 7736 + return "\\x92"; 7737 + case 147: 7738 + return "\\x93"; 7739 + case 148: 7740 + return "\\x94"; 7741 + case 149: 7742 + return "\\x95"; 7743 + case 150: 7744 + return "\\x96"; 7745 + case 151: 7746 + return "\\x97"; 7747 + case 152: 7748 + return "\\x98"; 7749 + case 153: 7750 + return "\\x99"; 7751 + case 154: 7752 + return "\\x9A"; 7753 + case 155: 7754 + return "\\x9B"; 7755 + case 156: 7756 + return "\\x9C"; 7757 + case 157: 7758 + return "\\x9D"; 7759 + case 158: 7760 + return "\\x9E"; 7761 + case 159: 7762 + return "\\x9F"; 7763 + case 160: 7764 + return "\\xA0"; 7765 + case 161: 7766 + return "\\xA1"; 7767 + case 162: 7768 + return "\\xA2"; 7769 + case 163: 7770 + return "\\xA3"; 7771 + case 164: 7772 + return "\\xA4"; 7773 + case 165: 7774 + return "\\xA5"; 7775 + case 166: 7776 + return "\\xA6"; 7777 + case 167: 7778 + return "\\xA7"; 7779 + case 168: 7780 + return "\\xA8"; 7781 + case 169: 7782 + return "\\xA9"; 7783 + case 170: 7784 + return "\\xAA"; 7785 + case 171: 7786 + return "\\xAB"; 7787 + case 172: 7788 + return "\\xAC"; 7789 + case 173: 7790 + return "\\xAD"; 7791 + case 174: 7792 + return "\\xAE"; 7793 + case 175: 7794 + return "\\xAF"; 7795 + case 176: 7796 + return "\\xB0"; 7797 + case 177: 7798 + return "\\xB1"; 7799 + case 178: 7800 + return "\\xB2"; 7801 + case 179: 7802 + return "\\xB3"; 7803 + case 180: 7804 + return "\\xB4"; 7805 + case 181: 7806 + return "\\xB5"; 7807 + case 182: 7808 + return "\\xB6"; 7809 + case 183: 7810 + return "\\xB7"; 7811 + case 184: 7812 + return "\\xB8"; 7813 + case 185: 7814 + return "\\xB9"; 7815 + case 186: 7816 + return "\\xBA"; 7817 + case 187: 7818 + return "\\xBB"; 7819 + case 188: 7820 + return "\\xBC"; 7821 + case 189: 7822 + return "\\xBD"; 7823 + case 190: 7824 + return "\\xBE"; 7825 + case 191: 7826 + return "\\xBF"; 7827 + case 192: 7828 + return "\\xC0"; 7829 + case 193: 7830 + return "\\xC1"; 7831 + case 194: 7832 + return "\\xC2"; 7833 + case 195: 7834 + return "\\xC3"; 7835 + case 196: 7836 + return "\\xC4"; 7837 + case 197: 7838 + return "\\xC5"; 7839 + case 198: 7840 + return "\\xC6"; 7841 + case 199: 7842 + return "\\xC7"; 7843 + case 200: 7844 + return "\\xC8"; 7845 + case 201: 7846 + return "\\xC9"; 7847 + case 202: 7848 + return "\\xCA"; 7849 + case 203: 7850 + return "\\xCB"; 7851 + case 204: 7852 + return "\\xCC"; 7853 + case 205: 7854 + return "\\xCD"; 7855 + case 206: 7856 + return "\\xCE"; 7857 + case 207: 7858 + return "\\xCF"; 7859 + case 208: 7860 + return "\\xD0"; 7861 + case 209: 7862 + return "\\xD1"; 7863 + case 210: 7864 + return "\\xD2"; 7865 + case 211: 7866 + return "\\xD3"; 7867 + case 212: 7868 + return "\\xD4"; 7869 + case 213: 7870 + return "\\xD5"; 7871 + case 214: 7872 + return "\\xD6"; 7873 + case 215: 7874 + return "\\xD7"; 7875 + case 216: 7876 + return "\\xD8"; 7877 + case 217: 7878 + return "\\xD9"; 7879 + case 218: 7880 + return "\\xDA"; 7881 + case 219: 7882 + return "\\xDB"; 7883 + case 220: 7884 + return "\\xDC"; 7885 + case 221: 7886 + return "\\xDD"; 7887 + case 222: 7888 + return "\\xDE"; 7889 + case 223: 7890 + return "\\xDF"; 7891 + case 224: 7892 + return "\\xE0"; 7893 + case 225: 7894 + return "\\xE1"; 7895 + case 226: 7896 + return "\\xE2"; 7897 + case 227: 7898 + return "\\xE3"; 7899 + case 228: 7900 + return "\\xE4"; 7901 + case 229: 7902 + return "\\xE5"; 7903 + case 230: 7904 + return "\\xE6"; 7905 + case 231: 7906 + return "\\xE7"; 7907 + case 232: 7908 + return "\\xE8"; 7909 + case 233: 7910 + return "\\xE9"; 7911 + case 234: 7912 + return "\\xEA"; 7913 + case 235: 7914 + return "\\xEB"; 7915 + case 236: 7916 + return "\\xEC"; 7917 + case 237: 7918 + return "\\xED"; 7919 + case 238: 7920 + return "\\xEE"; 7921 + case 239: 7922 + return "\\xEF"; 7923 + case 240: 7924 + return "\\xF0"; 7925 + case 241: 7926 + return "\\xF1"; 7927 + case 242: 7928 + return "\\xF2"; 7929 + case 243: 7930 + return "\\xF3"; 7931 + case 244: 7932 + return "\\xF4"; 7933 + case 245: 7934 + return "\\xF5"; 7935 + case 246: 7936 + return "\\xF6"; 7937 + case 247: 7938 + return "\\xF7"; 7939 + case 248: 7940 + return "\\xF8"; 7941 + case 249: 7942 + return "\\xF9"; 7943 + case 250: 7944 + return "\\xFA"; 7945 + case 251: 7946 + return "\\xFB"; 7947 + case 252: 7948 + return "\\xFC"; 7949 + case 253: 7950 + return "\\xFD"; 7951 + case 254: 7952 + return "\\xFE"; 7953 + case 255: 7954 + return "\\xFF"; 7955 + default: 7956 + assert(0); /* never gets here */ 7957 + return "dead code"; 7958 + } 7959 + assert(0); /* never gets here */ 7960 +} 7961 + 7962 +#endif /* XML_DTD */ 7963 + 7964 +static unsigned long 7965 +getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) { 7966 + const char *const valueOrNull = getenv(variableName); 7967 + if (valueOrNull == NULL) { 7968 + return defaultDebugLevel; 7969 + } 7970 + const char *const value = valueOrNull; 7971 + 7972 + errno = 0; 7973 + char *afterValue = (char *)value; 7974 + unsigned long debugLevel = strtoul(value, &afterValue, 10); 7975 + if ((errno != 0) || (afterValue[0] != '\0')) { 7976 + errno = 0; 7977 + return defaultDebugLevel; 7978 + } 7979 + 7980 + return debugLevel; 7981 +}
Changes to expat/xmlrole.c.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> 12 + Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> 13 + Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 14 + Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net> 15 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 16 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 17 + Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 18 + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> 11 19 Licensed under the MIT license: 12 20 13 21 Permission is hereby granted, free of charge, to any person obtaining 14 22 a copy of this software and associated documentation files (the 15 23 "Software"), to deal in the Software without restriction, including 16 24 without limitation the rights to use, copy, modify, merge, publish, 17 25 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 26 34 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 35 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 36 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 37 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 38 USE OR OTHER DEALINGS IN THE SOFTWARE. 31 39 */ 32 40 41 +#include <expat_config.h> 42 + 33 43 #include <stddef.h> 34 44 35 45 #ifdef _WIN32 36 46 # include "winconfig.h" 37 -#else 38 -# ifdef HAVE_EXPAT_CONFIG_H 39 -# include <expat_config.h> 40 -# endif 41 -#endif /* ndef _WIN32 */ 47 +#endif 42 48 43 49 #include "expat_external.h" 44 50 #include "internal.h" 45 51 #include "xmlrole.h" 46 52 #include "ascii.h" 47 53 48 54 /* Doesn't check:
Changes to expat/xmlrole.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Karl Waclawek <karl@waclawek.net> 12 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 13 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 14 Licensed under the MIT license: 12 15 13 16 Permission is hereby granted, free of charge, to any person obtaining 14 17 a copy of this software and associated documentation files (the 15 18 "Software"), to deal in the Software without restriction, including 16 19 without limitation the rights to use, copy, modify, merge, publish, 17 20 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/xmltok.c.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> 13 + Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 14 + Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net> 15 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 16 + Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> 17 + Copyright (c) 2016 Don Lewis <truckman@apache.org> 18 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 19 + Copyright (c) 2017 Alexander Bluhm <alexander.bluhm@gmx.net> 20 + Copyright (c) 2017 Benbuck Nason <bnason@netflix.com> 21 + Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> 22 + Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 23 + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> 11 24 Licensed under the MIT license: 12 25 13 26 Permission is hereby granted, free of charge, to any person obtaining 14 27 a copy of this software and associated documentation files (the 15 28 "Software"), to deal in the Software without restriction, including 16 29 without limitation the rights to use, copy, modify, merge, publish, 17 30 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 26 39 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 40 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 41 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 42 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 43 USE OR OTHER DEALINGS IN THE SOFTWARE. 31 44 */ 32 45 46 +#include <expat_config.h> 47 + 33 48 #include <stddef.h> 34 49 #include <string.h> /* memcpy */ 35 50 #include <stdbool.h> 36 51 37 52 #ifdef _WIN32 38 53 # include "winconfig.h" 39 -#else 40 -# ifdef HAVE_EXPAT_CONFIG_H 41 -# include <expat_config.h> 42 -# endif 43 -#endif /* ndef _WIN32 */ 54 +#endif 44 55 45 56 #include "expat_external.h" 46 57 #include "internal.h" 47 58 #include "xmltok.h" 48 59 #include "nametab.h" 49 60 50 61 #ifdef XML_DTD ................................................................................ 257 268 } 258 269 #else 259 270 # define BYTE_TO_ASCII(enc, p) (*(p)) 260 271 #endif 261 272 262 273 #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) 263 274 #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) 264 -#define IS_INVALID_CHAR(enc, p, n) \ 265 - (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 275 +#ifdef XML_MIN_SIZE 276 +# define IS_INVALID_CHAR(enc, p, n) \ 277 + (AS_NORMAL_ENCODING(enc)->isInvalid##n \ 278 + && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 279 +#else 280 +# define IS_INVALID_CHAR(enc, p, n) \ 281 + (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 282 +#endif 266 283 267 284 #ifdef XML_MIN_SIZE 268 285 # define IS_NAME_CHAR_MINBPC(enc, p) \ 269 286 (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) 270 287 # define IS_NMSTRT_CHAR_MINBPC(enc, p) \ 271 288 (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) 272 289 #else
Changes to expat/xmltok.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2002-2005 Karl Waclawek <karl@waclawek.net> 13 + Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org> 14 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 11 15 Licensed under the MIT license: 12 16 13 17 Permission is hereby granted, free of charge, to any person obtaining 14 18 a copy of this software and associated documentation files (the 15 19 "Software"), to deal in the Software without restriction, including 16 20 without limitation the rights to use, copy, modify, merge, publish, 17 21 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/xmltok_impl.c.
1 -/* This file is included! 1 +/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)! 2 2 __ __ _ 3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 + Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 13 + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> 14 + Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 15 + Copyright (c) 2018 Benjamin Peterson <benjamin@python.org> 16 + Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com> 17 + Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 18 + Copyright (c) 2020 Boris Kolpackov <boris@codesynthesis.com> 11 19 Licensed under the MIT license: 12 20 13 21 Permission is hereby granted, free of charge, to any person obtaining 14 22 a copy of this software and associated documentation files (the 15 23 "Software"), to deal in the Software without restriction, including 16 24 without limitation the rights to use, copy, modify, merge, publish, 17 25 distribute, sublicense, and/or sell copies of the Software, and to permit ................................................................................ 28 36 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 37 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 38 USE OR OTHER DEALINGS IN THE SOFTWARE. 31 39 */ 32 40 33 41 #ifdef XML_TOK_IMPL_C 34 42 35 -# ifndef IS_INVALID_CHAR 43 +# ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined 36 44 # define IS_INVALID_CHAR(enc, ptr, n) (0) 37 45 # endif 38 46 39 47 # define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ 40 48 case BT_LEAD##n: \ 41 49 if (end - ptr < n) \ 42 50 return XML_TOK_PARTIAL_CHAR; \
Changes to expat/xmltok_impl.h.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2017-2019 Sebastian Pipping <sebastian@pipping.org> 11 12 Licensed under the MIT license: 12 13 13 14 Permission is hereby granted, free of charge, to any person obtaining 14 15 a copy of this software and associated documentation files (the 15 16 "Software"), to deal in the Software without restriction, including 16 17 without limitation the rights to use, copy, modify, merge, publish, 17 18 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to expat/xmltok_ns.c.
3 3 ___\ \/ /_ __ __ _| |_ 4 4 / _ \\ /| '_ \ / _` | __| 5 5 | __// \| |_) | (_| | |_ 6 6 \___/_/\_\ .__/ \__,_|\__| 7 7 |_| XML parser 8 8 9 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 - Copyright (c) 2000-2017 Expat development team 10 + Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 + Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> 12 + Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 13 + Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> 14 + Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> 11 15 Licensed under the MIT license: 12 16 13 17 Permission is hereby granted, free of charge, to any person obtaining 14 18 a copy of this software and associated documentation files (the 15 19 "Software"), to deal in the Software without restriction, including 16 20 without limitation the rights to use, copy, modify, merge, publish, 17 21 distribute, sublicense, and/or sell copies of the Software, and to permit
Changes to generic/tcldom.c.
166 166 #define SERIALIZE_INDENT_ATTR_WITH_TAB 512 167 167 168 168 /*---------------------------------------------------------------------------- 169 169 | Module Globals 170 170 | 171 171 \---------------------------------------------------------------------------*/ 172 172 #ifndef TCL_THREADS 173 - static int storeLineColumn = 0; 174 - static int dontCreateObjCommands = 0; 175 - static int dontCheckCharData = 0; 176 - static int dontCheckName = 0; 177 - static int domCreateCmdMode = 0; 173 + static int storeLineColumn = 0; 174 + static int dontCreateObjCommands = 0; 175 + static int dontCheckCharData = 0; 176 + static int dontCheckName = 0; 177 + static int domCreateCmdMode = 0; 178 + /* BLAP stands for BillionLaughsAttackProtection */ 179 + static float BLAPMaximumAmplification; 180 + unsigned long long BLAPActivationThreshold; 178 181 # define TSD(x) x 179 182 # define GetTcldomTSD() 180 183 #else 181 184 typedef struct ThreadSpecificData { 182 185 int storeLineColumn; 183 186 int dontCreateObjCommands; 184 187 int dontCheckCharData; 185 188 int dontCheckName; 186 189 int domCreateCmdMode; 190 + float BLAPMaximumAmplification; 191 + unsigned long long BLAPActivationThreshold; 187 192 } ThreadSpecificData; 188 193 static Tcl_ThreadDataKey dataKey; 189 194 static Tcl_HashTable sharedDocs; 190 195 static Tcl_Mutex tableMutex; 191 196 static int tcldomInitialized; 192 197 # define TSD(x) tsdPtr->x 193 198 # define GetTcldomTSD() ThreadSpecificData *tsdPtr = \