@crossbind/port-expat 2.0.0-beta.66 → 2.0.0-beta.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build.mjs CHANGED
@@ -2,6 +2,12 @@ export default {
2
2
  sha256: '16afbb9cefead2aa278105cf27d9f597bde7fbf3dbb85015857ca7ca6a4e89ba', // expat-2.9.0.tar.gz
3
3
  getURL: (version) => `https://github.com/libexpat/libexpat/releases/download/R_${version.replaceAll('.', '_')}/expat-${version}.tar.gz`,
4
4
  buildType: 'cmake',
5
+ patches: [
6
+ {
7
+ file: new URL('./patches/pr1431-parser-reset.patch', import.meta.url),
8
+ advisories: ['CVE-2026-113351'],
9
+ },
10
+ ],
5
11
  getBuildParams: () => [
6
12
  '-DEXPAT_BUILD_TESTS=OFF',
7
13
  '-DEXPAT_BUILD_TOOLS=OFF',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossbind/port-expat",
3
- "version": "2.0.0-beta.66",
3
+ "version": "2.0.0-beta.67",
4
4
  "nativeVersion": "2.9.0",
5
5
  "description": "This package provides the precompiled Expat XML parser library, built using crossbind, for seamless integration into JavaScript, WebAssembly, and React Native projects. It enables fast and efficient parsing of XML data, making it ideal for applications requiring robust XML handling across platforms. Perfect for web, server-side, and mobile development environments.",
6
6
  "homepage": "https://crossbind.dev/ports/expat/",
@@ -0,0 +1,120 @@
1
+ [CVE-2026-113351] Fix parser reset
2
+ Upstream: https://github.com/libexpat/libexpat/pull/1431 (lib/xmlparse.c only, without the repository's expat/ prefix)
3
+
4
+ diff --git a/lib/xmlparse.c b/lib/xmlparse.c
5
+ index ab2d4f1ed2..f12b7d31ad 100644
6
+ --- a/lib/xmlparse.c
7
+ +++ b/lib/xmlparse.c
8
+ @@ -467,6 +467,7 @@ typedef struct accounting {
9
+ typedef struct MALLOC_TRACKER {
10
+ size_t bytesAllocated;
11
+ size_t peakBytesAllocated; // updated live only for debug level >=2
12
+ + size_t bytesAllocatedWhenLastReset;
13
+ unsigned long debugLevel;
14
+ float maximumAmplificationFactor; // >=1.0
15
+ XmlBigCount activationThresholdBytes;
16
+ @@ -615,7 +616,8 @@ static XML_Parser parserCreate(const XML_Char *encodingName,
17
+ const XML_Char *nameSep, DTD *dtd,
18
+ XML_Parser parentParser);
19
+
20
+ -static void parserInit(XML_Parser parser, const XML_Char *encodingName);
21
+ +static void parserInit(XML_Parser parser, const XML_Char *encodingName,
22
+ + bool isReset);
23
+
24
+ #if XML_GE == 1
25
+ static float accountingGetCurrentAmplification(XML_Parser rootParser);
26
+ @@ -865,11 +867,22 @@ expat_heap_increase_tolerable(XML_Parser rootParser, size_t increase,
27
+ size_t newTotal = 0;
28
+ bool tolerable = true;
29
+
30
+ + // The idea is to subtract the amount of memory that was already
31
+ + // allocated the last time that `XML_ParserReset` was called for
32
+ + // this parser, the memory use of one document could skew the
33
+ + // memory statso of the next document.
34
+ + const size_t bytesAllocated
35
+ + = (rootParser->m_alloc_tracker.bytesAllocatedWhenLastReset
36
+ + > rootParser->m_alloc_tracker.bytesAllocated)
37
+ + ? 0
38
+ + : (rootParser->m_alloc_tracker.bytesAllocated
39
+ + - rootParser->m_alloc_tracker.bytesAllocatedWhenLastReset);
40
+ +
41
+ // Detect integer overflow
42
+ - if (SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated < increase) {
43
+ + if (SIZE_MAX - bytesAllocated < increase) {
44
+ tolerable = false;
45
+ } else {
46
+ - newTotal = rootParser->m_alloc_tracker.bytesAllocated + increase;
47
+ + newTotal = bytesAllocated + increase;
48
+
49
+ if (newTotal >= rootParser->m_alloc_tracker.activationThresholdBytes) {
50
+ assert(newTotal > 0);
51
+ @@ -1449,7 +1462,7 @@ parserCreate(const XML_Char *encodingName,
52
+
53
+ poolInit(&parser->m_tempPool, parser);
54
+ poolInit(&parser->m_temp2Pool, parser);
55
+ - parserInit(parser, encodingName);
56
+ + parserInit(parser, encodingName, /*isReset=*/false);
57
+
58
+ if (encodingName && ! parser->m_protocolEncodingName) {
59
+ if (dtd) {
60
+ @@ -1476,7 +1489,7 @@ parserCreate(const XML_Char *encodingName,
61
+ }
62
+
63
+ static void
64
+ -parserInit(XML_Parser parser, const XML_Char *encodingName) {
65
+ +parserInit(XML_Parser parser, const XML_Char *encodingName, bool isReset) {
66
+ parser->m_processor = prologInitProcessor;
67
+ XmlPrologStateInit(&parser->m_prologState);
68
+ if (encodingName != NULL) {
69
+ @@ -1557,15 +1570,24 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
70
+ parser->m_hash_secret_salt_set = XML_FALSE;
71
+
72
+ #if XML_GE == 1
73
+ - memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
74
+ - parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
75
+ - parser->m_accounting.maximumAmplificationFactor
76
+ - = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
77
+ - parser->m_accounting.activationThresholdBytes
78
+ - = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
79
+ -
80
+ - memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
81
+ - parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
82
+ + parser->m_accounting.countBytesDirect = 0;
83
+ + parser->m_accounting.countBytesIndirect = 0;
84
+ + if (! isReset) {
85
+ + parser->m_accounting.debugLevel
86
+ + = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
87
+ + parser->m_accounting.maximumAmplificationFactor
88
+ + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
89
+ + parser->m_accounting.activationThresholdBytes
90
+ + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
91
+ + }
92
+ +
93
+ + parser->m_entity_stats.countEverOpened = 0;
94
+ + parser->m_entity_stats.currentDepth = 0;
95
+ + parser->m_entity_stats.maximumDepthSeen = 0;
96
+ + if (! isReset)
97
+ + parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
98
+ +#else
99
+ + UNUSED_P(isReset);
100
+ #endif
101
+ }
102
+
103
+ @@ -1628,8 +1650,16 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
104
+ poolClear(&parser->m_temp2Pool);
105
+ FREE(parser, (void *)parser->m_protocolEncodingName);
106
+ parser->m_protocolEncodingName = NULL;
107
+ - parserInit(parser, encodingName);
108
+ + parserInit(parser, encodingName, /*isReset=*/true);
109
+ dtdReset(parser->m_dtd, parser);
110
+ +
111
+ +#if XML_GE == 1
112
+ + parser->m_alloc_tracker.bytesAllocatedWhenLastReset
113
+ + = parser->m_alloc_tracker.bytesAllocated;
114
+ +#endif
115
+ +
116
+ + // NOTE: This effectively checks for `copyString` having failed during the
117
+ + // call to `parserInit` above
118
+ if (encodingName && ! parser->m_protocolEncodingName) {
119
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
120
+ return XML_FALSE;