Socket
Socket
Sign inDemoInstall

fast-xml-parser

Package Overview
Dependencies
Maintainers
1
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-xml-parser - npm Package Compare versions

Comparing version 2.4.4 to 2.5.0

README.html

5

bin/parser.js

@@ -132,4 +132,5 @@ var getAllMatches = require("./util").getAllMatches;

//var attrsRegx = new RegExp("(\\S+)=.([^'\"]+)","g");
var attrsRegx = new RegExp("(\\S+)=(.)([^=>]*)\\2","g");
//var attrsRegx = new RegExp("(\\S+)=\\s*[\"']?((?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?","g");
//var attrsRegx = new RegExp("(\\S+)=\\s*(['\"])((?:.(?!\\2))*.)","g");
var attrsRegx = new RegExp("(\\S+)\\s*=\\s*(['\"])(.*?)\\2","g");
function buildAttributesArr(attrStr,ignore,prefix,ignoreNS){

@@ -136,0 +137,0 @@ attrStr = attrStr || attrStr.trim();

197

bin/validator.js
var getAllMatches = require("./util").getAllMatches;
var InvalidXmlException = require("./InvalidXmlException");
var validate = function (xmlData){
xmlData = xmlData.replace(/[ \t]/g, " ");
var eStack = [], currentTag = "", lineNum = 1;
for (var i = 0; i < xmlData.length;i++) {
if(xmlData[i] === "\n"){
lineNum++;
}else if(xmlData[i] === '<'){
if(xmlData[i+1] === " "){//comment tag
throw new InvalidXmlException("Invalid tag at "+ lineNum + ":" + i);
}else if(xmlData[i+1] === "!"){//comment tag or CDATA tag
var tg = "";
if(xmlData[i+2] === "-")
tg = getCommentTag(xmlData,i,lineNum);
else if(xmlData[i+2] === "["){
tg = getCDATA(xmlData,i,lineNum);
var tagsPattern = new RegExp("<\\/?([\\w:\\-]+)\\s*\/?>","g");
exports.validate = function validate2(xmlData){
xmlData = xmlData.replace(/\n/g,"");//make it single line
xmlData = xmlData.replace(/(<!\[CDATA\[.*?\]\]>)/g,"");//Remove all CDATA
xmlData = xmlData.replace(/(<!--.*?(?:-->))/g,"");//Remove all comments
if(validateAttributes(xmlData) !== true) return false;
xmlData = xmlData.replace(/(\s+(?:[\w:\-]+)\s*=\s*(['\"]).*?\2)/g,"");//Remove all attributes
xmlData = xmlData.replace(/(^\s*<\?xml\s*\?>)/g,"");//Remove XML starting tag
if(xmlData.indexOf("<![CDATA[") > 0 || xmlData.indexOf("<!--") > 0 ) return false;
var tags = getAllMatches(xmlData,tagsPattern);
if(tags.length === 0) return false; //non xml string
var result = checkForMatchingTag(tags,0);
if(result !== true) return false; else return true;
}
var attrStringPattern = new RegExp("<[\\w:\-]+(.*?)\/?>","g");
var attrPattern = new RegExp("\\s+([\\w:\-]+)\\s*=\\s*(['\"])(.*?)\\2","g");
function validateAttributes(xmlData){
var attrStrings = getAllMatches(xmlData,attrStringPattern);
for (i=0;i<attrStrings.length;i++){
if(attrStrings[i][1].trim().length > 0 && attrStrings[i][1].trim().length < 4){ //invalid attributes
return false;
}else if(attrStrings[i][1].trim().length !== 0){
var attrsList = getAllMatches(attrStrings[i][1],attrPattern);
var attrNames=[];
for (j=0;j<attrsList.length;j++){
if(attrNames[attrsList[j][1]]){//duplicate attributes
return false;
}else{
throw new InvalidXmlException("Invalid tag at "+ lineNum + ":" + i);
attrNames[attrsList[j][1]]=1;
//validate attribute value
//if(!validateAttrValue(attrsList[3])) return false;
}
i+=tg.length-1;
}else if(xmlData[i+1] === "/"){//closing tag
i+=2;
currentTag = getEndTagName(xmlData,i,lineNum);
if(eStack[eStack.length-1] !== currentTag){
throw new InvalidXmlException("closing tag is not matching at "+ lineNum + ":" + i);
}else{
eStack.pop();
}
i+=currentTag.length;
}else{
currentTag = getTagName(xmlData,++i);
i+=currentTag.length;
var attrStr = getAttrStr(xmlData,i,lineNum);
if(attrStr && (attrStr[attrStr.length-1] === "/"|| attrStr[attrStr.length-1] === "?")){
i+=attrStr.length;
}else{
eStack.push(currentTag);
}
var text = getvalue(xmlData,++i);
i+=text.length-1;
}
}
}
if(eStack.length === 0) return true;
else
throw new InvalidXmlException("closing tag is missing for "+ eStack);
};
/**
* Validate and return comment tag
*/
function getCommentTag(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === "-" && xmlData[i+1] === "-" && xmlData[i+2] === ">") break;
}
if(xmlData.substr(startIndex,4) === "<!--" && xmlData.substr(i,3) === "-->")
return xmlData.substring(startIndex,i);
else
throw new InvalidXmlException("Invalid comment tag at " + lineNum +":"+ startIndex);
return true;
}
/**
* Validate and return comment tag
*/
function getCDATA(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === "<" && xmlData[i+1] === "/") {
i--;
break;
}
}
if(xmlData.substr(startIndex,9) === "<![CDATA[" && xmlData.substr(i-2,3) === "]]>")
return xmlData.substring(startIndex,i);
else
throw new InvalidXmlException("Invalid CDATA tag at " + lineNum +":"+ startIndex);
}
function checkForMatchingTag(tags,i){
if(tags.length === i) {
return true;
}else if(tags[i][0].indexOf("</") === 0) {//closing tag
return i;
}else if(tags[i][0].indexOf("/>") === tags[i][0].length-2){//Self closing tag
return checkForMatchingTag(tags,i+1);
/**
* Validate and return end ending tag
*/
function getEndTagName(xmlData,startIndex,lineNum){
xmlData = xmlData.replace(/\s/g, " ");for (var i = startIndex; i < xmlData.length && xmlData[i] !== " " && xmlData[i] !== ">"; i++);
if(xmlData[i-1] !== ">"){
for(var j=i;j<xmlData.length && xmlData[j] !== ">"; j++){
if(xmlData[j] !== " ")
throw new InvalidXmlException("Invalid closing tag at " + lineNum +":"+ startIndex);
}
}
return xmlData.substring(startIndex,i);
}
var attrsRegx1 = new RegExp('(?:[\\s]+([\\w:\-]+)[\\s]*=[\\s]*"([^"]*)")',"g");
var attrsRegx2 = new RegExp("(?:[\\s]+([\\w:\-]+)[\\s]*=[\\s]*'([^']*)')","g");
var attrNamesRegx = new RegExp("([\\w: \-]+)[\\s]*=","g");
/**
* Repeated attributes are not allowed
* if attribute value is enclosed in \' there can't be \' in value
* if attribute value is enclosed in \" there can't be \" in value
* there should be space between 2 attributs
* attribute name can't have space, \', \", =
*/
function getAttrStr(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length && xmlData[i] !== ">"; i++);
if(xmlData[i] === ">"){
var attrStr = xmlData.substring(startIndex,i);
//attrStr = attrStr.trim();
if(attrStr.length > 4){ //a=""
var attrs = getListOfAttrsName([],attrStr,attrsRegx1,startIndex,lineNum);
attrs = getListOfAttrsName(attrs,attrStr,attrsRegx2,startIndex,lineNum);
var matches = getAllMatches(attrStr,attrNamesRegx);
for (i = 0; i < matches.length; i++) {
var attrName = matches[i][1].trim();
if(!attrs[attrName])
throw new InvalidXmlException("Invalid arguments at " + lineNum +":"+ startIndex);
}else if(tags.length > i+1){
if(tags[i+1][0].indexOf("</") === 0){
if(tags[i][1] === tags[i+1][1]) {
return checkForMatchingTag(tags,i+2);
}else {
return -1;//not matching
}
}
return attrStr;
}else{
throw new InvalidXmlException("Not closing tag at " + lineNum +":"+ startIndex);
}else
var nextIndex = checkForMatchingTag(tags,i+1);
if(nextIndex !== -1 && tags[nextIndex][0].indexOf("</") === 0){
if(tags[i][1] === tags[nextIndex][1]) {
return checkForMatchingTag(tags,nextIndex+1);
}else {
return -1;//not matching
}
}
}
return -1;
}
function getListOfAttrsName(attrs,attrStr,attrsRegx,startIndex,lineNum){
var matches = getAllMatches(attrStr,attrsRegx);
for (var i = 0; i < matches.length; i++) {
var attrName = matches[i][1];
if(!attrs[attrName])
attrs[attrName] = true;
else
throw new InvalidXmlException("Argument "+ attrName +" is redefined at " + lineNum +":"+ startIndex);
}
return attrs;
}
function getTagName(xmlData,startIndex){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === " " || xmlData[i] === ">" || (xmlData[i] === "/" && xmlData[i+1] === ">")) break;
}
return xmlData.substring(startIndex,i);
}
function getvalue(xmlData,startIndex){
for (var i = startIndex; i < xmlData.length && xmlData[i] !== "<"; i++);
return xmlData.substring(startIndex,i);
}
exports.validate = validate;
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.parser = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var InvalidXmlException = function (msg){
this.name = "InvalidXmlException";
this.message = msg;
this.stack = (new Error()).stack;
}
InvalidXmlException.prototype = Object.create(Error.prototype);
InvalidXmlException.prototype.constructor = InvalidXmlException;
module.exports = InvalidXmlException;
},{}],2:[function(require,module,exports){
var getAllMatches = require("./util").getAllMatches;

@@ -143,4 +133,5 @@

//var attrsRegx = new RegExp("(\\S+)=.([^'\"]+)","g");
var attrsRegx = new RegExp("(\\S+)=(.)([^=>]*)\\2","g");
//var attrsRegx = new RegExp("(\\S+)=\\s*[\"']?((?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?","g");
//var attrsRegx = new RegExp("(\\S+)=\\s*(['\"])((?:.(?!\\2))*.)","g");
var attrsRegx = new RegExp("(\\S+)\\s*=\\s*(['\"])(.*?)\\2","g");
function buildAttributesArr(attrStr,ignore,prefix,ignoreNS){

@@ -189,3 +180,3 @@ attrStr = attrStr || attrStr.trim();

},{"./util":3,"./validator":4}],3:[function(require,module,exports){
},{"./util":2,"./validator":3}],2:[function(require,module,exports){
var getAllMatches = function(string, regex) {

@@ -207,157 +198,78 @@ //var regex = new RegExp(regex_str,"g");

exports.getAllMatches = getAllMatches;
},{}],4:[function(require,module,exports){
},{}],3:[function(require,module,exports){
var getAllMatches = require("./util").getAllMatches;
var InvalidXmlException = require("./InvalidXmlException");
var validate = function (xmlData){
xmlData = xmlData.replace(/[ \t]/g, " ");
var eStack = [], currentTag = "", lineNum = 1;
for (var i = 0; i < xmlData.length;i++) {
if(xmlData[i] === "\n"){
lineNum++;
}else if(xmlData[i] === '<'){
if(xmlData[i+1] === " "){//comment tag
throw new InvalidXmlException("Invalid tag at "+ lineNum + ":" + i);
}else if(xmlData[i+1] === "!"){//comment tag or CDATA tag
var tg = "";
if(xmlData[i+2] === "-")
tg = getCommentTag(xmlData,i,lineNum);
else if(xmlData[i+2] === "["){
tg = getCDATA(xmlData,i,lineNum);
var tagsPattern = new RegExp("<\\/?([\\w:\\-]+)\\s*\/?>","g");
exports.validate = function validate2(xmlData){
xmlData = xmlData.replace(/\n/g,"");//make it single line
xmlData = xmlData.replace(/(<!\[CDATA\[.*?\]\]>)/g,"");//Remove all CDATA
xmlData = xmlData.replace(/(<!--.*?(?:-->))/g,"");//Remove all comments
if(validateAttributes(xmlData) !== true) return false;
xmlData = xmlData.replace(/(\s+(?:[\w:\-]+)\s*=\s*(['\"]).*?\2)/g,"");//Remove all attributes
xmlData = xmlData.replace(/(^\s*<\?xml\s*\?>)/g,"");//Remove XML starting tag
if(xmlData.indexOf("<![CDATA[") > 0 || xmlData.indexOf("<!--") > 0 ) return false;
var tags = getAllMatches(xmlData,tagsPattern);
if(tags.length === 0) return false; //non xml string
var result = checkForMatchingTag(tags,0);
if(result !== true) return false; else return true;
}
var attrStringPattern = new RegExp("<[\\w:\-]+(.*?)\/?>","g");
var attrPattern = new RegExp("\\s+([\\w:\-]+)\\s*=\\s*(['\"])(.*?)\\2","g");
function validateAttributes(xmlData){
var attrStrings = getAllMatches(xmlData,attrStringPattern);
for (i=0;i<attrStrings.length;i++){
if(attrStrings[i][1].trim().length > 0 && attrStrings[i][1].trim().length < 4){ //invalid attributes
return false;
}else if(attrStrings[i][1].trim().length !== 0){
var attrsList = getAllMatches(attrStrings[i][1],attrPattern);
var attrNames=[];
for (j=0;j<attrsList.length;j++){
if(attrNames[attrsList[j][1]]){//duplicate attributes
return false;
}else{
throw new InvalidXmlException("Invalid tag at "+ lineNum + ":" + i);
attrNames[attrsList[j][1]]=1;
//validate attribute value
//if(!validateAttrValue(attrsList[3])) return false;
}
i+=tg.length-1;
}else if(xmlData[i+1] === "/"){//closing tag
i+=2;
currentTag = getEndTagName(xmlData,i,lineNum);
if(eStack[eStack.length-1] !== currentTag){
throw new InvalidXmlException("closing tag is not matching at "+ lineNum + ":" + i);
}else{
eStack.pop();
}
i+=currentTag.length;
}else{
currentTag = getTagName(xmlData,++i);
i+=currentTag.length;
var attrStr = getAttrStr(xmlData,i,lineNum);
if(attrStr && (attrStr[attrStr.length-1] === "/"|| attrStr[attrStr.length-1] === "?")){
i+=attrStr.length;
}else{
eStack.push(currentTag);
}
var text = getvalue(xmlData,++i);
i+=text.length-1;
}
}
}
if(eStack.length === 0) return true;
else
throw new InvalidXmlException("closing tag is missing for "+ eStack);
};
/**
* Validate and return comment tag
*/
function getCommentTag(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === "-" && xmlData[i+1] === "-" && xmlData[i+2] === ">") break;
}
if(xmlData.substr(startIndex,4) === "<!--" && xmlData.substr(i,3) === "-->")
return xmlData.substring(startIndex,i);
else
throw new InvalidXmlException("Invalid comment tag at " + lineNum +":"+ startIndex);
return true;
}
/**
* Validate and return comment tag
*/
function getCDATA(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === "<" && xmlData[i+1] === "/") {
i--;
break;
}
}
if(xmlData.substr(startIndex,9) === "<![CDATA[" && xmlData.substr(i-2,3) === "]]>")
return xmlData.substring(startIndex,i);
else
throw new InvalidXmlException("Invalid CDATA tag at " + lineNum +":"+ startIndex);
}
function checkForMatchingTag(tags,i){
if(tags.length === i) {
return true;
}else if(tags[i][0].indexOf("</") === 0) {//closing tag
return i;
}else if(tags[i][0].indexOf("/>") === tags[i][0].length-2){//Self closing tag
return checkForMatchingTag(tags,i+1);
/**
* Validate and return end ending tag
*/
function getEndTagName(xmlData,startIndex,lineNum){
xmlData = xmlData.replace(/\s/g, " ");for (var i = startIndex; i < xmlData.length && xmlData[i] !== " " && xmlData[i] !== ">"; i++);
if(xmlData[i-1] !== ">"){
for(var j=i;j<xmlData.length && xmlData[j] !== ">"; j++){
if(xmlData[j] !== " ")
throw new InvalidXmlException("Invalid closing tag at " + lineNum +":"+ startIndex);
}
}
return xmlData.substring(startIndex,i);
}
var attrsRegx1 = new RegExp('(?:[\\s]+([\\w:\-]+)[\\s]*=[\\s]*"([^"]*)")',"g");
var attrsRegx2 = new RegExp("(?:[\\s]+([\\w:\-]+)[\\s]*=[\\s]*'([^']*)')","g");
var attrNamesRegx = new RegExp("([\\w: \-]+)[\\s]*=","g");
/**
* Repeated attributes are not allowed
* if attribute value is enclosed in \' there can't be \' in value
* if attribute value is enclosed in \" there can't be \" in value
* there should be space between 2 attributs
* attribute name can't have space, \', \", =
*/
function getAttrStr(xmlData,startIndex,lineNum){
for (var i = startIndex; i < xmlData.length && xmlData[i] !== ">"; i++);
if(xmlData[i] === ">"){
var attrStr = xmlData.substring(startIndex,i);
//attrStr = attrStr.trim();
if(attrStr.length > 4){ //a=""
var attrs = getListOfAttrsName([],attrStr,attrsRegx1,startIndex,lineNum);
attrs = getListOfAttrsName(attrs,attrStr,attrsRegx2,startIndex,lineNum);
var matches = getAllMatches(attrStr,attrNamesRegx);
for (i = 0; i < matches.length; i++) {
var attrName = matches[i][1].trim();
if(!attrs[attrName])
throw new InvalidXmlException("Invalid arguments at " + lineNum +":"+ startIndex);
}else if(tags.length > i+1){
if(tags[i+1][0].indexOf("</") === 0){
if(tags[i][1] === tags[i+1][1]) {
return checkForMatchingTag(tags,i+2);
}else {
return -1;//not matching
}
}
return attrStr;
}else{
throw new InvalidXmlException("Not closing tag at " + lineNum +":"+ startIndex);
}else
var nextIndex = checkForMatchingTag(tags,i+1);
if(nextIndex !== -1 && tags[nextIndex][0].indexOf("</") === 0){
if(tags[i][1] === tags[nextIndex][1]) {
return checkForMatchingTag(tags,nextIndex+1);
}else {
return -1;//not matching
}
}
}
return -1;
}
function getListOfAttrsName(attrs,attrStr,attrsRegx,startIndex,lineNum){
var matches = getAllMatches(attrStr,attrsRegx);
for (var i = 0; i < matches.length; i++) {
var attrName = matches[i][1];
if(!attrs[attrName])
attrs[attrName] = true;
else
throw new InvalidXmlException("Argument "+ attrName +" is redefined at " + lineNum +":"+ startIndex);
}
return attrs;
}
function getTagName(xmlData,startIndex){
for (var i = startIndex; i < xmlData.length; i++){
if(xmlData[i] === " " || xmlData[i] === ">" || (xmlData[i] === "/" && xmlData[i+1] === ">")) break;
}
return xmlData.substring(startIndex,i);
}
function getvalue(xmlData,startIndex){
for (var i = startIndex; i < xmlData.length && xmlData[i] !== "<"; i++);
return xmlData.substring(startIndex,i);
}
exports.validate = validate;
},{"./InvalidXmlException":1,"./util":3}]},{},[2])(2)
},{"./util":2}]},{},[1])(1)
});
{
"name": "fast-xml-parser",
"version": "2.4.4",
"version": "2.5.0",
"description": "Validate XML or Parse XML to JS/JSON very fast without C/C++ based libraries",

@@ -9,3 +9,3 @@ "main": "./bin/parser.js",

"bundle": "browserify bin/parser.js --s parser > lib/parser.js",
"coverage": "istanbul cover jasmine --captureExceptions spec/*spec.js",
"coverage": "istanbul cover jasmine --captureExceptions spec/*spec.js; node ./benchmark/perfTest.js",
"coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 90 --statement 90"

@@ -35,3 +35,4 @@ },

"transformer",
"checker"
"checker",
"assert"
],

@@ -41,2 +42,3 @@ "author": "Amit Gupta (https://github.com/amitguptagwl)",

"devDependencies": {
"benchmark": "^2.1.4",
"browserify": "^14.1.0",

@@ -49,6 +51,3 @@ "coveralls": "^2.11.15",

"zombie": "^5.0.5"
},
"dependencies": {
"global": "^4.3.2"
}
}

@@ -60,4 +60,2 @@ # [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser)

**Give me a [star](https://github.com/NaturalIntelligence/fast-xml-parser)**, if you really like this project.
## Comparision

@@ -76,3 +74,3 @@ I decided to created this library when I couldn't find any library which can convert XML data to json without any callback and which is not based on any C/C++ library.

**Benchmark report**
### Benchmark report
![npm_xml2json_compare](https://cloud.githubusercontent.com/assets/7692328/22402086/7526a3a6-e5e2-11e6-8e6b-301691725c21.png)

@@ -82,6 +80,6 @@

validator benchmark: 2000 tps
**validator benchmark: 21000 tps**
### Limitation
This tool doesn't check if the XML is valid or not. If the XML is not valid you may get invalid result.
Parser doesn't check if the XML is valid or not. If the XML is not valid you may get invalid result. So you can call the validator function first to check the structure.

@@ -93,2 +91,6 @@ Report an issue or request for a feature [here](https://github.com/NaturalIntelligence/fast-xml-parser/issues)

**Give me a [star](https://github.com/NaturalIntelligence/fast-xml-parser)**, if you really like this project.
**Fund collected (since the starting of the project)** : $0
Some of my other NPM pojects

@@ -95,0 +97,0 @@ - [stubmatic](https://github.com/NaturalIntelligence/Stubmatic) : A stub server to mock behaviour of HTTP(s) / REST / SOAP services. Stubbing redis is on the way.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc