@depup/mammoth 1.12.1-depup.0 → 1.12.2-depup.0
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/NEWS +6 -0
- package/README.md +4 -4
- package/changes.json +3 -3
- package/lib/document-to-html.js +2 -2
- package/lib/docx/content-types-reader.js +5 -5
- package/lib/docx/numbering-xml.js +4 -4
- package/lib/docx/relationships-reader.js +2 -2
- package/lib/docx/styles-reader.js +23 -12
- package/lib/style-reader.js +1 -1
- package/lib/styles/html-paths.js +2 -2
- package/lib/xml/reader.js +1 -1
- package/mammoth.browser.js +41 -30
- package/mammoth.browser.min.js +3 -3
- package/package.json +7 -7
- package/test/docx/styles-reader.tests.js +12 -0
package/NEWS
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# 1.12.2
|
|
2
|
+
|
|
3
|
+
* Avoid prototype pollution when reading the styles defined in a document. This
|
|
4
|
+
avoids an issue where a maliciously crafted document could be used to set
|
|
5
|
+
externalFileAccess to true.
|
|
6
|
+
|
|
1
7
|
# 1.12.1
|
|
2
8
|
|
|
3
9
|
* Fix: on Windows, when an image's content type includes a backslash in the
|
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/mammoth
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [mammoth](https://www.npmjs.com/package/mammoth) @ 1.12.
|
|
17
|
-
| Processed | 2026-08-
|
|
16
|
+
| Original | [mammoth](https://www.npmjs.com/package/mammoth) @ 1.12.2 |
|
|
17
|
+
| Processed | 2026-08-28 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 7 |
|
|
20
20
|
|
|
@@ -22,8 +22,8 @@ npm install @depup/mammoth
|
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
|
-
| @xmldom/xmldom | ^0.8.6 | ^0.9.
|
|
26
|
-
| argparse | ~1.0.3 | ^3.0.
|
|
25
|
+
| @xmldom/xmldom | ^0.8.6 | ^0.9.12 |
|
|
26
|
+
| argparse | ~1.0.3 | ^3.0.1 |
|
|
27
27
|
| bluebird | ~3.4.0 | ^3.7.2 |
|
|
28
28
|
| jszip | ^3.7.1 | ^3.10.1 |
|
|
29
29
|
| path-is-absolute | ^1.0.0 | ^2.0.0 |
|
package/changes.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"bumped": {
|
|
3
3
|
"@xmldom/xmldom": {
|
|
4
4
|
"from": "^0.8.6",
|
|
5
|
-
"to": "^0.9.
|
|
5
|
+
"to": "^0.9.12"
|
|
6
6
|
},
|
|
7
7
|
"argparse": {
|
|
8
8
|
"from": "~1.0.3",
|
|
9
|
-
"to": "^3.0.
|
|
9
|
+
"to": "^3.0.1"
|
|
10
10
|
},
|
|
11
11
|
"bluebird": {
|
|
12
12
|
"from": "~3.4.0",
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"to": "^15.1.1"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
"timestamp": "2026-08-
|
|
32
|
+
"timestamp": "2026-08-28T20:02:44.372Z",
|
|
33
33
|
"totalUpdated": 7
|
|
34
34
|
}
|
package/lib/document-to-html.js
CHANGED
|
@@ -42,7 +42,7 @@ function DocumentConversion(options, comments) {
|
|
|
42
42
|
function convertToHtml(document) {
|
|
43
43
|
var messages = [];
|
|
44
44
|
|
|
45
|
-
var html = elementToHtml(document, messages,
|
|
45
|
+
var html = elementToHtml(document, messages, Object.create(null));
|
|
46
46
|
|
|
47
47
|
var deferredNodes = [];
|
|
48
48
|
walkHtml(html, function(node) {
|
|
@@ -50,7 +50,7 @@ function DocumentConversion(options, comments) {
|
|
|
50
50
|
deferredNodes.push(node);
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
|
-
var deferredValues =
|
|
53
|
+
var deferredValues = Object.create(null);
|
|
54
54
|
return promises.mapSeries(deferredNodes, function(deferred) {
|
|
55
55
|
return deferred.value().then(function(value) {
|
|
56
56
|
deferredValues[deferred.id] = value;
|
|
@@ -14,9 +14,9 @@ exports.defaultContentTypes = contentTypes({}, {});
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
function readContentTypesFromXml(element) {
|
|
17
|
-
var extensionDefaults =
|
|
18
|
-
var overrides =
|
|
19
|
-
|
|
17
|
+
var extensionDefaults = Object.create(null);
|
|
18
|
+
var overrides = Object.create(null);
|
|
19
|
+
|
|
20
20
|
element.children.forEach(function(child) {
|
|
21
21
|
if (child.name === "content-types:Default") {
|
|
22
22
|
extensionDefaults[child.attributes.Extension] = child.attributes.ContentType;
|
|
@@ -41,7 +41,7 @@ function contentTypes(overrides, extensionDefaults) {
|
|
|
41
41
|
} else {
|
|
42
42
|
var pathParts = path.split(".");
|
|
43
43
|
var extension = pathParts[pathParts.length - 1];
|
|
44
|
-
if (
|
|
44
|
+
if (Object.prototype.hasOwnProperty.call(extensionDefaults, extension)) {
|
|
45
45
|
return extensionDefaults[extension];
|
|
46
46
|
} else {
|
|
47
47
|
var fallback = fallbackContentTypes[extension.toLowerCase()];
|
|
@@ -54,5 +54,5 @@ function contentTypes(overrides, extensionDefaults) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
}
|
|
@@ -17,7 +17,7 @@ function Numbering(nums, abstractNums, styles) {
|
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
function findLevel(numId, level) {
|
|
20
|
-
return findLevelWithSeenNumIds(numId, level,
|
|
20
|
+
return findLevelWithSeenNumIds(numId, level, Object.create(null));
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function findLevelWithSeenNumIds(numId, level, seenNumIds) {
|
|
@@ -63,7 +63,7 @@ function readNumberingXml(root, options) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
function readAbstractNums(root) {
|
|
66
|
-
var abstractNums =
|
|
66
|
+
var abstractNums = Object.create(null);
|
|
67
67
|
root.getElementsByTagName("w:abstractNum").forEach(function(element) {
|
|
68
68
|
var id = element.attributes["w:abstractNumId"];
|
|
69
69
|
abstractNums[id] = readAbstractNum(element);
|
|
@@ -72,7 +72,7 @@ function readAbstractNums(root) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
function readAbstractNum(element) {
|
|
75
|
-
var levels =
|
|
75
|
+
var levels = Object.create(null);
|
|
76
76
|
|
|
77
77
|
// Some malformed documents define numbering levels without an index, and
|
|
78
78
|
// reference the numbering using a w:numPr element without a w:ilvl child.
|
|
@@ -110,7 +110,7 @@ function readAbstractNum(element) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
function readNums(root) {
|
|
113
|
-
var nums =
|
|
113
|
+
var nums = Object.create(null);
|
|
114
114
|
root.getElementsByTagName("w:num").forEach(function(element) {
|
|
115
115
|
var numId = element.attributes["w:numId"];
|
|
116
116
|
var abstractNumId = element.first("w:abstractNumId").attributes["w:val"];
|
|
@@ -19,12 +19,12 @@ function readRelationships(element) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function Relationships(relationships) {
|
|
22
|
-
var targetsByRelationshipId =
|
|
22
|
+
var targetsByRelationshipId = Object.create(null);
|
|
23
23
|
relationships.forEach(function(relationship) {
|
|
24
24
|
targetsByRelationshipId[relationship.relationshipId] = relationship.target;
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
var targetsByType =
|
|
27
|
+
var targetsByType = Object.create(null);
|
|
28
28
|
relationships.forEach(function(relationship) {
|
|
29
29
|
if (!targetsByType[relationship.type]) {
|
|
30
30
|
targetsByType[relationship.type] = [];
|
|
@@ -22,21 +22,32 @@ function Styles(paragraphStyles, characterStyles, tableStyles, numberingStyles)
|
|
|
22
22
|
Styles.EMPTY = new Styles({}, {}, {}, {});
|
|
23
23
|
|
|
24
24
|
function readStylesXml(root) {
|
|
25
|
-
var paragraphStyles =
|
|
26
|
-
var characterStyles =
|
|
27
|
-
var tableStyles =
|
|
28
|
-
var numberingStyles =
|
|
29
|
-
|
|
30
|
-
var styles = {
|
|
31
|
-
"paragraph": paragraphStyles,
|
|
32
|
-
"character": characterStyles,
|
|
33
|
-
"table": tableStyles,
|
|
34
|
-
"numbering": numberingStyles
|
|
35
|
-
};
|
|
25
|
+
var paragraphStyles = Object.create(null);
|
|
26
|
+
var characterStyles = Object.create(null);
|
|
27
|
+
var tableStyles = Object.create(null);
|
|
28
|
+
var numberingStyles = Object.create(null);
|
|
36
29
|
|
|
37
30
|
root.getElementsByTagName("w:style").forEach(function(styleElement) {
|
|
38
31
|
var style = readStyleElement(styleElement);
|
|
39
|
-
var styleSet
|
|
32
|
+
var styleSet;
|
|
33
|
+
|
|
34
|
+
switch (style.type) {
|
|
35
|
+
case "paragraph":
|
|
36
|
+
styleSet = paragraphStyles;
|
|
37
|
+
break;
|
|
38
|
+
|
|
39
|
+
case "character":
|
|
40
|
+
styleSet = characterStyles;
|
|
41
|
+
break;
|
|
42
|
+
|
|
43
|
+
case "table":
|
|
44
|
+
styleSet = tableStyles;
|
|
45
|
+
break;
|
|
46
|
+
|
|
47
|
+
case "numbering":
|
|
48
|
+
styleSet = numberingStyles;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
40
51
|
|
|
41
52
|
// Per 17.7.4.17 style (Style Definition) of ECMA-376 4th edition Part 1:
|
|
42
53
|
//
|
package/lib/style-reader.js
CHANGED
|
@@ -257,7 +257,7 @@ function htmlPathRule() {
|
|
|
257
257
|
capture(freshRule),
|
|
258
258
|
capture(separatorRule)
|
|
259
259
|
).map(function(tagName, attributesList, fresh, separator) {
|
|
260
|
-
var attributes =
|
|
260
|
+
var attributes = Object.create(null);
|
|
261
261
|
var options = {};
|
|
262
262
|
attributesList.forEach(function(attribute) {
|
|
263
263
|
if (attribute.append && attributes[attribute.name]) {
|
package/lib/styles/html-paths.js
CHANGED
|
@@ -38,7 +38,7 @@ function element(tagName, attributes, options) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function Element(tagName, attributes, options) {
|
|
41
|
-
var tagNames =
|
|
41
|
+
var tagNames = Object.create(null);
|
|
42
42
|
if (_.isArray(tagName)) {
|
|
43
43
|
tagName.forEach(function(tagName) {
|
|
44
44
|
tagNames[tagName] = true;
|
|
@@ -47,7 +47,7 @@ function Element(tagName, attributes, options) {
|
|
|
47
47
|
} else {
|
|
48
48
|
tagNames[tagName] = true;
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
this.tagName = tagName;
|
|
52
52
|
this.tagNames = tagNames;
|
|
53
53
|
this.attributes = attributes || {};
|
package/lib/xml/reader.js
CHANGED
|
@@ -42,7 +42,7 @@ function readString(xmlString, namespaceMap) {
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
var convertedAttributes =
|
|
45
|
+
var convertedAttributes = Object.create(null);
|
|
46
46
|
_.forEach(element.attributes, function(attribute) {
|
|
47
47
|
convertedAttributes[convertName(attribute)] = attribute.value;
|
|
48
48
|
});
|
package/mammoth.browser.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
// Module: lop@0.4.2
|
|
26
26
|
// License: BSD-2-Clause
|
|
27
27
|
//
|
|
28
|
-
// Module: mammoth@1.12.
|
|
28
|
+
// Module: mammoth@1.12.2
|
|
29
29
|
// License: BSD-2-Clause
|
|
30
30
|
//
|
|
31
31
|
// Module: option@0.2.4
|
|
@@ -115,7 +115,7 @@ function DocumentConversion(options, comments) {
|
|
|
115
115
|
function convertToHtml(document) {
|
|
116
116
|
var messages = [];
|
|
117
117
|
|
|
118
|
-
var html = elementToHtml(document, messages,
|
|
118
|
+
var html = elementToHtml(document, messages, Object.create(null));
|
|
119
119
|
|
|
120
120
|
var deferredNodes = [];
|
|
121
121
|
walkHtml(html, function(node) {
|
|
@@ -123,7 +123,7 @@ function DocumentConversion(options, comments) {
|
|
|
123
123
|
deferredNodes.push(node);
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
|
-
var deferredValues =
|
|
126
|
+
var deferredValues = Object.create(null);
|
|
127
127
|
return promises.mapSeries(deferredNodes, function(deferred) {
|
|
128
128
|
return deferred.value().then(function(value) {
|
|
129
129
|
deferredValues[deferred.id] = value;
|
|
@@ -1649,9 +1649,9 @@ exports.defaultContentTypes = contentTypes({}, {});
|
|
|
1649
1649
|
|
|
1650
1650
|
|
|
1651
1651
|
function readContentTypesFromXml(element) {
|
|
1652
|
-
var extensionDefaults =
|
|
1653
|
-
var overrides =
|
|
1654
|
-
|
|
1652
|
+
var extensionDefaults = Object.create(null);
|
|
1653
|
+
var overrides = Object.create(null);
|
|
1654
|
+
|
|
1655
1655
|
element.children.forEach(function(child) {
|
|
1656
1656
|
if (child.name === "content-types:Default") {
|
|
1657
1657
|
extensionDefaults[child.attributes.Extension] = child.attributes.ContentType;
|
|
@@ -1676,7 +1676,7 @@ function contentTypes(overrides, extensionDefaults) {
|
|
|
1676
1676
|
} else {
|
|
1677
1677
|
var pathParts = path.split(".");
|
|
1678
1678
|
var extension = pathParts[pathParts.length - 1];
|
|
1679
|
-
if (
|
|
1679
|
+
if (Object.prototype.hasOwnProperty.call(extensionDefaults, extension)) {
|
|
1680
1680
|
return extensionDefaults[extension];
|
|
1681
1681
|
} else {
|
|
1682
1682
|
var fallback = fallbackContentTypes[extension.toLowerCase()];
|
|
@@ -1689,7 +1689,7 @@ function contentTypes(overrides, extensionDefaults) {
|
|
|
1689
1689
|
}
|
|
1690
1690
|
}
|
|
1691
1691
|
};
|
|
1692
|
-
|
|
1692
|
+
|
|
1693
1693
|
}
|
|
1694
1694
|
|
|
1695
1695
|
},{}],8:[function(require,module,exports){
|
|
@@ -2002,7 +2002,7 @@ function Numbering(nums, abstractNums, styles) {
|
|
|
2002
2002
|
);
|
|
2003
2003
|
|
|
2004
2004
|
function findLevel(numId, level) {
|
|
2005
|
-
return findLevelWithSeenNumIds(numId, level,
|
|
2005
|
+
return findLevelWithSeenNumIds(numId, level, Object.create(null));
|
|
2006
2006
|
}
|
|
2007
2007
|
|
|
2008
2008
|
function findLevelWithSeenNumIds(numId, level, seenNumIds) {
|
|
@@ -2048,7 +2048,7 @@ function readNumberingXml(root, options) {
|
|
|
2048
2048
|
}
|
|
2049
2049
|
|
|
2050
2050
|
function readAbstractNums(root) {
|
|
2051
|
-
var abstractNums =
|
|
2051
|
+
var abstractNums = Object.create(null);
|
|
2052
2052
|
root.getElementsByTagName("w:abstractNum").forEach(function(element) {
|
|
2053
2053
|
var id = element.attributes["w:abstractNumId"];
|
|
2054
2054
|
abstractNums[id] = readAbstractNum(element);
|
|
@@ -2057,7 +2057,7 @@ function readAbstractNums(root) {
|
|
|
2057
2057
|
}
|
|
2058
2058
|
|
|
2059
2059
|
function readAbstractNum(element) {
|
|
2060
|
-
var levels =
|
|
2060
|
+
var levels = Object.create(null);
|
|
2061
2061
|
|
|
2062
2062
|
// Some malformed documents define numbering levels without an index, and
|
|
2063
2063
|
// reference the numbering using a w:numPr element without a w:ilvl child.
|
|
@@ -2095,7 +2095,7 @@ function readAbstractNum(element) {
|
|
|
2095
2095
|
}
|
|
2096
2096
|
|
|
2097
2097
|
function readNums(root) {
|
|
2098
|
-
var nums =
|
|
2098
|
+
var nums = Object.create(null);
|
|
2099
2099
|
root.getElementsByTagName("w:num").forEach(function(element) {
|
|
2100
2100
|
var numId = element.attributes["w:numId"];
|
|
2101
2101
|
var abstractNumId = element.first("w:abstractNumId").attributes["w:val"];
|
|
@@ -2201,12 +2201,12 @@ function readRelationships(element) {
|
|
|
2201
2201
|
}
|
|
2202
2202
|
|
|
2203
2203
|
function Relationships(relationships) {
|
|
2204
|
-
var targetsByRelationshipId =
|
|
2204
|
+
var targetsByRelationshipId = Object.create(null);
|
|
2205
2205
|
relationships.forEach(function(relationship) {
|
|
2206
2206
|
targetsByRelationshipId[relationship.relationshipId] = relationship.target;
|
|
2207
2207
|
});
|
|
2208
2208
|
|
|
2209
|
-
var targetsByType =
|
|
2209
|
+
var targetsByType = Object.create(null);
|
|
2210
2210
|
relationships.forEach(function(relationship) {
|
|
2211
2211
|
if (!targetsByType[relationship.type]) {
|
|
2212
2212
|
targetsByType[relationship.type] = [];
|
|
@@ -2326,21 +2326,32 @@ function Styles(paragraphStyles, characterStyles, tableStyles, numberingStyles)
|
|
|
2326
2326
|
Styles.EMPTY = new Styles({}, {}, {}, {});
|
|
2327
2327
|
|
|
2328
2328
|
function readStylesXml(root) {
|
|
2329
|
-
var paragraphStyles =
|
|
2330
|
-
var characterStyles =
|
|
2331
|
-
var tableStyles =
|
|
2332
|
-
var numberingStyles =
|
|
2333
|
-
|
|
2334
|
-
var styles = {
|
|
2335
|
-
"paragraph": paragraphStyles,
|
|
2336
|
-
"character": characterStyles,
|
|
2337
|
-
"table": tableStyles,
|
|
2338
|
-
"numbering": numberingStyles
|
|
2339
|
-
};
|
|
2329
|
+
var paragraphStyles = Object.create(null);
|
|
2330
|
+
var characterStyles = Object.create(null);
|
|
2331
|
+
var tableStyles = Object.create(null);
|
|
2332
|
+
var numberingStyles = Object.create(null);
|
|
2340
2333
|
|
|
2341
2334
|
root.getElementsByTagName("w:style").forEach(function(styleElement) {
|
|
2342
2335
|
var style = readStyleElement(styleElement);
|
|
2343
|
-
var styleSet
|
|
2336
|
+
var styleSet;
|
|
2337
|
+
|
|
2338
|
+
switch (style.type) {
|
|
2339
|
+
case "paragraph":
|
|
2340
|
+
styleSet = paragraphStyles;
|
|
2341
|
+
break;
|
|
2342
|
+
|
|
2343
|
+
case "character":
|
|
2344
|
+
styleSet = characterStyles;
|
|
2345
|
+
break;
|
|
2346
|
+
|
|
2347
|
+
case "table":
|
|
2348
|
+
styleSet = tableStyles;
|
|
2349
|
+
break;
|
|
2350
|
+
|
|
2351
|
+
case "numbering":
|
|
2352
|
+
styleSet = numberingStyles;
|
|
2353
|
+
break;
|
|
2354
|
+
}
|
|
2344
2355
|
|
|
2345
2356
|
// Per 17.7.4.17 style (Style Definition) of ECMA-376 4th edition Part 1:
|
|
2346
2357
|
//
|
|
@@ -3259,7 +3270,7 @@ function htmlPathRule() {
|
|
|
3259
3270
|
capture(freshRule),
|
|
3260
3271
|
capture(separatorRule)
|
|
3261
3272
|
).map(function(tagName, attributesList, fresh, separator) {
|
|
3262
|
-
var attributes =
|
|
3273
|
+
var attributes = Object.create(null);
|
|
3263
3274
|
var options = {};
|
|
3264
3275
|
attributesList.forEach(function(attribute) {
|
|
3265
3276
|
if (attribute.append && attributes[attribute.name]) {
|
|
@@ -3509,7 +3520,7 @@ function element(tagName, attributes, options) {
|
|
|
3509
3520
|
}
|
|
3510
3521
|
|
|
3511
3522
|
function Element(tagName, attributes, options) {
|
|
3512
|
-
var tagNames =
|
|
3523
|
+
var tagNames = Object.create(null);
|
|
3513
3524
|
if (_.isArray(tagName)) {
|
|
3514
3525
|
tagName.forEach(function(tagName) {
|
|
3515
3526
|
tagNames[tagName] = true;
|
|
@@ -3518,7 +3529,7 @@ function Element(tagName, attributes, options) {
|
|
|
3518
3529
|
} else {
|
|
3519
3530
|
tagNames[tagName] = true;
|
|
3520
3531
|
}
|
|
3521
|
-
|
|
3532
|
+
|
|
3522
3533
|
this.tagName = tagName;
|
|
3523
3534
|
this.tagNames = tagNames;
|
|
3524
3535
|
this.attributes = attributes || {};
|
|
@@ -4123,7 +4134,7 @@ function readString(xmlString, namespaceMap) {
|
|
|
4123
4134
|
}
|
|
4124
4135
|
});
|
|
4125
4136
|
|
|
4126
|
-
var convertedAttributes =
|
|
4137
|
+
var convertedAttributes = Object.create(null);
|
|
4127
4138
|
_.forEach(element.attributes, function(attribute) {
|
|
4128
4139
|
convertedAttributes[convertName(attribute)] = attribute.value;
|
|
4129
4140
|
});
|