@jjrawlins/cdk-diff-pr-github-action 1.4.3 → 1.5.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.
Files changed (104) hide show
  1. package/.jsii +4 -4
  2. package/lib/CdkDiffIamTemplate.js +2 -2
  3. package/lib/CdkDiffIamTemplateStackSet.js +2 -2
  4. package/lib/CdkDiffStackWorkflow.js +1 -1
  5. package/lib/CdkDriftDetectionWorkflow.js +1 -1
  6. package/lib/CdkDriftIamTemplate.js +2 -2
  7. package/lib/bin/cdk-changeset-script.js +4 -2
  8. package/node_modules/@aws-sdk/client-cloudformation/package.json +12 -12
  9. package/node_modules/@aws-sdk/client-sso/package.json +11 -11
  10. package/node_modules/@aws-sdk/core/dist-cjs/index.js +15 -6
  11. package/node_modules/@aws-sdk/core/dist-cjs/submodules/protocols/index.js +15 -6
  12. package/node_modules/@aws-sdk/core/dist-es/submodules/protocols/query/AwsEc2QueryProtocol.js +1 -0
  13. package/node_modules/@aws-sdk/core/dist-es/submodules/protocols/query/QueryShapeSerializer.js +14 -6
  14. package/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QuerySerializerSettings.d.ts +4 -0
  15. package/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QueryShapeSerializer.d.ts +1 -1
  16. package/node_modules/@aws-sdk/core/dist-types/ts3.4/submodules/protocols/query/QuerySerializerSettings.d.ts +1 -0
  17. package/node_modules/@aws-sdk/core/dist-types/ts3.4/submodules/protocols/query/QueryShapeSerializer.d.ts +6 -1
  18. package/node_modules/@aws-sdk/core/package.json +4 -4
  19. package/node_modules/@aws-sdk/credential-provider-env/package.json +2 -2
  20. package/node_modules/@aws-sdk/credential-provider-http/package.json +3 -3
  21. package/node_modules/@aws-sdk/credential-provider-ini/package.json +9 -9
  22. package/node_modules/@aws-sdk/credential-provider-login/package.json +3 -3
  23. package/node_modules/@aws-sdk/credential-provider-node/package.json +7 -7
  24. package/node_modules/@aws-sdk/credential-provider-process/package.json +2 -2
  25. package/node_modules/@aws-sdk/credential-provider-sso/package.json +4 -4
  26. package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +3 -3
  27. package/node_modules/@aws-sdk/middleware-user-agent/package.json +4 -4
  28. package/node_modules/@aws-sdk/nested-clients/package.json +11 -11
  29. package/node_modules/@aws-sdk/token-providers/package.json +3 -3
  30. package/node_modules/@aws-sdk/util-endpoints/package.json +1 -1
  31. package/node_modules/@aws-sdk/util-user-agent-node/package.json +2 -2
  32. package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
  33. package/node_modules/@smithy/core/dist-cjs/submodules/event-streams/index.js +3 -0
  34. package/node_modules/@smithy/core/dist-cjs/submodules/protocols/index.js +3 -1
  35. package/node_modules/@smithy/core/dist-es/submodules/event-streams/EventStreamSerde.js +3 -0
  36. package/node_modules/@smithy/core/dist-es/submodules/protocols/HttpBindingProtocol.js +3 -1
  37. package/node_modules/@smithy/core/package.json +1 -1
  38. package/node_modules/@smithy/middleware-endpoint/package.json +2 -2
  39. package/node_modules/@smithy/middleware-retry/package.json +2 -2
  40. package/node_modules/@smithy/smithy-client/package.json +3 -3
  41. package/node_modules/@smithy/util-defaults-mode-browser/package.json +2 -2
  42. package/node_modules/@smithy/util-defaults-mode-node/package.json +2 -2
  43. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/CHANGELOG.md +13 -0
  44. package/node_modules/fast-xml-parser/lib/fxp.cjs +1 -0
  45. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxp.d.cts +83 -14
  46. package/node_modules/fast-xml-parser/lib/fxp.min.js +2 -0
  47. package/node_modules/fast-xml-parser/lib/fxp.min.js.map +1 -0
  48. package/node_modules/fast-xml-parser/lib/fxparser.min.js +2 -0
  49. package/node_modules/fast-xml-parser/lib/fxparser.min.js.map +1 -0
  50. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/package.json +4 -4
  51. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/fxp.d.ts +74 -12
  52. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/EntitiesParser.js +7 -5
  53. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/DocTypeReader.js +65 -53
  54. package/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +86 -0
  55. package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/OrderedObjParser.js +255 -187
  56. package/package.json +2 -2
  57. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.cjs +0 -1
  58. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js +0 -2
  59. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js.map +0 -1
  60. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js +0 -2
  61. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js.map +0 -1
  62. package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +0 -46
  63. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/LICENSE +0 -0
  64. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/README.md +0 -0
  65. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxbuilder.min.js +0 -0
  66. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxbuilder.min.js.map +0 -0
  67. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxvalidator.min.js +0 -0
  68. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxvalidator.min.js.map +0 -0
  69. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/cli.js +0 -0
  70. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/man.js +0 -0
  71. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/read.js +0 -0
  72. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/fxp.js +0 -0
  73. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/ignoreAttributes.js +0 -0
  74. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/util.js +0 -0
  75. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/CharsSymbol.js +0 -0
  76. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OptionsBuilder.js +0 -0
  77. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/BaseOutputBuilder.js +0 -0
  78. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsArrBuilder.js +0 -0
  79. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsMinArrBuilder.js +0 -0
  80. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsObjBuilder.js +0 -0
  81. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/ParserOptionsBuilder.js +0 -0
  82. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/Report.js +0 -0
  83. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/TagPath.js +0 -0
  84. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/TagPathMatcher.js +0 -0
  85. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XMLParser.js +0 -0
  86. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/Xml2JsParser.js +0 -0
  87. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XmlPartReader.js +0 -0
  88. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XmlSpecialTagsReader.js +0 -0
  89. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/inputSource/BufferSource.js +0 -0
  90. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/inputSource/StringSource.js +0 -0
  91. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/EntitiesParser.js +0 -0
  92. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/booleanParser.js +0 -0
  93. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/booleanParserExt.js +0 -0
  94. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/currency.js +0 -0
  95. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/join.js +0 -0
  96. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/number.js +0 -0
  97. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/trim.js +0 -0
  98. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/validator.js +0 -0
  99. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlbuilder/json2xml.js +0 -0
  100. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlbuilder/orderedJs2Xml.js +0 -0
  101. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlbuilder/prettifyJs2Xml.js +0 -0
  102. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/XMLParser.js +0 -0
  103. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/node2json.js +0 -0
  104. /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/xmlNode.js +0 -0
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
  ///@ts-check
3
3
 
4
- import {getAllMatches, isExist} from '../util.js';
4
+ import { getAllMatches, isExist } from '../util.js';
5
5
  import xmlNode from './xmlNode.js';
6
6
  import DocTypeReader from './DocTypeReader.js';
7
7
  import toNumber from "strnum";
@@ -14,19 +14,19 @@ import getIgnoreAttributesFn from "../ignoreAttributes.js";
14
14
  //const tagsRegx = new RegExp("<(\\/?[\\w:\\-\._]+)([^>]*)>(\\s*"+cdataRegx+")*([^<]+)?","g");
15
15
  //const tagsRegx = new RegExp("<(\\/?)((\\w*:)?([\\w:\\-\._]+))([^>]*)>([^<]*)("+cdataRegx+"([^<]*))*([^<]+)?","g");
16
16
 
17
- export default class OrderedObjParser{
18
- constructor(options){
17
+ export default class OrderedObjParser {
18
+ constructor(options) {
19
19
  this.options = options;
20
20
  this.currentNode = null;
21
21
  this.tagsNodeStack = [];
22
22
  this.docTypeEntities = {};
23
23
  this.lastEntities = {
24
- "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
25
- "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
26
- "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
27
- "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
24
+ "apos": { regex: /&(apos|#39|#x27);/g, val: "'" },
25
+ "gt": { regex: /&(gt|#62|#x3E);/g, val: ">" },
26
+ "lt": { regex: /&(lt|#60|#x3C);/g, val: "<" },
27
+ "quot": { regex: /&(quot|#34|#x22);/g, val: "\"" },
28
28
  };
29
- this.ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
29
+ this.ampEntity = { regex: /&(amp|#38|#x26);/g, val: "&" };
30
30
  this.htmlEntities = {
31
31
  "space": { regex: /&(nbsp|#160);/g, val: " " },
32
32
  // "lt" : { regex: /&(lt|#60);/g, val: "<" },
@@ -34,15 +34,15 @@ export default class OrderedObjParser{
34
34
  // "amp" : { regex: /&(amp|#38);/g, val: "&" },
35
35
  // "quot" : { regex: /&(quot|#34);/g, val: "\"" },
36
36
  // "apos" : { regex: /&(apos|#39);/g, val: "'" },
37
- "cent" : { regex: /&(cent|#162);/g, val: "¢" },
38
- "pound" : { regex: /&(pound|#163);/g, val: "£" },
39
- "yen" : { regex: /&(yen|#165);/g, val: "¥" },
40
- "euro" : { regex: /&(euro|#8364);/g, val: "€" },
41
- "copyright" : { regex: /&(copy|#169);/g, val: "©" },
42
- "reg" : { regex: /&(reg|#174);/g, val: "®" },
43
- "inr" : { regex: /&(inr|#8377);/g, val: "₹" },
44
- "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => fromCodePoint(str, 10, "&#") },
45
- "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => fromCodePoint(str, 16, "&#x") },
37
+ "cent": { regex: /&(cent|#162);/g, val: "¢" },
38
+ "pound": { regex: /&(pound|#163);/g, val: "£" },
39
+ "yen": { regex: /&(yen|#165);/g, val: "¥" },
40
+ "euro": { regex: /&(euro|#8364);/g, val: "€" },
41
+ "copyright": { regex: /&(copy|#169);/g, val: "©" },
42
+ "reg": { regex: /&(reg|#174);/g, val: "®" },
43
+ "inr": { regex: /&(inr|#8377);/g, val: "₹" },
44
+ "num_dec": { regex: /&#([0-9]{1,7});/g, val: (_, str) => fromCodePoint(str, 10, "&#") },
45
+ "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_, str) => fromCodePoint(str, 16, "&#x") },
46
46
  };
47
47
  this.addExternalEntities = addExternalEntities;
48
48
  this.parseXml = parseXml;
@@ -55,16 +55,18 @@ export default class OrderedObjParser{
55
55
  this.saveTextToParentTag = saveTextToParentTag;
56
56
  this.addChild = addChild;
57
57
  this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)
58
+ this.entityExpansionCount = 0;
59
+ this.currentExpandedLength = 0;
58
60
 
59
- if(this.options.stopNodes && this.options.stopNodes.length > 0){
61
+ if (this.options.stopNodes && this.options.stopNodes.length > 0) {
60
62
  this.stopNodesExact = new Set();
61
63
  this.stopNodesWildcard = new Set();
62
- for(let i = 0; i < this.options.stopNodes.length; i++){
64
+ for (let i = 0; i < this.options.stopNodes.length; i++) {
63
65
  const stopNodeExp = this.options.stopNodes[i];
64
- if(typeof stopNodeExp !== 'string') continue;
65
- if(stopNodeExp.startsWith("*.")){
66
+ if (typeof stopNodeExp !== 'string') continue;
67
+ if (stopNodeExp.startsWith("*.")) {
66
68
  this.stopNodesWildcard.add(stopNodeExp.substring(2));
67
- }else{
69
+ } else {
68
70
  this.stopNodesExact.add(stopNodeExp);
69
71
  }
70
72
  }
@@ -73,13 +75,14 @@ export default class OrderedObjParser{
73
75
 
74
76
  }
75
77
 
76
- function addExternalEntities(externalEntities){
78
+ function addExternalEntities(externalEntities) {
77
79
  const entKeys = Object.keys(externalEntities);
78
80
  for (let i = 0; i < entKeys.length; i++) {
79
81
  const ent = entKeys[i];
82
+ const escaped = ent.replace(/[.\-+*:]/g, '\\.');
80
83
  this.lastEntities[ent] = {
81
- regex: new RegExp("&"+ent+";","g"),
82
- val : externalEntities[ent]
84
+ regex: new RegExp("&" + escaped + ";", "g"),
85
+ val: externalEntities[ent]
83
86
  }
84
87
  }
85
88
  }
@@ -98,23 +101,23 @@ function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode,
98
101
  if (this.options.trimValues && !dontTrim) {
99
102
  val = val.trim();
100
103
  }
101
- if(val.length > 0){
102
- if(!escapeEntities) val = this.replaceEntitiesValue(val);
103
-
104
+ if (val.length > 0) {
105
+ if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
106
+
104
107
  const newval = this.options.tagValueProcessor(tagName, val, jPath, hasAttributes, isLeafNode);
105
- if(newval === null || newval === undefined){
108
+ if (newval === null || newval === undefined) {
106
109
  //don't parse
107
110
  return val;
108
- }else if(typeof newval !== typeof val || newval !== val){
111
+ } else if (typeof newval !== typeof val || newval !== val) {
109
112
  //overwrite
110
113
  return newval;
111
- }else if(this.options.trimValues){
114
+ } else if (this.options.trimValues) {
112
115
  return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
113
- }else{
116
+ } else {
114
117
  const trimmedVal = val.trim();
115
- if(trimmedVal === val){
118
+ if (trimmedVal === val) {
116
119
  return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
117
- }else{
120
+ } else {
118
121
  return val;
119
122
  }
120
123
  }
@@ -140,7 +143,7 @@ function resolveNameSpace(tagname) {
140
143
  //const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm");
141
144
  const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
142
145
 
143
- function buildAttributesMap(attrStr, jPath) {
146
+ function buildAttributesMap(attrStr, jPath, tagName) {
144
147
  if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') {
145
148
  // attrStr = attrStr.replace(/\r?\n/g, ' ');
146
149
  //attrStr = attrStr || attrStr.trim();
@@ -159,20 +162,20 @@ function buildAttributesMap(attrStr, jPath) {
159
162
  if (this.options.transformAttributeName) {
160
163
  aName = this.options.transformAttributeName(aName);
161
164
  }
162
- if(aName === "__proto__") aName = "#__proto__";
165
+ if (aName === "__proto__") aName = "#__proto__";
163
166
  if (oldVal !== undefined) {
164
167
  if (this.options.trimValues) {
165
168
  oldVal = oldVal.trim();
166
169
  }
167
- oldVal = this.replaceEntitiesValue(oldVal);
170
+ oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);
168
171
  const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath);
169
- if(newVal === null || newVal === undefined){
172
+ if (newVal === null || newVal === undefined) {
170
173
  //don't parse
171
174
  attrs[aName] = oldVal;
172
- }else if(typeof newVal !== typeof oldVal || newVal !== oldVal){
175
+ } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {
173
176
  //overwrite
174
177
  attrs[aName] = newVal;
175
- }else{
178
+ } else {
176
179
  //parse
177
180
  attrs[aName] = parseValue(
178
181
  oldVal,
@@ -197,47 +200,52 @@ function buildAttributesMap(attrStr, jPath) {
197
200
  }
198
201
  }
199
202
 
200
- const parseXml = function(xmlData) {
203
+ const parseXml = function (xmlData) {
201
204
  xmlData = xmlData.replace(/\r\n?/g, "\n"); //TODO: remove this line
202
205
  const xmlObj = new xmlNode('!xml');
203
206
  let currentNode = xmlObj;
204
207
  let textData = "";
205
208
  let jPath = "";
209
+
210
+ // Reset entity expansion counters for this document
211
+ this.entityExpansionCount = 0;
212
+ this.currentExpandedLength = 0;
213
+
206
214
  const docTypeReader = new DocTypeReader(this.options.processEntities);
207
- for(let i=0; i< xmlData.length; i++){//for each char in XML data
215
+ for (let i = 0; i < xmlData.length; i++) {//for each char in XML data
208
216
  const ch = xmlData[i];
209
- if(ch === '<'){
217
+ if (ch === '<') {
210
218
  // const nextIndex = i+1;
211
219
  // const _2ndChar = xmlData[nextIndex];
212
- if( xmlData[i+1] === '/') {//Closing Tag
220
+ if (xmlData[i + 1] === '/') {//Closing Tag
213
221
  const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.")
214
- let tagName = xmlData.substring(i+2,closeIndex).trim();
222
+ let tagName = xmlData.substring(i + 2, closeIndex).trim();
215
223
 
216
- if(this.options.removeNSPrefix){
224
+ if (this.options.removeNSPrefix) {
217
225
  const colonIndex = tagName.indexOf(":");
218
- if(colonIndex !== -1){
219
- tagName = tagName.substr(colonIndex+1);
226
+ if (colonIndex !== -1) {
227
+ tagName = tagName.substr(colonIndex + 1);
220
228
  }
221
229
  }
222
230
 
223
- if(this.options.transformTagName) {
231
+ if (this.options.transformTagName) {
224
232
  tagName = this.options.transformTagName(tagName);
225
233
  }
226
234
 
227
- if(currentNode){
235
+ if (currentNode) {
228
236
  textData = this.saveTextToParentTag(textData, currentNode, jPath);
229
237
  }
230
238
 
231
239
  //check if last tag of nested tag was unpaired tag
232
- const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1);
233
- if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){
240
+ const lastTagName = jPath.substring(jPath.lastIndexOf(".") + 1);
241
+ if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {
234
242
  throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
235
243
  }
236
244
  let propIndex = 0
237
- if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){
238
- propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1)
245
+ if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {
246
+ propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.') - 1)
239
247
  this.tagsNodeStack.pop();
240
- }else{
248
+ } else {
241
249
  propIndex = jPath.lastIndexOf(".");
242
250
  }
243
251
  jPath = jPath.substring(0, propIndex);
@@ -245,61 +253,61 @@ const parseXml = function(xmlData) {
245
253
  currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
246
254
  textData = "";
247
255
  i = closeIndex;
248
- } else if( xmlData[i+1] === '?') {
256
+ } else if (xmlData[i + 1] === '?') {
249
257
 
250
- let tagData = readTagExp(xmlData,i, false, "?>");
251
- if(!tagData) throw new Error("Pi Tag is not closed.");
258
+ let tagData = readTagExp(xmlData, i, false, "?>");
259
+ if (!tagData) throw new Error("Pi Tag is not closed.");
252
260
 
253
261
  textData = this.saveTextToParentTag(textData, currentNode, jPath);
254
- if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags){
262
+ if ((this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags) {
255
263
  //do nothing
256
- }else{
257
-
264
+ } else {
265
+
258
266
  const childNode = new xmlNode(tagData.tagName);
259
267
  childNode.add(this.options.textNodeName, "");
260
-
261
- if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){
262
- childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath);
268
+
269
+ if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {
270
+ childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
263
271
  }
264
272
  this.addChild(currentNode, childNode, jPath, i);
265
273
  }
266
274
 
267
275
 
268
276
  i = tagData.closeIndex + 1;
269
- } else if(xmlData.substr(i + 1, 3) === '!--') {
270
- const endIndex = findClosingIndex(xmlData, "-->", i+4, "Comment is not closed.")
271
- if(this.options.commentPropName){
277
+ } else if (xmlData.substr(i + 1, 3) === '!--') {
278
+ const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed.")
279
+ if (this.options.commentPropName) {
272
280
  const comment = xmlData.substring(i + 4, endIndex - 2);
273
281
 
274
282
  textData = this.saveTextToParentTag(textData, currentNode, jPath);
275
283
 
276
- currentNode.add(this.options.commentPropName, [ { [this.options.textNodeName] : comment } ]);
284
+ currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);
277
285
  }
278
286
  i = endIndex;
279
- } else if( xmlData.substr(i + 1, 2) === '!D') {
287
+ } else if (xmlData.substr(i + 1, 2) === '!D') {
280
288
  const result = docTypeReader.readDocType(xmlData, i);
281
289
  this.docTypeEntities = result.entities;
282
290
  i = result.i;
283
- }else if(xmlData.substr(i + 1, 2) === '![') {
291
+ } else if (xmlData.substr(i + 1, 2) === '![') {
284
292
  const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
285
- const tagExp = xmlData.substring(i + 9,closeIndex);
293
+ const tagExp = xmlData.substring(i + 9, closeIndex);
286
294
 
287
295
  textData = this.saveTextToParentTag(textData, currentNode, jPath);
288
296
 
289
297
  let val = this.parseTextData(tagExp, currentNode.tagname, jPath, true, false, true, true);
290
- if(val == undefined) val = "";
298
+ if (val == undefined) val = "";
291
299
 
292
300
  //cdata should be set even if it is 0 length string
293
- if(this.options.cdataPropName){
294
- currentNode.add(this.options.cdataPropName, [ { [this.options.textNodeName] : tagExp } ]);
295
- }else{
301
+ if (this.options.cdataPropName) {
302
+ currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]);
303
+ } else {
296
304
  currentNode.add(this.options.textNodeName, val);
297
305
  }
298
-
306
+
299
307
  i = closeIndex + 2;
300
- }else {//Opening tag
301
- let result = readTagExp(xmlData,i, this.options.removeNSPrefix);
302
- let tagName= result.tagName;
308
+ } else {//Opening tag
309
+ let result = readTagExp(xmlData, i, this.options.removeNSPrefix);
310
+ let tagName = result.tagName;
303
311
  const rawTagName = result.rawTagName;
304
312
  let tagExp = result.tagExp;
305
313
  let attrExpPresent = result.attrExpPresent;
@@ -308,15 +316,15 @@ const parseXml = function(xmlData) {
308
316
  if (this.options.transformTagName) {
309
317
  //console.log(tagExp, tagName)
310
318
  const newTagName = this.options.transformTagName(tagName);
311
- if(tagExp === tagName) {
319
+ if (tagExp === tagName) {
312
320
  tagExp = newTagName
313
321
  }
314
322
  tagName = newTagName;
315
323
  }
316
-
324
+
317
325
  //save text as child node
318
326
  if (currentNode && textData) {
319
- if(currentNode.tagname !== '!xml'){
327
+ if (currentNode.tagname !== '!xml') {
320
328
  //when nested tag is found
321
329
  textData = this.saveTextToParentTag(textData, currentNode, jPath, false);
322
330
  }
@@ -324,88 +332,87 @@ const parseXml = function(xmlData) {
324
332
 
325
333
  //check if last tag was unpaired tag
326
334
  const lastTag = currentNode;
327
- if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){
335
+ if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {
328
336
  currentNode = this.tagsNodeStack.pop();
329
337
  jPath = jPath.substring(0, jPath.lastIndexOf("."));
330
338
  }
331
- if(tagName !== xmlObj.tagname){
339
+ if (tagName !== xmlObj.tagname) {
332
340
  jPath += jPath ? "." + tagName : tagName;
333
341
  }
334
342
  const startIndex = i;
335
343
  if (this.isItStopNode(this.stopNodesExact, this.stopNodesWildcard, jPath, tagName)) {
336
344
  let tagContent = "";
337
345
  //self-closing tag
338
- if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
339
- if(tagName[tagName.length - 1] === "/"){ //remove trailing '/'
346
+ if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
347
+ if (tagName[tagName.length - 1] === "/") { //remove trailing '/'
340
348
  tagName = tagName.substr(0, tagName.length - 1);
341
349
  jPath = jPath.substr(0, jPath.length - 1);
342
350
  tagExp = tagName;
343
- }else{
351
+ } else {
344
352
  tagExp = tagExp.substr(0, tagExp.length - 1);
345
353
  }
346
354
  i = result.closeIndex;
347
355
  }
348
356
  //unpaired tag
349
- else if(this.options.unpairedTags.indexOf(tagName) !== -1){
350
-
357
+ else if (this.options.unpairedTags.indexOf(tagName) !== -1) {
358
+
351
359
  i = result.closeIndex;
352
360
  }
353
361
  //normal tag
354
- else{
362
+ else {
355
363
  //read until closing tag is found
356
364
  const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
357
- if(!result) throw new Error(`Unexpected end of ${rawTagName}`);
365
+ if (!result) throw new Error(`Unexpected end of ${rawTagName}`);
358
366
  i = result.i;
359
367
  tagContent = result.tagContent;
360
368
  }
361
369
 
362
370
  const childNode = new xmlNode(tagName);
363
371
 
364
- if(tagName !== tagExp && attrExpPresent){
365
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath
366
- );
372
+ if (tagName !== tagExp && attrExpPresent) {
373
+ childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
367
374
  }
368
- if(tagContent) {
375
+ if (tagContent) {
369
376
  tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
370
377
  }
371
-
378
+
372
379
  jPath = jPath.substr(0, jPath.lastIndexOf("."));
373
380
  childNode.add(this.options.textNodeName, tagContent);
374
-
381
+
375
382
  this.addChild(currentNode, childNode, jPath, startIndex);
376
- }else{
377
- //selfClosing tag
378
- if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
379
- if(tagName[tagName.length - 1] === "/"){ //remove trailing '/'
383
+ } else {
384
+ //selfClosing tag
385
+ if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
386
+ if (tagName[tagName.length - 1] === "/") { //remove trailing '/'
380
387
  tagName = tagName.substr(0, tagName.length - 1);
381
388
  jPath = jPath.substr(0, jPath.length - 1);
382
389
  tagExp = tagName;
383
- }else{
390
+ } else {
384
391
  tagExp = tagExp.substr(0, tagExp.length - 1);
385
392
  }
386
-
387
- if(this.options.transformTagName) {
393
+
394
+ if (this.options.transformTagName) {
388
395
  const newTagName = this.options.transformTagName(tagName);
389
- if(tagExp === tagName) {
396
+ if (tagExp === tagName) {
390
397
  tagExp = newTagName
391
398
  }
392
399
  tagName = newTagName;
393
400
  }
394
401
 
395
402
  const childNode = new xmlNode(tagName);
396
- if(tagName !== tagExp && attrExpPresent){
397
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
403
+ if (tagName !== tagExp && attrExpPresent) {
404
+ childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
398
405
  }
399
406
  this.addChild(currentNode, childNode, jPath, startIndex);
400
407
  jPath = jPath.substr(0, jPath.lastIndexOf("."));
401
408
  }
402
- //opening tag
403
- else{
404
- const childNode = new xmlNode( tagName);
409
+ //opening tag
410
+ else {
411
+ const childNode = new xmlNode(tagName);
405
412
  this.tagsNodeStack.push(currentNode);
406
-
407
- if(tagName !== tagExp && attrExpPresent){
408
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
413
+
414
+ if (tagName !== tagExp && attrExpPresent) {
415
+ childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
409
416
  }
410
417
  this.addChild(currentNode, childNode, jPath, startIndex);
411
418
  currentNode = childNode;
@@ -414,52 +421,113 @@ const parseXml = function(xmlData) {
414
421
  i = closeIndex;
415
422
  }
416
423
  }
417
- }else{
424
+ } else {
418
425
  textData += xmlData[i];
419
426
  }
420
427
  }
421
428
  return xmlObj.child;
422
429
  }
423
430
 
424
- function addChild(currentNode, childNode, jPath, startIndex){
431
+ function addChild(currentNode, childNode, jPath, startIndex) {
425
432
  // unset startIndex if not requested
426
433
  if (!this.options.captureMetaData) startIndex = undefined;
427
434
  const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"])
428
- if(result === false){
435
+ if (result === false) {
429
436
  //do nothing
430
- } else if(typeof result === "string"){
437
+ } else if (typeof result === "string") {
431
438
  childNode.tagname = result
432
439
  currentNode.addChild(childNode, startIndex);
433
- }else{
440
+ } else {
434
441
  currentNode.addChild(childNode, startIndex);
435
442
  }
436
443
  }
437
444
 
438
- const replaceEntitiesValue = function(val){
445
+ const replaceEntitiesValue = function (val, tagName, jPath) {
446
+ // Performance optimization: Early return if no entities to replace
447
+ if (val.indexOf('&') === -1) {
448
+ return val;
449
+ }
450
+
451
+ const entityConfig = this.options.processEntities;
439
452
 
440
- if(this.options.processEntities){
441
- for(let entityName in this.docTypeEntities){
442
- const entity = this.docTypeEntities[entityName];
443
- val = val.replace( entity.regx, entity.val);
453
+ if (!entityConfig.enabled) {
454
+ return val;
455
+ }
456
+
457
+ // Check tag-specific filtering
458
+ if (entityConfig.allowedTags) {
459
+ if (!entityConfig.allowedTags.includes(tagName)) {
460
+ return val; // Skip entity replacement for current tag as not set
444
461
  }
445
- for(let entityName in this.lastEntities){
446
- const entity = this.lastEntities[entityName];
447
- val = val.replace( entity.regex, entity.val);
462
+ }
463
+
464
+ if (entityConfig.tagFilter) {
465
+ if (!entityConfig.tagFilter(tagName, jPath)) {
466
+ return val; // Skip based on custom filter
448
467
  }
449
- if(this.options.htmlEntities){
450
- for(let entityName in this.htmlEntities){
451
- const entity = this.htmlEntities[entityName];
452
- val = val.replace( entity.regex, entity.val);
468
+ }
469
+
470
+ // Replace DOCTYPE entities
471
+ for (let entityName in this.docTypeEntities) {
472
+ const entity = this.docTypeEntities[entityName];
473
+ const matches = val.match(entity.regx);
474
+
475
+ if (matches) {
476
+ // Track expansions
477
+ this.entityExpansionCount += matches.length;
478
+
479
+ // Check expansion limit
480
+ if (entityConfig.maxTotalExpansions &&
481
+ this.entityExpansionCount > entityConfig.maxTotalExpansions) {
482
+ throw new Error(
483
+ `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
484
+ );
485
+ }
486
+
487
+ // Store length before replacement
488
+ const lengthBefore = val.length;
489
+ val = val.replace(entity.regx, entity.val);
490
+
491
+ // Check expanded length immediately after replacement
492
+ if (entityConfig.maxExpandedLength) {
493
+ this.currentExpandedLength += (val.length - lengthBefore);
494
+
495
+ if (this.currentExpandedLength > entityConfig.maxExpandedLength) {
496
+ throw new Error(
497
+ `Total expanded content size exceeded: ${this.currentExpandedLength} > ${entityConfig.maxExpandedLength}`
498
+ );
499
+ }
453
500
  }
454
501
  }
455
- val = val.replace( this.ampEntity.regex, this.ampEntity.val);
456
502
  }
503
+ if (val.indexOf('&') === -1) return val; // Early exit
504
+
505
+ // Replace standard entities
506
+ for (let entityName in this.lastEntities) {
507
+ const entity = this.lastEntities[entityName];
508
+ val = val.replace(entity.regex, entity.val);
509
+ }
510
+ if (val.indexOf('&') === -1) return val; // Early exit
511
+
512
+ // Replace HTML entities if enabled
513
+ if (this.options.htmlEntities) {
514
+ for (let entityName in this.htmlEntities) {
515
+ const entity = this.htmlEntities[entityName];
516
+ val = val.replace(entity.regex, entity.val);
517
+ }
518
+ }
519
+
520
+ // Replace ampersand entity last
521
+ val = val.replace(this.ampEntity.regex, this.ampEntity.val);
522
+
457
523
  return val;
458
524
  }
525
+
526
+
459
527
  function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) {
460
528
  if (textData) { //store previously collected data as textNode
461
- if(isLeafNode === undefined) isLeafNode = currentNode.child.length === 0
462
-
529
+ if (isLeafNode === undefined) isLeafNode = currentNode.child.length === 0
530
+
463
531
  textData = this.parseTextData(textData,
464
532
  currentNode.tagname,
465
533
  jPath,
@@ -481,9 +549,9 @@ function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) {
481
549
  * @param {string} jPath
482
550
  * @param {string} currentTagName
483
551
  */
484
- function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName){
485
- if(stopNodesWildcard && stopNodesWildcard.has(currentTagName)) return true;
486
- if(stopNodesExact && stopNodesExact.has(jPath)) return true;
552
+ function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName) {
553
+ if (stopNodesWildcard && stopNodesWildcard.has(currentTagName)) return true;
554
+ if (stopNodesExact && stopNodesExact.has(jPath)) return true;
487
555
  return false;
488
556
  }
489
557
 
@@ -493,24 +561,24 @@ function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName){
493
561
  * @param {number} i starting index
494
562
  * @returns
495
563
  */
496
- function tagExpWithClosingIndex(xmlData, i, closingChar = ">"){
564
+ function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
497
565
  let attrBoundary;
498
566
  let tagExp = "";
499
567
  for (let index = i; index < xmlData.length; index++) {
500
568
  let ch = xmlData[index];
501
569
  if (attrBoundary) {
502
- if (ch === attrBoundary) attrBoundary = "";//reset
570
+ if (ch === attrBoundary) attrBoundary = "";//reset
503
571
  } else if (ch === '"' || ch === "'") {
504
- attrBoundary = ch;
572
+ attrBoundary = ch;
505
573
  } else if (ch === closingChar[0]) {
506
- if(closingChar[1]){
507
- if(xmlData[index + 1] === closingChar[1]){
574
+ if (closingChar[1]) {
575
+ if (xmlData[index + 1] === closingChar[1]) {
508
576
  return {
509
577
  data: tagExp,
510
578
  index: index
511
579
  }
512
580
  }
513
- }else{
581
+ } else {
514
582
  return {
515
583
  data: tagExp,
516
584
  index: index
@@ -523,33 +591,33 @@ function tagExpWithClosingIndex(xmlData, i, closingChar = ">"){
523
591
  }
524
592
  }
525
593
 
526
- function findClosingIndex(xmlData, str, i, errMsg){
594
+ function findClosingIndex(xmlData, str, i, errMsg) {
527
595
  const closingIndex = xmlData.indexOf(str, i);
528
- if(closingIndex === -1){
596
+ if (closingIndex === -1) {
529
597
  throw new Error(errMsg)
530
- }else{
598
+ } else {
531
599
  return closingIndex + str.length - 1;
532
600
  }
533
601
  }
534
602
 
535
- function readTagExp(xmlData,i, removeNSPrefix, closingChar = ">"){
536
- const result = tagExpWithClosingIndex(xmlData, i+1, closingChar);
537
- if(!result) return;
603
+ function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") {
604
+ const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);
605
+ if (!result) return;
538
606
  let tagExp = result.data;
539
607
  const closeIndex = result.index;
540
608
  const separatorIndex = tagExp.search(/\s/);
541
609
  let tagName = tagExp;
542
610
  let attrExpPresent = true;
543
- if(separatorIndex !== -1){//separate tag name and attributes expression
611
+ if (separatorIndex !== -1) {//separate tag name and attributes expression
544
612
  tagName = tagExp.substring(0, separatorIndex);
545
613
  tagExp = tagExp.substring(separatorIndex + 1).trimStart();
546
614
  }
547
615
 
548
616
  const rawTagName = tagName;
549
- if(removeNSPrefix){
617
+ if (removeNSPrefix) {
550
618
  const colonIndex = tagName.indexOf(":");
551
- if(colonIndex !== -1){
552
- tagName = tagName.substr(colonIndex+1);
619
+ if (colonIndex !== -1) {
620
+ tagName = tagName.substr(colonIndex + 1);
553
621
  attrExpPresent = tagName !== result.data.substr(colonIndex + 1);
554
622
  }
555
623
  }
@@ -568,47 +636,47 @@ function readTagExp(xmlData,i, removeNSPrefix, closingChar = ">"){
568
636
  * @param {string} tagName
569
637
  * @param {number} i
570
638
  */
571
- function readStopNodeData(xmlData, tagName, i){
639
+ function readStopNodeData(xmlData, tagName, i) {
572
640
  const startIndex = i;
573
641
  // Starting at 1 since we already have an open tag
574
642
  let openTagCount = 1;
575
643
 
576
644
  for (; i < xmlData.length; i++) {
577
- if( xmlData[i] === "<"){
578
- if (xmlData[i+1] === "/") {//close tag
579
- const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`);
580
- let closeTagName = xmlData.substring(i+2,closeIndex).trim();
581
- if(closeTagName === tagName){
582
- openTagCount--;
583
- if (openTagCount === 0) {
584
- return {
585
- tagContent: xmlData.substring(startIndex, i),
586
- i : closeIndex
587
- }
645
+ if (xmlData[i] === "<") {
646
+ if (xmlData[i + 1] === "/") {//close tag
647
+ const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`);
648
+ let closeTagName = xmlData.substring(i + 2, closeIndex).trim();
649
+ if (closeTagName === tagName) {
650
+ openTagCount--;
651
+ if (openTagCount === 0) {
652
+ return {
653
+ tagContent: xmlData.substring(startIndex, i),
654
+ i: closeIndex
588
655
  }
589
656
  }
590
- i=closeIndex;
591
- } else if(xmlData[i+1] === '?') {
592
- const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.")
593
- i=closeIndex;
594
- } else if(xmlData.substr(i + 1, 3) === '!--') {
595
- const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.")
596
- i=closeIndex;
597
- } else if(xmlData.substr(i + 1, 2) === '![') {
598
- const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
599
- i=closeIndex;
600
- } else {
601
- const tagData = readTagExp(xmlData, i, '>')
657
+ }
658
+ i = closeIndex;
659
+ } else if (xmlData[i + 1] === '?') {
660
+ const closeIndex = findClosingIndex(xmlData, "?>", i + 1, "StopNode is not closed.")
661
+ i = closeIndex;
662
+ } else if (xmlData.substr(i + 1, 3) === '!--') {
663
+ const closeIndex = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed.")
664
+ i = closeIndex;
665
+ } else if (xmlData.substr(i + 1, 2) === '![') {
666
+ const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
667
+ i = closeIndex;
668
+ } else {
669
+ const tagData = readTagExp(xmlData, i, '>')
602
670
 
603
- if (tagData) {
604
- const openTagName = tagData && tagData.tagName;
605
- if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") {
606
- openTagCount++;
607
- }
608
- i=tagData.closeIndex;
671
+ if (tagData) {
672
+ const openTagName = tagData && tagData.tagName;
673
+ if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== "/") {
674
+ openTagCount++;
609
675
  }
676
+ i = tagData.closeIndex;
610
677
  }
611
678
  }
679
+ }
612
680
  }//end for loop
613
681
  }
614
682
 
@@ -616,8 +684,8 @@ function parseValue(val, shouldParse, options) {
616
684
  if (shouldParse && typeof val === 'string') {
617
685
  //console.log(options)
618
686
  const newval = val.trim();
619
- if(newval === 'true' ) return true;
620
- else if(newval === 'false' ) return false;
687
+ if (newval === 'true') return true;
688
+ else if (newval === 'false') return false;
621
689
  else return toNumber(val, options);
622
690
  } else {
623
691
  if (isExist(val)) {
@@ -628,12 +696,12 @@ function parseValue(val, shouldParse, options) {
628
696
  }
629
697
  }
630
698
 
631
- function fromCodePoint(str, base, prefix){
699
+ function fromCodePoint(str, base, prefix) {
632
700
  const codePoint = Number.parseInt(str, base);
633
701
 
634
702
  if (codePoint >= 0 && codePoint <= 0x10FFFF) {
635
- return String.fromCodePoint(codePoint);
703
+ return String.fromCodePoint(codePoint);
636
704
  } else {
637
- return prefix +str + ";";
705
+ return prefix + str + ";";
638
706
  }
639
707
  }