Skip to content

Commit fe9a852

Browse files
committed
update strnum and release detail
1 parent 943ef0e commit fe9a852

File tree

10 files changed

+326
-10
lines changed

10 files changed

+326
-10
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<small>Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.</small>
22

3+
4+
**5.3.5 / 2026-02-08**
5+
- fix: Escape regex char in entity name
6+
- update strnum to 2.1.2
7+
- add missing exports in CJS typings
8+
9+
310
**5.3.4 / 2026-01-30**
411
- fix: handle HTML numeric and hex entities when out of range
512

lib/fxp.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

lib/fxp.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/fxp.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/fxparser.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/fxparser.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fast-xml-parser",
3-
"version": "5.3.4",
3+
"version": "5.3.5",
44
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
55
"main": "./lib/fxp.cjs",
66
"type": "module",
@@ -87,6 +87,6 @@
8787
}
8888
],
8989
"dependencies": {
90-
"strnum": "^2.1.0"
90+
"strnum": "^2.1.2"
9191
}
9292
}

spec/entities_spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,31 @@ describe("XMLParser Entities", function() {
154154
expect(result).toEqual(expected);
155155
});
156156

157+
it("should escape regex char from entity name", function() {
158+
const xmlData = `<?xml version="1.0"?>
159+
<!DOCTYPE foo [
160+
<!ENTITY l. "<img src=x onerror=alert(1)>">
161+
]>
162+
<root>
163+
<text>Hello &lt;b&gt;World&lt;/b&gt;</text>
164+
</root>`;
165+
166+
const expected = {
167+
"?xml": "",
168+
"root": {
169+
"text": "Hello <b>World</b>"
170+
}
171+
};
172+
173+
const options = {
174+
175+
};
176+
const parser = new XMLParser(options);
177+
let result = parser.parse(xmlData);
178+
//console.log(JSON.stringify(result,null,4));
179+
expect(result).toEqual(expected);
180+
});
181+
157182
it("should parse attributes having '>' in value", function() {
158183
const xmlData = `
159184
<?xml version="1.0" encoding="UTF-8"?>

spec/v6/xmlParser_spec.js

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
2+
import XMLParser from "../../src/v6/XMLParser.js";
3+
import JsObjOutputBuilder from "../../src/v6/OutputBuilders/JsObjBuilder.js";
4+
import numberParser from "../../src/v6/valueParsers/number.js";
5+
6+
describe("XMLParser v6", function () {
7+
8+
it("should parse all values as string, int, boolean, float, hexadecimal", function () {
9+
const xmlData = `<rootNode>
10+
<tag>value</tag>
11+
<boolean>true</boolean>
12+
<intTag>045</intTag>
13+
<floatTag>65.34</floatTag>
14+
<hexadecimal>0x15</hexadecimal>
15+
</rootNode>`;
16+
const expected = {
17+
"rootNode": {
18+
"tag": "value",
19+
"boolean": true,
20+
"intTag": 45,
21+
"floatTag": 65.34,
22+
"hexadecimal": 21
23+
}
24+
};
25+
26+
const parser = new XMLParser();
27+
let result = parser.parse(xmlData);
28+
expect(result).toEqual(expected);
29+
});
30+
31+
it("should parse only true numbers", function () {
32+
const xmlData = `<rootNode>
33+
<tag>value</tag>
34+
<boolean>true</boolean>
35+
<intTag>045</intTag>
36+
<floatTag>65.340</floatTag>
37+
<long>420926189200190257681175017717</long>
38+
</rootNode>`;
39+
const expected = {
40+
"rootNode": {
41+
"tag": "value",
42+
"boolean": true,
43+
"intTag": "045",
44+
"floatTag": 65.34,
45+
"long": 4.209261892001902e+29
46+
}
47+
};
48+
49+
const options = {
50+
tags: {
51+
valueParsers: [
52+
"boolean",
53+
new numberParser({
54+
hex: true,
55+
leadingZeros: false,
56+
eNotation: true
57+
})
58+
]
59+
}
60+
};
61+
const parser = new XMLParser(options);
62+
let result = parser.parse(xmlData);
63+
expect(result).toEqual(expected);
64+
});
65+
66+
it("should parse number ending in .0 for parseTrueNumberOnly:false", function () {
67+
const xmlData = `<rootNode>
68+
<floatTag0>0.0</floatTag0>
69+
<floatTag1>1.0</floatTag1>
70+
<floatTag2>2.0000</floatTag2>
71+
<floatTag3 float="3.00"/>
72+
</rootNode>`;
73+
const expected = {
74+
"rootNode": {
75+
"floatTag0": 0,
76+
"floatTag1": 1,
77+
"floatTag2": 2,
78+
"floatTag3": {
79+
"@_float": 3
80+
}
81+
}
82+
};
83+
84+
const options = {
85+
attributes: {
86+
ignore: false,
87+
valueParsers: ["number"] // parse attributes as numbers
88+
},
89+
tags: {
90+
valueParsers: [
91+
new numberParser({
92+
leadingZeros: false
93+
})
94+
]
95+
}
96+
};
97+
const parser = new XMLParser(options);
98+
let result = parser.parse(xmlData);
99+
expect(result).toEqual(expected);
100+
});
101+
102+
it("should not parse values to primitive type", function () {
103+
const xmlData = `<rootNode><tag>value</tag><boolean>true</boolean><intTag>045</intTag><floatTag>65.34</floatTag></rootNode>`;
104+
const expected = {
105+
"rootNode": {
106+
"tag": "value",
107+
"boolean": "true",
108+
"intTag": "045",
109+
"floatTag": "65.34"
110+
}
111+
};
112+
113+
const options = {
114+
tags: {
115+
valueParsers: [] // No value parsers
116+
}
117+
};
118+
const parser = new XMLParser(options);
119+
let result = parser.parse(xmlData);
120+
expect(result).toEqual(expected);
121+
});
122+
123+
it("should parse number values of attributes as number", function () {
124+
const xmlData = `<rootNode><tag int='045' intNegative='-045' float='65.34' floatNegative='-65.34'>value</tag></rootNode>`;
125+
const expected = {
126+
"rootNode": {
127+
"tag": {
128+
"#text": "value",
129+
"@_int": 45,
130+
"@_intNegative": -45,
131+
"@_float": 65.34,
132+
"@_floatNegative": -65.34
133+
}
134+
}
135+
};
136+
137+
const options = {
138+
attributes: {
139+
ignore: false,
140+
valueParsers: ["number"]
141+
}
142+
};
143+
const parser = new XMLParser(options);
144+
let result = parser.parse(xmlData);
145+
expect(result).toEqual(expected);
146+
});
147+
148+
it("should skip tag arguments", function () {
149+
const xmlData = `<rootNode><tag ns:arg='value'>value</tag><intTag ns:arg='value' ns:arg2='value2' >45</intTag><floatTag>65.34</floatTag></rootNode>`;
150+
const expected = {
151+
"rootNode": {
152+
"tag": "value",
153+
"intTag": 45,
154+
"floatTag": 65.34
155+
}
156+
};
157+
158+
const options = {
159+
attributes: {
160+
ignore: true // skip attributes
161+
}
162+
};
163+
const parser = new XMLParser(options);
164+
let result = parser.parse(xmlData);
165+
expect(result).toEqual(expected);
166+
});
167+
168+
it("should ignore namespace and text node attributes", function () {
169+
const xmlData = `\
170+
<root:node>
171+
<tag ns:arg='value'>value</tag>
172+
<intTag ns:arg='value' ns:arg2='value2' >45</intTag>
173+
<floatTag>65.34</floatTag>
174+
<nsTag xmlns:tns-ns='urn:none' tns-ns:attr='tns'></nsTag>
175+
<nsTagNoAttr xmlns:tns-ns='urn:none'></nsTagNoAttr>
176+
</root:node>`;
177+
178+
const expected = {
179+
"node": {
180+
"tag": {
181+
"@_arg": "value",
182+
"#text": "value"
183+
},
184+
"intTag": {
185+
"@_arg": "value",
186+
"@_arg2": "value2",
187+
"#text": 45
188+
},
189+
"floatTag": 65.34,
190+
"nsTag": {
191+
"@_attr": "tns"
192+
//"#text": ""
193+
},
194+
"nsTagNoAttr": ""
195+
}
196+
};
197+
198+
const options = {
199+
removeNSPrefix: true,
200+
attributes: {
201+
ignore: false
202+
}
203+
};
204+
const parser = new XMLParser(options);
205+
let result = parser.parse(xmlData);
206+
207+
expect(result).toEqual(expected);
208+
});
209+
210+
it("should parse empty text Node", function () {
211+
const xmlData = `<rootNode><tag></tag></rootNode>`;
212+
const expected = {
213+
"rootNode": {
214+
"tag": ""
215+
}
216+
};
217+
218+
const parser = new XMLParser();
219+
let result = parser.parse(xmlData);
220+
expect(result).toEqual(expected);
221+
});
222+
223+
it("should parse self closing tags", function () {
224+
const xmlData = "<rootNode><tag ns:arg='value'/></rootNode>";
225+
const expected = {
226+
"rootNode": {
227+
"tag": {
228+
"@_ns:arg": "value"
229+
}
230+
}
231+
};
232+
233+
const options = {
234+
attributes: {
235+
ignore: false
236+
}
237+
};
238+
const parser = new XMLParser(options);
239+
let result = parser.parse(xmlData);
240+
241+
expect(result).toEqual(expected);
242+
});
243+
244+
it("should parse repeated nodes in array", function () {
245+
const xmlData = `\
246+
<rootNode>
247+
<tag>value</tag>
248+
<tag>45</tag>
249+
<tag>65.34</tag>
250+
</rootNode>`;
251+
const expected = {
252+
"rootNode": {
253+
"tag": ["value", 45, 65.34]
254+
}
255+
};
256+
257+
const parser = new XMLParser();
258+
let result = parser.parse(xmlData);
259+
expect(result).toEqual(expected);
260+
});
261+
262+
it("should parse nested nodes in nested properties", function () {
263+
const xmlData = `\
264+
<rootNode>
265+
<parenttag>
266+
<tag>value</tag>
267+
<tag>45</tag>
268+
<tag>65.34</tag>
269+
</parenttag>
270+
</rootNode>`;
271+
const expected = {
272+
"rootNode": {
273+
"parenttag": {
274+
"tag": ["value", 45, 65.34]
275+
}
276+
}
277+
};
278+
279+
const parser = new XMLParser();
280+
let result = parser.parse(xmlData);
281+
expect(result).toEqual(expected);
282+
});
283+
284+
});

0 commit comments

Comments
 (0)