@cdk8s/awscdk-resolver 0.0.609 → 0.0.610
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/.jsii +3 -3
- package/lib/resolve.js +1 -1
- package/node_modules/@aws-sdk/client-cloudformation/package.json +3 -3
- package/node_modules/@aws-sdk/core/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-env/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-http/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +9 -9
- package/node_modules/@aws-sdk/credential-provider-login/package.json +3 -3
- package/node_modules/@aws-sdk/credential-provider-node/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-process/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +3 -3
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/package.json +2 -2
- package/node_modules/@aws-sdk/token-providers/package.json +3 -3
- package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-parser.browser.js +1 -1
- package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-parser.js +233 -43
- package/node_modules/@aws-sdk/xml-builder/dist-es/xml-parser.browser.js +1 -1
- package/node_modules/@aws-sdk/xml-builder/dist-es/xml-parser.js +233 -43
- package/node_modules/@aws-sdk/xml-builder/dist-types/ts3.4/xml-parser.d.ts +1 -1
- package/node_modules/@aws-sdk/xml-builder/dist-types/xml-parser.d.ts +2 -1
- package/node_modules/@aws-sdk/xml-builder/package.json +4 -4
- package/node_modules/@smithy/core/dist-cjs/submodules/cbor/index.js +518 -371
- package/node_modules/@smithy/core/dist-cjs/submodules/client/index.js +1 -1
- package/node_modules/@smithy/core/dist-es/submodules/cbor/cbor-decode.js +326 -269
- package/node_modules/@smithy/core/dist-es/submodules/cbor/cbor-encode.js +192 -103
- package/node_modules/@smithy/core/dist-es/submodules/cbor/cbor.js +4 -2
- package/node_modules/@smithy/core/dist-es/submodules/client/smithy-client/get-value-from-text-node.js +1 -1
- package/node_modules/@smithy/core/dist-types/submodules/cbor/cbor-decode.d.ts +4 -0
- package/node_modules/@smithy/core/dist-types/submodules/cbor/cbor-encode.d.ts +8 -4
- package/node_modules/@smithy/core/package.json +1 -1
- package/node_modules/@smithy/credential-provider-imds/package.json +2 -2
- package/node_modules/@smithy/fetch-http-handler/package.json +2 -2
- package/node_modules/@smithy/node-http-handler/package.json +2 -2
- package/node_modules/@smithy/signature-v4/package.json +2 -2
- package/package.json +6 -6
- package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-external/nodable_entities.js +0 -333
- package/node_modules/@aws-sdk/xml-builder/dist-es/xml-external/nodable_entities.js +0 -332
- package/node_modules/@aws-sdk/xml-builder/dist-types/ts3.4/xml-external/nodable_entities.d.ts +0 -66
- package/node_modules/@aws-sdk/xml-builder/dist-types/xml-external/nodable_entities.d.ts +0 -65
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/CHANGELOG.md +0 -827
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/LICENSE +0 -21
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/README.md +0 -202
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxbuilder.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxbuilder.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.cjs +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.d.cts +0 -770
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxvalidator.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxvalidator.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/package.json +0 -93
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/cli/cli.js +0 -97
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/cli/man.js +0 -17
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/cli/read.js +0 -43
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/fxp.d.ts +0 -739
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/fxp.js +0 -14
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/ignoreAttributes.js +0 -18
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/util.js +0 -61
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/CharsSymbol.js +0 -16
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/EntitiesParser.js +0 -106
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OptionsBuilder.js +0 -61
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OutputBuilders/BaseOutputBuilder.js +0 -69
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsArrBuilder.js +0 -103
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsMinArrBuilder.js +0 -100
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsObjBuilder.js +0 -154
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/OutputBuilders/ParserOptionsBuilder.js +0 -94
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/Report.js +0 -0
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/TagPath.js +0 -81
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/TagPathMatcher.js +0 -13
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/XMLParser.js +0 -83
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/Xml2JsParser.js +0 -235
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/XmlPartReader.js +0 -210
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/XmlSpecialTagsReader.js +0 -111
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/inputSource/BufferSource.js +0 -116
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/inputSource/StringSource.js +0 -121
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/EntitiesParser.js +0 -105
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParser.js +0 -22
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParserExt.js +0 -19
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/currency.js +0 -38
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/join.js +0 -13
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/number.js +0 -14
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/v6/valueParsers/trim.js +0 -6
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/validator.js +0 -425
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js +0 -6
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js +0 -407
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +0 -163
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +0 -840
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js +0 -71
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/node2json.js +0 -177
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js +0 -40
- package/node_modules/@nodable/entities/README.md +0 -41
- package/node_modules/@nodable/entities/package.json +0 -57
- package/node_modules/@nodable/entities/src/EntityDecoder.js +0 -644
- package/node_modules/@nodable/entities/src/EntityEncoder.js +0 -194
- package/node_modules/@nodable/entities/src/entities.js +0 -1159
- package/node_modules/@nodable/entities/src/entityTries.js +0 -49
- package/node_modules/@nodable/entities/src/index.d.ts +0 -341
- package/node_modules/@nodable/entities/src/index.js +0 -29
- package/node_modules/anynum/LICENSE +0 -21
- package/node_modules/anynum/README.md +0 -142
- package/node_modules/anynum/anynum.js +0 -135
- package/node_modules/anynum/digitTable.js +0 -116
- package/node_modules/anynum/package.json +0 -42
- package/node_modules/fast-xml-builder/CHANGELOG.md +0 -40
- package/node_modules/fast-xml-builder/LICENSE +0 -21
- package/node_modules/fast-xml-builder/README.md +0 -74
- package/node_modules/fast-xml-builder/lib/fxb.cjs +0 -1
- package/node_modules/fast-xml-builder/lib/fxb.d.cts +0 -270
- package/node_modules/fast-xml-builder/lib/fxb.min.js +0 -2
- package/node_modules/fast-xml-builder/lib/fxb.min.js.map +0 -1
- package/node_modules/fast-xml-builder/package.json +0 -81
- package/node_modules/fast-xml-builder/src/fxb.d.ts +0 -270
- package/node_modules/fast-xml-builder/src/fxb.js +0 -599
- package/node_modules/fast-xml-builder/src/ignoreAttributes.js +0 -18
- package/node_modules/fast-xml-builder/src/orderedJs2Xml.js +0 -359
- package/node_modules/fast-xml-builder/src/prettifyJs2Xml.js +0 -0
- package/node_modules/fast-xml-builder/src/util.js +0 -16
- package/node_modules/path-expression-matcher/LICENSE +0 -21
- package/node_modules/path-expression-matcher/README.md +0 -947
- package/node_modules/path-expression-matcher/lib/pem.cjs +0 -1
- package/node_modules/path-expression-matcher/lib/pem.d.cts +0 -715
- package/node_modules/path-expression-matcher/lib/pem.min.js +0 -2
- package/node_modules/path-expression-matcher/lib/pem.min.js.map +0 -1
- package/node_modules/path-expression-matcher/package.json +0 -79
- package/node_modules/path-expression-matcher/src/Expression.js +0 -232
- package/node_modules/path-expression-matcher/src/ExpressionSet.js +0 -225
- package/node_modules/path-expression-matcher/src/Matcher.js +0 -660
- package/node_modules/path-expression-matcher/src/index.d.ts +0 -589
- package/node_modules/path-expression-matcher/src/index.js +0 -29
- package/node_modules/strnum/CHANGELOG.md +0 -51
- package/node_modules/strnum/LICENSE +0 -21
- package/node_modules/strnum/README.md +0 -113
- package/node_modules/strnum/package.json +0 -36
- package/node_modules/strnum/strnum.js +0 -171
- package/node_modules/xml-naming/README.md +0 -189
- package/node_modules/xml-naming/package.json +0 -54
- package/node_modules/xml-naming/src/index.d.ts +0 -74
- package/node_modules/xml-naming/src/index.js +0 -270
|
@@ -1,840 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
///@ts-check
|
|
3
|
-
|
|
4
|
-
import { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';
|
|
5
|
-
import xmlNode from './xmlNode.js';
|
|
6
|
-
import DocTypeReader from './DocTypeReader.js';
|
|
7
|
-
import toNumber from "strnum";
|
|
8
|
-
import getIgnoreAttributesFn from "../ignoreAttributes.js";
|
|
9
|
-
import { Expression, Matcher } from 'path-expression-matcher';
|
|
10
|
-
import { ExpressionSet } from 'path-expression-matcher';
|
|
11
|
-
import { EntityDecoder, XML, CURRENCY, COMMON_HTML } from '@nodable/entities';
|
|
12
|
-
|
|
13
|
-
// const regx =
|
|
14
|
-
// '<((!\\[CDATA\\[([\\s\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\/)(NAME)\\s*>))([^<]*)'
|
|
15
|
-
// .replace(/NAME/g, util.nameRegexp);
|
|
16
|
-
|
|
17
|
-
//const tagsRegx = new RegExp("<(\\/?[\\w:\\-\._]+)([^>]*)>(\\s*"+cdataRegx+")*([^<]+)?","g");
|
|
18
|
-
//const tagsRegx = new RegExp("<(\\/?)((\\w*:)?([\\w:\\-\._]+))([^>]*)>([^<]*)("+cdataRegx+"([^<]*))*([^<]+)?","g");
|
|
19
|
-
|
|
20
|
-
// Helper functions for attribute and namespace handling
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Extract raw attributes (without prefix) from prefixed attribute map
|
|
24
|
-
* @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap
|
|
25
|
-
* @param {object} options - Parser options containing attributeNamePrefix
|
|
26
|
-
* @returns {object} Raw attributes for matcher
|
|
27
|
-
*/
|
|
28
|
-
function extractRawAttributes(prefixedAttrs, options) {
|
|
29
|
-
if (!prefixedAttrs) return {};
|
|
30
|
-
|
|
31
|
-
// Handle attributesGroupName option
|
|
32
|
-
const attrs = options.attributesGroupName
|
|
33
|
-
? prefixedAttrs[options.attributesGroupName]
|
|
34
|
-
: prefixedAttrs;
|
|
35
|
-
|
|
36
|
-
if (!attrs) return {};
|
|
37
|
-
|
|
38
|
-
const rawAttrs = {};
|
|
39
|
-
for (const key in attrs) {
|
|
40
|
-
// Remove the attribute prefix to get raw name
|
|
41
|
-
if (key.startsWith(options.attributeNamePrefix)) {
|
|
42
|
-
const rawName = key.substring(options.attributeNamePrefix.length);
|
|
43
|
-
rawAttrs[rawName] = attrs[key];
|
|
44
|
-
} else {
|
|
45
|
-
// Attribute without prefix (shouldn't normally happen, but be safe)
|
|
46
|
-
rawAttrs[key] = attrs[key];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return rawAttrs;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Extract namespace from raw tag name
|
|
54
|
-
* @param {string} rawTagName - Tag name possibly with namespace (e.g., "soap:Envelope")
|
|
55
|
-
* @returns {string|undefined} Namespace or undefined
|
|
56
|
-
*/
|
|
57
|
-
function extractNamespace(rawTagName) {
|
|
58
|
-
if (!rawTagName || typeof rawTagName !== 'string') return undefined;
|
|
59
|
-
|
|
60
|
-
const colonIndex = rawTagName.indexOf(':');
|
|
61
|
-
if (colonIndex !== -1 && colonIndex > 0) {
|
|
62
|
-
const ns = rawTagName.substring(0, colonIndex);
|
|
63
|
-
// Don't treat xmlns as a namespace
|
|
64
|
-
if (ns !== 'xmlns') {
|
|
65
|
-
return ns;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export default class OrderedObjParser {
|
|
72
|
-
constructor(options, externalEntities) {
|
|
73
|
-
this.options = options;
|
|
74
|
-
this.currentNode = null;
|
|
75
|
-
this.tagsNodeStack = [];
|
|
76
|
-
this.parseXml = parseXml;
|
|
77
|
-
this.parseTextData = parseTextData;
|
|
78
|
-
this.resolveNameSpace = resolveNameSpace;
|
|
79
|
-
this.buildAttributesMap = buildAttributesMap;
|
|
80
|
-
this.isItStopNode = isItStopNode;
|
|
81
|
-
this.replaceEntitiesValue = replaceEntitiesValue;
|
|
82
|
-
this.readStopNodeData = readStopNodeData;
|
|
83
|
-
this.saveTextToParentTag = saveTextToParentTag;
|
|
84
|
-
this.addChild = addChild;
|
|
85
|
-
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)
|
|
86
|
-
this.entityExpansionCount = 0;
|
|
87
|
-
this.currentExpandedLength = 0;
|
|
88
|
-
let namedEntities = { ...XML };
|
|
89
|
-
if (this.options.entityDecoder) {
|
|
90
|
-
this.entityDecoder = this.options.entityDecoder
|
|
91
|
-
} else {
|
|
92
|
-
if (typeof this.options.htmlEntities === "object") namedEntities = this.options.htmlEntities;
|
|
93
|
-
else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };
|
|
94
|
-
this.entityDecoder = new EntityDecoder({
|
|
95
|
-
namedEntities: { ...namedEntities, ...externalEntities },
|
|
96
|
-
numericAllowed: this.options.htmlEntities,
|
|
97
|
-
limit: {
|
|
98
|
-
maxTotalExpansions: this.options.processEntities.maxTotalExpansions,
|
|
99
|
-
maxExpandedLength: this.options.processEntities.maxExpandedLength,
|
|
100
|
-
applyLimitsTo: this.options.processEntities.appliesTo,
|
|
101
|
-
}
|
|
102
|
-
//postCheck: resolved => resolved
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Initialize path matcher for path-expression-matcher
|
|
107
|
-
this.matcher = new Matcher();
|
|
108
|
-
|
|
109
|
-
// Live read-only proxy of matcher — PEM creates and caches this internally.
|
|
110
|
-
// All user callbacks receive this instead of the mutable matcher.
|
|
111
|
-
this.readonlyMatcher = this.matcher.readOnly();
|
|
112
|
-
|
|
113
|
-
// Flag to track if current node is a stop node (optimization)
|
|
114
|
-
this.isCurrentNodeStopNode = false;
|
|
115
|
-
|
|
116
|
-
// Pre-compile stopNodes expressions
|
|
117
|
-
this.stopNodeExpressionsSet = new ExpressionSet();
|
|
118
|
-
const stopNodesOpts = this.options.stopNodes;
|
|
119
|
-
if (stopNodesOpts && stopNodesOpts.length > 0) {
|
|
120
|
-
for (let i = 0; i < stopNodesOpts.length; i++) {
|
|
121
|
-
const stopNodeExp = stopNodesOpts[i];
|
|
122
|
-
if (typeof stopNodeExp === 'string') {
|
|
123
|
-
// Convert string to Expression object
|
|
124
|
-
this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));
|
|
125
|
-
} else if (stopNodeExp instanceof Expression) {
|
|
126
|
-
// Already an Expression object
|
|
127
|
-
this.stopNodeExpressionsSet.add(stopNodeExp);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.stopNodeExpressionsSet.seal();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @param {string} val
|
|
139
|
-
* @param {string} tagName
|
|
140
|
-
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
|
|
141
|
-
* @param {boolean} dontTrim
|
|
142
|
-
* @param {boolean} hasAttributes
|
|
143
|
-
* @param {boolean} isLeafNode
|
|
144
|
-
* @param {boolean} escapeEntities
|
|
145
|
-
*/
|
|
146
|
-
function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {
|
|
147
|
-
const options = this.options;
|
|
148
|
-
if (val !== undefined) {
|
|
149
|
-
if (options.trimValues && !dontTrim) {
|
|
150
|
-
val = val.trim();
|
|
151
|
-
}
|
|
152
|
-
if (val.length > 0) {
|
|
153
|
-
if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
|
|
154
|
-
|
|
155
|
-
// Pass jPath string or matcher based on options.jPath setting
|
|
156
|
-
const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;
|
|
157
|
-
const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
|
|
158
|
-
if (newval === null || newval === undefined) {
|
|
159
|
-
//don't parse
|
|
160
|
-
return val;
|
|
161
|
-
} else if (typeof newval !== typeof val || newval !== val) {
|
|
162
|
-
//overwrite
|
|
163
|
-
return newval;
|
|
164
|
-
} else if (options.trimValues) {
|
|
165
|
-
return parseValue(val, options.parseTagValue, options.numberParseOptions);
|
|
166
|
-
} else {
|
|
167
|
-
const trimmedVal = val.trim();
|
|
168
|
-
if (trimmedVal === val) {
|
|
169
|
-
return parseValue(val, options.parseTagValue, options.numberParseOptions);
|
|
170
|
-
} else {
|
|
171
|
-
return val;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function resolveNameSpace(tagname) {
|
|
179
|
-
if (this.options.removeNSPrefix) {
|
|
180
|
-
const tags = tagname.split(':');
|
|
181
|
-
const prefix = tagname.charAt(0) === '/' ? '/' : '';
|
|
182
|
-
if (tags[0] === 'xmlns') {
|
|
183
|
-
return '';
|
|
184
|
-
}
|
|
185
|
-
if (tags.length === 2) {
|
|
186
|
-
tagname = prefix + tags[1];
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return tagname;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
//TODO: change regex to capture NS
|
|
193
|
-
//const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm");
|
|
194
|
-
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
|
|
195
|
-
|
|
196
|
-
function buildAttributesMap(attrStr, jPath, tagName, force = false) {
|
|
197
|
-
const options = this.options;
|
|
198
|
-
if (force === true || (options.ignoreAttributes !== true && typeof attrStr === 'string')) {
|
|
199
|
-
// attrStr = attrStr.replace(/\r?\n/g, ' ');
|
|
200
|
-
//attrStr = attrStr || attrStr.trim();
|
|
201
|
-
|
|
202
|
-
const matches = getAllMatches(attrStr, attrsRegx);
|
|
203
|
-
const len = matches.length; //don't make it inline
|
|
204
|
-
const attrs = {};
|
|
205
|
-
|
|
206
|
-
// Pre-process values once: trim + entity replacement
|
|
207
|
-
// Reused in both matcher update and second pass
|
|
208
|
-
const processedVals = new Array(len);
|
|
209
|
-
let hasRawAttrs = false;
|
|
210
|
-
const rawAttrsForMatcher = {};
|
|
211
|
-
|
|
212
|
-
for (let i = 0; i < len; i++) {
|
|
213
|
-
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
214
|
-
const oldVal = matches[i][4];
|
|
215
|
-
|
|
216
|
-
if (attrName.length && oldVal !== undefined) {
|
|
217
|
-
let val = oldVal;
|
|
218
|
-
if (options.trimValues) val = val.trim();
|
|
219
|
-
val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);
|
|
220
|
-
processedVals[i] = val;
|
|
221
|
-
|
|
222
|
-
rawAttrsForMatcher[attrName] = val;
|
|
223
|
-
hasRawAttrs = true;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Update matcher ONCE before second pass, if applicable
|
|
228
|
-
if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) {
|
|
229
|
-
jPath.updateCurrent(rawAttrsForMatcher);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Hoist toString() once — path doesn't change during attribute processing
|
|
233
|
-
const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;
|
|
234
|
-
|
|
235
|
-
// Second pass: apply processors, build final attrs
|
|
236
|
-
let hasAttrs = false;
|
|
237
|
-
for (let i = 0; i < len; i++) {
|
|
238
|
-
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
239
|
-
|
|
240
|
-
if (this.ignoreAttributesFn(attrName, jPathStr)) continue;
|
|
241
|
-
|
|
242
|
-
let aName = options.attributeNamePrefix + attrName;
|
|
243
|
-
|
|
244
|
-
if (attrName.length) {
|
|
245
|
-
if (options.transformAttributeName) {
|
|
246
|
-
aName = options.transformAttributeName(aName);
|
|
247
|
-
}
|
|
248
|
-
aName = sanitizeName(aName, options);
|
|
249
|
-
|
|
250
|
-
if (matches[i][4] !== undefined) {
|
|
251
|
-
// Reuse already-processed value — no double entity replacement
|
|
252
|
-
const oldVal = processedVals[i];
|
|
253
|
-
|
|
254
|
-
const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);
|
|
255
|
-
if (newVal === null || newVal === undefined) {
|
|
256
|
-
attrs[aName] = oldVal;
|
|
257
|
-
} else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {
|
|
258
|
-
attrs[aName] = newVal;
|
|
259
|
-
} else {
|
|
260
|
-
attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);
|
|
261
|
-
}
|
|
262
|
-
hasAttrs = true;
|
|
263
|
-
} else if (options.allowBooleanAttributes) {
|
|
264
|
-
attrs[aName] = true;
|
|
265
|
-
hasAttrs = true;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!hasAttrs) return;
|
|
271
|
-
|
|
272
|
-
if (options.attributesGroupName && !options.preserveOrder) {
|
|
273
|
-
const attrCollection = {};
|
|
274
|
-
attrCollection[options.attributesGroupName] = attrs;
|
|
275
|
-
return attrCollection;
|
|
276
|
-
}
|
|
277
|
-
return attrs;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
const parseXml = function (xmlData) {
|
|
281
|
-
xmlData = xmlData.replace(/\r\n?/g, "\n"); //TODO: remove this line
|
|
282
|
-
const xmlObj = new xmlNode('!xml');
|
|
283
|
-
let currentNode = xmlObj;
|
|
284
|
-
let textData = "";
|
|
285
|
-
|
|
286
|
-
// Reset matcher for new document
|
|
287
|
-
this.matcher.reset();
|
|
288
|
-
this.entityDecoder.reset();
|
|
289
|
-
|
|
290
|
-
// Reset entity expansion counters for this document
|
|
291
|
-
this.entityExpansionCount = 0;
|
|
292
|
-
this.currentExpandedLength = 0;
|
|
293
|
-
const options = this.options;
|
|
294
|
-
const docTypeReader = new DocTypeReader(options.processEntities);
|
|
295
|
-
const xmlLen = xmlData.length;
|
|
296
|
-
for (let i = 0; i < xmlLen; i++) {//for each char in XML data
|
|
297
|
-
const ch = xmlData[i];
|
|
298
|
-
if (ch === '<') {
|
|
299
|
-
// const nextIndex = i+1;
|
|
300
|
-
// const _2ndChar = xmlData[nextIndex];
|
|
301
|
-
const c1 = xmlData.charCodeAt(i + 1);
|
|
302
|
-
if (c1 === 47) {//Closing Tag '/'
|
|
303
|
-
const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.")
|
|
304
|
-
let tagName = xmlData.substring(i + 2, closeIndex).trim();
|
|
305
|
-
|
|
306
|
-
if (options.removeNSPrefix) {
|
|
307
|
-
const colonIndex = tagName.indexOf(":");
|
|
308
|
-
if (colonIndex !== -1) {
|
|
309
|
-
tagName = tagName.substr(colonIndex + 1);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
tagName = transformTagName(options.transformTagName, tagName, "", options).tagName;
|
|
314
|
-
|
|
315
|
-
if (currentNode) {
|
|
316
|
-
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
//check if last tag of nested tag was unpaired tag
|
|
320
|
-
const lastTagName = this.matcher.getCurrentTag();
|
|
321
|
-
if (tagName && options.unpairedTagsSet.has(tagName)) {
|
|
322
|
-
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
|
|
323
|
-
}
|
|
324
|
-
if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {
|
|
325
|
-
// Pop the unpaired tag
|
|
326
|
-
this.matcher.pop();
|
|
327
|
-
this.tagsNodeStack.pop();
|
|
328
|
-
}
|
|
329
|
-
// Pop the closing tag
|
|
330
|
-
this.matcher.pop();
|
|
331
|
-
this.isCurrentNodeStopNode = false; // Reset flag when closing tag
|
|
332
|
-
|
|
333
|
-
currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
|
|
334
|
-
textData = "";
|
|
335
|
-
i = closeIndex;
|
|
336
|
-
} else if (c1 === 63) { //'?'
|
|
337
|
-
|
|
338
|
-
let tagData = readTagExp(xmlData, i, false, "?>");
|
|
339
|
-
if (!tagData) throw new Error("Pi Tag is not closed.");
|
|
340
|
-
|
|
341
|
-
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
342
|
-
const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);
|
|
343
|
-
if (attsMap) {
|
|
344
|
-
const ver = attsMap[this.options.attributeNamePrefix + "version"];
|
|
345
|
-
this.entityDecoder.setXmlVersion(Number(ver) || 1.0);
|
|
346
|
-
}
|
|
347
|
-
if ((options.ignoreDeclaration && tagData.tagName === "?xml") || options.ignorePiTags) {
|
|
348
|
-
//do nothing
|
|
349
|
-
} else {
|
|
350
|
-
|
|
351
|
-
const childNode = new xmlNode(tagData.tagName);
|
|
352
|
-
childNode.add(options.textNodeName, "");
|
|
353
|
-
|
|
354
|
-
if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {
|
|
355
|
-
childNode[":@"] = attsMap
|
|
356
|
-
}
|
|
357
|
-
this.addChild(currentNode, childNode, this.readonlyMatcher, i);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
i = tagData.closeIndex + 1;
|
|
362
|
-
} else if (c1 === 33
|
|
363
|
-
&& xmlData.charCodeAt(i + 2) === 45
|
|
364
|
-
&& xmlData.charCodeAt(i + 3) === 45) { //'!--'
|
|
365
|
-
const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed.")
|
|
366
|
-
if (options.commentPropName) {
|
|
367
|
-
const comment = xmlData.substring(i + 4, endIndex - 2);
|
|
368
|
-
|
|
369
|
-
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
370
|
-
|
|
371
|
-
currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);
|
|
372
|
-
}
|
|
373
|
-
i = endIndex;
|
|
374
|
-
} else if (c1 === 33
|
|
375
|
-
&& xmlData.charCodeAt(i + 2) === 68) { //'!D'
|
|
376
|
-
const result = docTypeReader.readDocType(xmlData, i);
|
|
377
|
-
this.entityDecoder.addInputEntities(result.entities);
|
|
378
|
-
i = result.i;
|
|
379
|
-
} else if (c1 === 33
|
|
380
|
-
&& xmlData.charCodeAt(i + 2) === 91) { // '!['
|
|
381
|
-
const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
|
|
382
|
-
const tagExp = xmlData.substring(i + 9, closeIndex);
|
|
383
|
-
|
|
384
|
-
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
385
|
-
|
|
386
|
-
let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);
|
|
387
|
-
if (val == undefined) val = "";
|
|
388
|
-
|
|
389
|
-
//cdata should be set even if it is 0 length string
|
|
390
|
-
if (options.cdataPropName) {
|
|
391
|
-
currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);
|
|
392
|
-
} else {
|
|
393
|
-
currentNode.add(options.textNodeName, val);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
i = closeIndex + 2;
|
|
397
|
-
} else {//Opening tag
|
|
398
|
-
let result = readTagExp(xmlData, i, options.removeNSPrefix);
|
|
399
|
-
|
|
400
|
-
// Safety check: readTagExp can return undefined
|
|
401
|
-
if (!result) {
|
|
402
|
-
// Log context for debugging
|
|
403
|
-
const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));
|
|
404
|
-
throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
let tagName = result.tagName;
|
|
408
|
-
const rawTagName = result.rawTagName;
|
|
409
|
-
let tagExp = result.tagExp;
|
|
410
|
-
let attrExpPresent = result.attrExpPresent;
|
|
411
|
-
let closeIndex = result.closeIndex;
|
|
412
|
-
|
|
413
|
-
({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
|
|
414
|
-
|
|
415
|
-
if (options.strictReservedNames &&
|
|
416
|
-
(tagName === options.commentPropName
|
|
417
|
-
|| tagName === options.cdataPropName
|
|
418
|
-
|| tagName === options.textNodeName
|
|
419
|
-
|| tagName === options.attributesGroupName
|
|
420
|
-
)) {
|
|
421
|
-
throw new Error(`Invalid tag name: ${tagName}`);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
//save text as child node
|
|
425
|
-
if (currentNode && textData) {
|
|
426
|
-
if (currentNode.tagname !== '!xml') {
|
|
427
|
-
//when nested tag is found
|
|
428
|
-
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
//check if last tag was unpaired tag
|
|
433
|
-
const lastTag = currentNode;
|
|
434
|
-
if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {
|
|
435
|
-
currentNode = this.tagsNodeStack.pop();
|
|
436
|
-
this.matcher.pop();
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Clean up self-closing syntax BEFORE processing attributes
|
|
440
|
-
// This is where tagExp gets the trailing / removed
|
|
441
|
-
let isSelfClosing = false;
|
|
442
|
-
if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
|
|
443
|
-
isSelfClosing = true;
|
|
444
|
-
if (tagName[tagName.length - 1] === "/") {
|
|
445
|
-
tagName = tagName.substr(0, tagName.length - 1);
|
|
446
|
-
tagExp = tagName;
|
|
447
|
-
} else {
|
|
448
|
-
tagExp = tagExp.substr(0, tagExp.length - 1);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Re-check attrExpPresent after cleaning
|
|
452
|
-
attrExpPresent = (tagName !== tagExp);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// Now process attributes with CLEAN tagExp (no trailing /)
|
|
456
|
-
let prefixedAttrs = null;
|
|
457
|
-
let rawAttrs = {};
|
|
458
|
-
let namespace = undefined;
|
|
459
|
-
|
|
460
|
-
// Extract namespace from rawTagName
|
|
461
|
-
namespace = extractNamespace(rawTagName);
|
|
462
|
-
|
|
463
|
-
// Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path
|
|
464
|
-
if (tagName !== xmlObj.tagname) {
|
|
465
|
-
this.matcher.push(tagName, {}, namespace);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
// Now build attributes - callbacks will see correct matcher state
|
|
469
|
-
if (tagName !== tagExp && attrExpPresent) {
|
|
470
|
-
// Build attributes (returns prefixed attributes for the tree)
|
|
471
|
-
// Note: buildAttributesMap now internally updates the matcher with raw attributes
|
|
472
|
-
prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
|
|
473
|
-
|
|
474
|
-
if (prefixedAttrs) {
|
|
475
|
-
// Extract raw attributes (without prefix) for our use
|
|
476
|
-
//TODO: seems a performance overhead
|
|
477
|
-
rawAttrs = extractRawAttributes(prefixedAttrs, options);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Now check if this is a stop node (after attributes are set)
|
|
482
|
-
if (tagName !== xmlObj.tagname) {
|
|
483
|
-
this.isCurrentNodeStopNode = this.isItStopNode();
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
const startIndex = i;
|
|
487
|
-
if (this.isCurrentNodeStopNode) {
|
|
488
|
-
let tagContent = "";
|
|
489
|
-
|
|
490
|
-
// For self-closing tags, content is empty
|
|
491
|
-
if (isSelfClosing) {
|
|
492
|
-
i = result.closeIndex;
|
|
493
|
-
}
|
|
494
|
-
//unpaired tag
|
|
495
|
-
else if (options.unpairedTagsSet.has(tagName)) {
|
|
496
|
-
i = result.closeIndex;
|
|
497
|
-
}
|
|
498
|
-
//normal tag
|
|
499
|
-
else {
|
|
500
|
-
//read until closing tag is found
|
|
501
|
-
const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
|
|
502
|
-
if (!result) throw new Error(`Unexpected end of ${rawTagName}`);
|
|
503
|
-
i = result.i;
|
|
504
|
-
tagContent = result.tagContent;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
const childNode = new xmlNode(tagName);
|
|
508
|
-
|
|
509
|
-
if (prefixedAttrs) {
|
|
510
|
-
childNode[":@"] = prefixedAttrs;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// For stop nodes, store raw content as-is without any processing
|
|
514
|
-
childNode.add(options.textNodeName, tagContent);
|
|
515
|
-
|
|
516
|
-
this.matcher.pop(); // Pop the stop node tag
|
|
517
|
-
this.isCurrentNodeStopNode = false; // Reset flag
|
|
518
|
-
|
|
519
|
-
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
520
|
-
} else {
|
|
521
|
-
//selfClosing tag
|
|
522
|
-
if (isSelfClosing) {
|
|
523
|
-
({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
|
|
524
|
-
|
|
525
|
-
const childNode = new xmlNode(tagName);
|
|
526
|
-
if (prefixedAttrs) {
|
|
527
|
-
childNode[":@"] = prefixedAttrs;
|
|
528
|
-
}
|
|
529
|
-
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
530
|
-
this.matcher.pop(); // Pop self-closing tag
|
|
531
|
-
this.isCurrentNodeStopNode = false; // Reset flag
|
|
532
|
-
}
|
|
533
|
-
else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag
|
|
534
|
-
const childNode = new xmlNode(tagName);
|
|
535
|
-
if (prefixedAttrs) {
|
|
536
|
-
childNode[":@"] = prefixedAttrs;
|
|
537
|
-
}
|
|
538
|
-
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
539
|
-
this.matcher.pop(); // Pop unpaired tag
|
|
540
|
-
this.isCurrentNodeStopNode = false; // Reset flag
|
|
541
|
-
i = result.closeIndex;
|
|
542
|
-
// Continue to next iteration without changing currentNode
|
|
543
|
-
continue;
|
|
544
|
-
}
|
|
545
|
-
//opening tag
|
|
546
|
-
else {
|
|
547
|
-
const childNode = new xmlNode(tagName);
|
|
548
|
-
if (this.tagsNodeStack.length > options.maxNestedTags) {
|
|
549
|
-
throw new Error("Maximum nested tags exceeded");
|
|
550
|
-
}
|
|
551
|
-
this.tagsNodeStack.push(currentNode);
|
|
552
|
-
|
|
553
|
-
if (prefixedAttrs) {
|
|
554
|
-
childNode[":@"] = prefixedAttrs;
|
|
555
|
-
}
|
|
556
|
-
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
557
|
-
currentNode = childNode;
|
|
558
|
-
}
|
|
559
|
-
textData = "";
|
|
560
|
-
i = closeIndex;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
} else {
|
|
564
|
-
textData += xmlData[i];
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return xmlObj.child;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
function addChild(currentNode, childNode, matcher, startIndex) {
|
|
571
|
-
// unset startIndex if not requested
|
|
572
|
-
if (!this.options.captureMetaData) startIndex = undefined;
|
|
573
|
-
|
|
574
|
-
// Pass jPath string or matcher based on options.jPath setting
|
|
575
|
-
const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
|
|
576
|
-
const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"])
|
|
577
|
-
if (result === false) {
|
|
578
|
-
//do nothing
|
|
579
|
-
} else if (typeof result === "string") {
|
|
580
|
-
childNode.tagname = result
|
|
581
|
-
currentNode.addChild(childNode, startIndex);
|
|
582
|
-
} else {
|
|
583
|
-
currentNode.addChild(childNode, startIndex);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* @param {object} val - Entity object with regex and val properties
|
|
589
|
-
* @param {string} tagName - Tag name
|
|
590
|
-
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
|
|
591
|
-
*/
|
|
592
|
-
function replaceEntitiesValue(val, tagName, jPath) {
|
|
593
|
-
const entityConfig = this.options.processEntities;
|
|
594
|
-
|
|
595
|
-
if (!entityConfig || !entityConfig.enabled) {
|
|
596
|
-
return val;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// Check if tag is allowed to contain entities
|
|
600
|
-
if (entityConfig.allowedTags) {
|
|
601
|
-
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
602
|
-
const allowed = Array.isArray(entityConfig.allowedTags)
|
|
603
|
-
? entityConfig.allowedTags.includes(tagName)
|
|
604
|
-
: entityConfig.allowedTags(tagName, jPathOrMatcher);
|
|
605
|
-
|
|
606
|
-
if (!allowed) {
|
|
607
|
-
return val;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Apply custom tag filter if provided
|
|
612
|
-
if (entityConfig.tagFilter) {
|
|
613
|
-
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
614
|
-
if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {
|
|
615
|
-
return val; // Skip based on custom filter
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return this.entityDecoder.decode(val);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
|
|
624
|
-
if (textData) { //store previously collected data as textNode
|
|
625
|
-
if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0
|
|
626
|
-
|
|
627
|
-
textData = this.parseTextData(textData,
|
|
628
|
-
parentNode.tagname,
|
|
629
|
-
matcher,
|
|
630
|
-
false,
|
|
631
|
-
parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false,
|
|
632
|
-
isLeafNode);
|
|
633
|
-
|
|
634
|
-
if (textData !== undefined && textData !== "")
|
|
635
|
-
parentNode.add(this.options.textNodeName, textData);
|
|
636
|
-
textData = "";
|
|
637
|
-
}
|
|
638
|
-
return textData;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* @param {Array<Expression>} stopNodeExpressions - Array of compiled Expression objects
|
|
643
|
-
* @param {Matcher} matcher - Current path matcher
|
|
644
|
-
*/
|
|
645
|
-
function isItStopNode() {
|
|
646
|
-
if (this.stopNodeExpressionsSet.size === 0) return false;
|
|
647
|
-
|
|
648
|
-
return this.matcher.matchesAny(this.stopNodeExpressionsSet);
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* Returns the tag Expression and where it is ending handling single-double quotes situation
|
|
653
|
-
* @param {string} xmlData
|
|
654
|
-
* @param {number} i starting index
|
|
655
|
-
* @returns
|
|
656
|
-
*/
|
|
657
|
-
function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
|
|
658
|
-
//TODO: ignore boolean attributes in tag expression
|
|
659
|
-
//TODO: if ignore attributes, dont read full attribute expression but the end. But read for xml declaration
|
|
660
|
-
let attrBoundary = 0;
|
|
661
|
-
const len = xmlData.length;
|
|
662
|
-
const closeCode0 = closingChar.charCodeAt(0);
|
|
663
|
-
const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;
|
|
664
|
-
|
|
665
|
-
let result = '';
|
|
666
|
-
let segmentStart = i;
|
|
667
|
-
|
|
668
|
-
for (let index = i; index < len; index++) {
|
|
669
|
-
const code = xmlData.charCodeAt(index);
|
|
670
|
-
|
|
671
|
-
if (attrBoundary) {
|
|
672
|
-
if (code === attrBoundary) attrBoundary = 0;
|
|
673
|
-
} else if (code === 34 || code === 39) { // " or '
|
|
674
|
-
attrBoundary = code;
|
|
675
|
-
} else if (code === closeCode0) {
|
|
676
|
-
if (closeCode1 !== -1) {
|
|
677
|
-
if (xmlData.charCodeAt(index + 1) === closeCode1) {
|
|
678
|
-
result += xmlData.substring(segmentStart, index);
|
|
679
|
-
return { data: result, index };
|
|
680
|
-
}
|
|
681
|
-
} else {
|
|
682
|
-
result += xmlData.substring(segmentStart, index);
|
|
683
|
-
return { data: result, index };
|
|
684
|
-
}
|
|
685
|
-
} else if (code === 9 && !attrBoundary) { // \t - only replace with space outside attribute values
|
|
686
|
-
// Flush accumulated segment, add space, start new segment
|
|
687
|
-
result += xmlData.substring(segmentStart, index) + ' ';
|
|
688
|
-
segmentStart = index + 1;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
function findClosingIndex(xmlData, str, i, errMsg) {
|
|
694
|
-
const closingIndex = xmlData.indexOf(str, i);
|
|
695
|
-
if (closingIndex === -1) {
|
|
696
|
-
throw new Error(errMsg)
|
|
697
|
-
} else {
|
|
698
|
-
return closingIndex + str.length - 1;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
function findClosingChar(xmlData, char, i, errMsg) {
|
|
703
|
-
const closingIndex = xmlData.indexOf(char, i);
|
|
704
|
-
if (closingIndex === -1) throw new Error(errMsg);
|
|
705
|
-
return closingIndex; // no offset needed
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") {
|
|
709
|
-
const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);
|
|
710
|
-
if (!result) return;
|
|
711
|
-
let tagExp = result.data;
|
|
712
|
-
const closeIndex = result.index;
|
|
713
|
-
const separatorIndex = tagExp.search(/\s/);
|
|
714
|
-
let tagName = tagExp;
|
|
715
|
-
let attrExpPresent = true;
|
|
716
|
-
if (separatorIndex !== -1) {//separate tag name and attributes expression
|
|
717
|
-
tagName = tagExp.substring(0, separatorIndex);
|
|
718
|
-
tagExp = tagExp.substring(separatorIndex + 1).trimStart();
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const rawTagName = tagName;
|
|
722
|
-
if (removeNSPrefix) {
|
|
723
|
-
const colonIndex = tagName.indexOf(":");
|
|
724
|
-
if (colonIndex !== -1) {
|
|
725
|
-
tagName = tagName.substr(colonIndex + 1);
|
|
726
|
-
attrExpPresent = tagName !== result.data.substr(colonIndex + 1);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
return {
|
|
731
|
-
tagName: tagName,
|
|
732
|
-
tagExp: tagExp,
|
|
733
|
-
closeIndex: closeIndex,
|
|
734
|
-
attrExpPresent: attrExpPresent,
|
|
735
|
-
rawTagName: rawTagName,
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* find paired tag for a stop node
|
|
740
|
-
* @param {string} xmlData
|
|
741
|
-
* @param {string} tagName
|
|
742
|
-
* @param {number} i
|
|
743
|
-
*/
|
|
744
|
-
function readStopNodeData(xmlData, tagName, i) {
|
|
745
|
-
const startIndex = i;
|
|
746
|
-
// Starting at 1 since we already have an open tag
|
|
747
|
-
let openTagCount = 1;
|
|
748
|
-
|
|
749
|
-
const xmllen = xmlData.length;
|
|
750
|
-
for (; i < xmllen; i++) {
|
|
751
|
-
if (xmlData[i] === "<") {
|
|
752
|
-
const c1 = xmlData.charCodeAt(i + 1);
|
|
753
|
-
if (c1 === 47) {//close tag '/'
|
|
754
|
-
const closeIndex = findClosingChar(xmlData, ">", i, `${tagName} is not closed`);
|
|
755
|
-
let closeTagName = xmlData.substring(i + 2, closeIndex).trim();
|
|
756
|
-
if (closeTagName === tagName) {
|
|
757
|
-
openTagCount--;
|
|
758
|
-
if (openTagCount === 0) {
|
|
759
|
-
return {
|
|
760
|
-
tagContent: xmlData.substring(startIndex, i),
|
|
761
|
-
i: closeIndex
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
i = closeIndex;
|
|
766
|
-
} else if (c1 === 63) { //?
|
|
767
|
-
const closeIndex = findClosingIndex(xmlData, "?>", i + 1, "StopNode is not closed.")
|
|
768
|
-
i = closeIndex;
|
|
769
|
-
} else if (c1 === 33
|
|
770
|
-
&& xmlData.charCodeAt(i + 2) === 45
|
|
771
|
-
&& xmlData.charCodeAt(i + 3) === 45) { // '!--'
|
|
772
|
-
const closeIndex = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed.")
|
|
773
|
-
i = closeIndex;
|
|
774
|
-
} else if (c1 === 33
|
|
775
|
-
&& xmlData.charCodeAt(i + 2) === 91) { // '!['
|
|
776
|
-
const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
|
|
777
|
-
i = closeIndex;
|
|
778
|
-
} else {
|
|
779
|
-
const tagData = readTagExp(xmlData, i, false)
|
|
780
|
-
|
|
781
|
-
if (tagData) {
|
|
782
|
-
const openTagName = tagData && tagData.tagName;
|
|
783
|
-
if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== "/") {
|
|
784
|
-
openTagCount++;
|
|
785
|
-
}
|
|
786
|
-
i = tagData.closeIndex;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
}//end for loop
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
function parseValue(val, shouldParse, options) {
|
|
794
|
-
if (shouldParse && typeof val === 'string') {
|
|
795
|
-
//console.log(options)
|
|
796
|
-
const newval = val.trim();
|
|
797
|
-
if (newval === 'true') return true;
|
|
798
|
-
else if (newval === 'false') return false;
|
|
799
|
-
else return toNumber(val, options);
|
|
800
|
-
} else {
|
|
801
|
-
if (isExist(val)) {
|
|
802
|
-
return val;
|
|
803
|
-
} else {
|
|
804
|
-
return '';
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
function fromCodePoint(str, base, prefix) {
|
|
810
|
-
const codePoint = Number.parseInt(str, base);
|
|
811
|
-
|
|
812
|
-
if (codePoint >= 0 && codePoint <= 0x10FFFF) {
|
|
813
|
-
return String.fromCodePoint(codePoint);
|
|
814
|
-
} else {
|
|
815
|
-
return prefix + str + ";";
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
function transformTagName(fn, tagName, tagExp, options) {
|
|
820
|
-
if (fn) {
|
|
821
|
-
const newTagName = fn(tagName);
|
|
822
|
-
if (tagExp === tagName) {
|
|
823
|
-
tagExp = newTagName
|
|
824
|
-
}
|
|
825
|
-
tagName = newTagName;
|
|
826
|
-
}
|
|
827
|
-
tagName = sanitizeName(tagName, options);
|
|
828
|
-
return { tagName, tagExp };
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
function sanitizeName(name, options) {
|
|
834
|
-
if (criticalProperties.includes(name)) {
|
|
835
|
-
throw new Error(`[SECURITY] Invalid name: "${name}" is a reserved JavaScript keyword that could cause prototype pollution`);
|
|
836
|
-
} else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
|
|
837
|
-
return options.onDangerousProperty(name);
|
|
838
|
-
}
|
|
839
|
-
return name;
|
|
840
|
-
}
|