🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@aws-sdk/xml-builder

Package Overview
Dependencies
Maintainers
2
Versions
137
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aws-sdk/xml-builder - npm Package Compare versions

Comparing version
3.972.31
to
3.972.32
+236
-3
dist-cjs/index.js

@@ -1,4 +0,1 @@

const { parseXML } = require("./xml-parser");
exports.parseXML = parseXML;
const ATTR_ESCAPE_RE = /[&<>"]/g;

@@ -128,3 +125,239 @@ const ATTR_ESCAPE_MAP = {

function parseXML(xml) {
const state = new AwsXmlParser(xml);
return state.parse();
}
class AwsXmlParser {
x;
i = 0;
z;
constructor(x) {
this.x = x;
this.x = x.replace(/\r\n?/g, "\n");
this.z = this.x.length;
}
parse() {
const p = this;
const { z } = p;
while (p.i < z) {
p.trim();
if (p.i >= z) {
break;
}
if (p.isNext("<?")) {
p.readTo("?>");
p.trim();
}
else if (p.isNext("<!--")) {
p.readTo("-->");
p.trim();
}
else if (p.isNext("<!DOCTYPE", false)) {
p.skipDoctype();
p.trim();
}
else if (p.x[p.i] === "<") {
const root = p.parseTag();
return { [root.tag]: root.value };
}
else {
throw new Error("@aws-sdk XML parse error: unexpected content.");
}
}
throw new Error("@aws-sdk XML parse error: no root element.");
}
isNext(s, caseSensitive = true) {
const p = this;
if (caseSensitive) {
return p.x.startsWith(s, p.i);
}
return p.x.toLowerCase().startsWith(s.toLowerCase(), p.i);
}
readTo(stop) {
const p = this;
const _i = p.x.indexOf(stop, p.i);
if (_i === -1) {
throw new Error(`@aws-sdk XML parse error: expected "${stop}" not found.`);
}
const result = p.x.slice(p.i, _i);
p.i = _i + stop.length;
return result;
}
trim() {
const p = this;
while (p.i < p.z && " \t\r\n".includes(p.x[p.i])) {
++p.i;
}
}
readAttrValue() {
const p = this;
const quote = p.x[p.i];
++p.i;
let value = "";
while (p.i < p.z && p.x[p.i] !== quote) {
value += p.x[p.i++];
}
++p.i;
return p.decodeEntities(value);
}
parseTag() {
const p = this;
++p.i;
let tag = "";
while (p.i < p.z && !" \t\r\n>/".includes(p.x[p.i])) {
tag += p.x[p.i++];
}
let hasAttrs = false;
const attrs = Object.create(null);
while (p.i < p.z) {
p.trim();
if (">/".includes(p.x[p.i])) {
break;
}
let name = "";
while (p.i < p.z && !"= \t\r\n>/?".includes(p.x[p.i])) {
name += p.x[p.i++];
}
p.trim();
if (p.x[p.i] !== "=") {
break;
}
++p.i;
p.trim();
attrs[name] = p.readAttrValue();
hasAttrs = true;
}
if (p.i >= p.z) {
throw new Error("@aws-sdk XML parse error: unexpected end of input.");
}
if (p.x[p.i] === "/") {
++p.i;
if (p.i >= p.z || p.x[p.i] !== ">") {
throw new Error("@aws-sdk XML parse error: expected > at the end of self-closing tag.");
}
++p.i;
Object.setPrototypeOf(attrs, Object.prototype);
return { tag, value: hasAttrs ? attrs : "" };
}
if (p.x[p.i] !== ">") {
throw new Error("@aws-sdk XML parse error: expected > at the end of opening tag.");
}
++p.i;
const textParts = [];
const childTags = [];
let hasElementChild = false;
while (p.i < p.z) {
if (p.isNext("</")) {
break;
}
if (p.x[p.i] === "<") {
if (p.isNext("<!--")) {
p.readTo("-->");
}
else if (p.isNext("<![CDATA[")) {
p.i += 9;
textParts.push(p.readTo("]]>"));
}
else if (p.isNext("<?")) {
p.readTo("?>");
}
else {
hasElementChild = true;
childTags.push(p.parseTag());
}
}
else {
let text = "";
while (p.i < p.z && p.x[p.i] !== "<") {
text += p.x[p.i++];
}
textParts.push(p.decodeEntities(text));
}
}
if (!p.isNext("</")) {
throw new Error(`@aws-sdk XML parse error: missing closing tag </${tag}>.`);
}
p.i += 2;
const closeTag = p.readTo(">").trim();
if (closeTag !== tag) {
throw new Error(`@aws-sdk XML parse error: mismatched tags <${tag}> and </${closeTag}>.`);
}
if (!hasAttrs && textParts.length === 0 && !hasElementChild) {
return { tag, value: "" };
}
if (!hasAttrs && !hasElementChild) {
const text = textParts.length === 1 ? textParts[0] : textParts.join("");
if (text.trim() === "" && text.includes("\n")) {
return { tag, value: "" };
}
return { tag, value: text };
}
const obj = Object.create(null);
for (const text of textParts) {
if (text.trim() === "" && text.includes("\n")) {
continue;
}
obj["#text"] = "#text" in obj ? obj["#text"] + text : text;
}
for (const child of childTags) {
if (child.tag in obj) {
if (Array.isArray(obj[child.tag])) {
obj[child.tag].push(child.value);
}
else {
obj[child.tag] = [obj[child.tag], child.value];
}
}
else {
obj[child.tag] = child.value;
}
}
for (const [k, v] of Object.entries(attrs)) {
obj[k] = v;
}
Object.setPrototypeOf(obj, Object.prototype);
return { tag, value: obj };
}
static ENTITIES = {
amp: "&",
lt: "<",
gt: ">",
quot: '"',
apos: "'",
};
skipDoctype() {
const p = this;
p.i += 9;
let depth = 0;
while (p.i < p.z) {
const c = p.x[p.i];
if (c === "[") {
++depth;
}
else if (c === "]") {
--depth;
}
else if (c === ">" && depth === 0) {
++p.i;
return;
}
++p.i;
}
throw new Error("@aws-sdk XML parse error: unclosed DOCTYPE.");
}
decodeEntities(s) {
return s.replace(/&(?:#x([0-9a-fA-F]{1,6})|#(\d{1,7})|([a-zA-Z][a-zA-Z0-9]{0,30}));/g, (_, hex, dec, named) => {
if (hex) {
return String.fromCharCode(parseInt(hex, 16));
}
if (dec) {
return String.fromCharCode(parseInt(dec, 10));
}
return AwsXmlParser.ENTITIES[named] ?? "";
});
}
}
exports.XmlNode = XmlNode;
exports.XmlText = XmlText;
exports.parseXML = parseXML;
+3
-4
{
"name": "@aws-sdk/xml-builder",
"version": "3.972.31",
"version": "3.972.32",
"description": "XML utilities for the AWS SDK",
"dependencies": {
"@smithy/types": "^4.14.3",
"@smithy/types": "^4.15.0",
"tslib": "^2.6.2"

@@ -48,4 +48,3 @@ },

"react-native": {
"./dist-es/xml-parser": "./dist-es/xml-parser.browser",
"./dist-cjs/xml-parser": "./dist-cjs/xml-parser.browser"
"./dist-es/xml-parser": "./dist-es/xml-parser.browser"
},

@@ -52,0 +51,0 @@ "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages-internal/xml-builder",

let parser;
exports.parseXML = function parseXML(xmlString) {
if (!parser) {
parser = new DOMParser();
}
const xmlDocument = parser.parseFromString(xmlString, "application/xml");
if (xmlDocument.getElementsByTagName("parsererror").length > 0) {
throw new Error("DOMParser XML parsing error.");
}
const xmlToObj = (node) => {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent?.trim()) {
return node.textContent;
}
}
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node;
if (element.attributes.length === 0 && element.childNodes.length === 0) {
return "";
}
const obj = {};
const attributes = Array.from(element.attributes);
for (const attr of attributes) {
obj[`${attr.name}`] = attr.value;
}
const childNodes = Array.from(element.childNodes);
for (const child of childNodes) {
const childResult = xmlToObj(child);
if (childResult != null) {
const childName = child.nodeName;
if (childNodes.length === 1 && attributes.length === 0 && childName === "#text") {
return childResult;
}
if (childName in obj) {
if (Array.isArray(obj[childName])) {
obj[childName].push(childResult);
}
else {
obj[childName] = [obj[childName], childResult];
}
}
else {
obj[childName] = childResult;
}
}
else if (childNodes.length === 1 && attributes.length === 0) {
return element.textContent;
}
}
return obj;
}
return null;
};
return {
[xmlDocument.documentElement.nodeName]: xmlToObj(xmlDocument.documentElement),
};
};
exports.parseXML = function parseXML(xml) {
const state = new AwsXmlParser(xml);
return state.parse();
};
class AwsXmlParser {
x;
i = 0;
z;
constructor(x) {
this.x = x;
this.x = x.replace(/\r\n?/g, "\n");
this.z = this.x.length;
}
parse() {
const p = this;
const { z } = p;
while (p.i < z) {
p.trim();
if (p.i >= z) {
break;
}
if (p.isNext("<?")) {
p.readTo("?>");
p.trim();
}
else if (p.isNext("<!--")) {
p.readTo("-->");
p.trim();
}
else if (p.isNext("<!DOCTYPE", false)) {
p.skipDoctype();
p.trim();
}
else if (p.x[p.i] === "<") {
const root = p.parseTag();
return { [root.tag]: root.value };
}
else {
throw new Error("@aws-sdk XML parse error: unexpected content.");
}
}
throw new Error("@aws-sdk XML parse error: no root element.");
}
isNext(s, caseSensitive = true) {
const p = this;
if (caseSensitive) {
return p.x.startsWith(s, p.i);
}
return p.x.toLowerCase().startsWith(s.toLowerCase(), p.i);
}
readTo(stop) {
const p = this;
const _i = p.x.indexOf(stop, p.i);
if (_i === -1) {
throw new Error(`@aws-sdk XML parse error: expected "${stop}" not found.`);
}
const result = p.x.slice(p.i, _i);
p.i = _i + stop.length;
return result;
}
trim() {
const p = this;
while (p.i < p.z && " \t\r\n".includes(p.x[p.i])) {
++p.i;
}
}
readAttrValue() {
const p = this;
const quote = p.x[p.i];
++p.i;
let value = "";
while (p.i < p.z && p.x[p.i] !== quote) {
value += p.x[p.i++];
}
++p.i;
return p.decodeEntities(value);
}
parseTag() {
const p = this;
++p.i;
let tag = "";
while (p.i < p.z && !" \t\r\n>/".includes(p.x[p.i])) {
tag += p.x[p.i++];
}
let hasAttrs = false;
const attrs = Object.create(null);
while (p.i < p.z) {
p.trim();
if (">/".includes(p.x[p.i])) {
break;
}
let name = "";
while (p.i < p.z && !"= \t\r\n>/?".includes(p.x[p.i])) {
name += p.x[p.i++];
}
p.trim();
if (p.x[p.i] !== "=") {
break;
}
++p.i;
p.trim();
attrs[name] = p.readAttrValue();
hasAttrs = true;
}
if (p.i >= p.z) {
throw new Error("@aws-sdk XML parse error: unexpected end of input.");
}
if (p.x[p.i] === "/") {
++p.i;
if (p.i >= p.z || p.x[p.i] !== ">") {
throw new Error("@aws-sdk XML parse error: expected > at the end of self-closing tag.");
}
++p.i;
Object.setPrototypeOf(attrs, Object.prototype);
return { tag, value: hasAttrs ? attrs : "" };
}
if (p.x[p.i] !== ">") {
throw new Error("@aws-sdk XML parse error: expected > at the end of opening tag.");
}
++p.i;
const textParts = [];
const childTags = [];
let hasElementChild = false;
while (p.i < p.z) {
if (p.isNext("</")) {
break;
}
if (p.x[p.i] === "<") {
if (p.isNext("<!--")) {
p.readTo("-->");
}
else if (p.isNext("<![CDATA[")) {
p.i += 9;
textParts.push(p.readTo("]]>"));
}
else if (p.isNext("<?")) {
p.readTo("?>");
}
else {
hasElementChild = true;
childTags.push(p.parseTag());
}
}
else {
let text = "";
while (p.i < p.z && p.x[p.i] !== "<") {
text += p.x[p.i++];
}
textParts.push(p.decodeEntities(text));
}
}
if (!p.isNext("</")) {
throw new Error(`@aws-sdk XML parse error: missing closing tag </${tag}>.`);
}
p.i += 2;
const closeTag = p.readTo(">").trim();
if (closeTag !== tag) {
throw new Error(`@aws-sdk XML parse error: mismatched tags <${tag}> and </${closeTag}>.`);
}
if (!hasAttrs && textParts.length === 0 && !hasElementChild) {
return { tag, value: "" };
}
if (!hasAttrs && !hasElementChild) {
const text = textParts.length === 1 ? textParts[0] : textParts.join("");
if (text.trim() === "" && text.includes("\n")) {
return { tag, value: "" };
}
return { tag, value: text };
}
const obj = Object.create(null);
for (const text of textParts) {
if (text.trim() === "" && text.includes("\n")) {
continue;
}
obj["#text"] = "#text" in obj ? obj["#text"] + text : text;
}
for (const child of childTags) {
if (child.tag in obj) {
if (Array.isArray(obj[child.tag])) {
obj[child.tag].push(child.value);
}
else {
obj[child.tag] = [obj[child.tag], child.value];
}
}
else {
obj[child.tag] = child.value;
}
}
for (const [k, v] of Object.entries(attrs)) {
obj[k] = v;
}
Object.setPrototypeOf(obj, Object.prototype);
return { tag, value: obj };
}
static ENTITIES = {
amp: "&",
lt: "<",
gt: ">",
quot: '"',
apos: "'",
};
skipDoctype() {
const p = this;
p.i += 9;
let depth = 0;
while (p.i < p.z) {
const c = p.x[p.i];
if (c === "[") {
++depth;
}
else if (c === "]") {
--depth;
}
else if (c === ">" && depth === 0) {
++p.i;
return;
}
++p.i;
}
throw new Error("@aws-sdk XML parse error: unclosed DOCTYPE.");
}
decodeEntities(s) {
return s.replace(/&(?:#x([0-9a-fA-F]{1,6})|#(\d{1,7})|([a-zA-Z][a-zA-Z0-9]{0,30}));/g, (_, hex, dec, named) => {
if (hex) {
return String.fromCharCode(parseInt(hex, 16));
}
if (dec) {
return String.fromCharCode(parseInt(dec, 10));
}
return AwsXmlParser.ENTITIES[named] ?? "";
});
}
}