CyberChef/src/core/operations/XPathExpression.mjs

87 lines
2.2 KiB
JavaScript

/**
* @author Mikescher (https://github.com/Mikescher | https://mikescher.com)
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import xmldom from "@xmldom/xmldom";
import xpath from "xpath";
/**
* XPath expression operation
*/
class XPathExpression extends Operation {
/**
* XPathExpression constructor
*/
constructor() {
super();
this.name = "XPath expression";
this.module = "Code";
this.description = "Extract information from an XML document with an XPath query";
this.infoURL = "https://wikipedia.org/wiki/XPath";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "XPath",
"type": "string",
"value": ""
},
{
"name": "Result delimiter",
"type": "binaryShortString",
"value": "\\n"
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [query, delimiter] = args;
let doc;
try {
doc = new xmldom.DOMParser({
errorHandler: {
warning(w) {
throw w;
},
error(e) {
throw e;
},
fatalError(e) {
throw e;
}
}
}).parseFromString(input, "application/xml");
} catch (err) {
throw new OperationError("Invalid input XML.");
}
let nodes;
try {
nodes = xpath.parse(query).select({ node: doc, allowAnyNamespaceForNoPrefix: true });
} catch (err) {
throw new OperationError(`Invalid XPath. Details:\n${err.message}.`);
}
const nodeToString = function(node) {
return node.toString();
};
return nodes.map(nodeToString).join(delimiter);
}
}
export default XPathExpression;