poe-code 15.0.0 → 15.0.2

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 (86) hide show
  1. package/dist/metafile.json +1 -1
  2. package/package.json +13 -1
  3. package/packages/safe-bash/dist/chunks/chunk-4OKU6JXB.js +5279 -0
  4. package/packages/safe-bash/dist/chunks/chunk-4OKU6JXB.js.map +7 -0
  5. package/packages/safe-bash/dist/chunks/chunk-5HT35GTV.js +520 -0
  6. package/packages/safe-bash/dist/chunks/chunk-5HT35GTV.js.map +7 -0
  7. package/packages/safe-bash/dist/chunks/chunk-B637PJBS.js +3317 -0
  8. package/packages/safe-bash/dist/chunks/chunk-B637PJBS.js.map +7 -0
  9. package/packages/safe-bash/dist/commands/structured/query-core.d.ts +35 -0
  10. package/packages/safe-bash/dist/commands/structured/query-core.d.ts.map +1 -0
  11. package/packages/safe-bash/dist/commands/structured/query-core.js +588 -0
  12. package/packages/safe-bash/dist/commands/structured/query-core.js.map +1 -0
  13. package/packages/safe-bash/dist/commands/xml/evaluate.d.ts +27 -0
  14. package/packages/safe-bash/dist/commands/xml/evaluate.d.ts.map +1 -0
  15. package/packages/safe-bash/dist/commands/xml/evaluate.js +208 -0
  16. package/packages/safe-bash/dist/commands/xml/evaluate.js.map +1 -0
  17. package/packages/safe-bash/dist/commands/xml/index.browser.js +12 -0
  18. package/packages/safe-bash/dist/commands/xml/index.browser.js.map +7 -0
  19. package/packages/safe-bash/dist/commands/xml/index.d.ts +7 -0
  20. package/packages/safe-bash/dist/commands/xml/index.d.ts.map +1 -0
  21. package/packages/safe-bash/dist/commands/xml/index.js +196 -0
  22. package/packages/safe-bash/dist/commands/xml/index.js.map +1 -0
  23. package/packages/safe-bash/dist/commands/xml/limits.d.ts +36 -0
  24. package/packages/safe-bash/dist/commands/xml/limits.d.ts.map +1 -0
  25. package/packages/safe-bash/dist/commands/xml/limits.js +55 -0
  26. package/packages/safe-bash/dist/commands/xml/limits.js.map +1 -0
  27. package/packages/safe-bash/dist/commands/xml/query.d.ts +21 -0
  28. package/packages/safe-bash/dist/commands/xml/query.d.ts.map +1 -0
  29. package/packages/safe-bash/dist/commands/xml/query.js +111 -0
  30. package/packages/safe-bash/dist/commands/xml/query.js.map +1 -0
  31. package/packages/safe-bash/dist/commands/yq/accounting.d.ts +64 -0
  32. package/packages/safe-bash/dist/commands/yq/accounting.d.ts.map +1 -0
  33. package/packages/safe-bash/dist/commands/yq/accounting.js +257 -0
  34. package/packages/safe-bash/dist/commands/yq/accounting.js.map +1 -0
  35. package/packages/safe-bash/dist/commands/yq/encoder.d.ts +6 -0
  36. package/packages/safe-bash/dist/commands/yq/encoder.d.ts.map +1 -0
  37. package/packages/safe-bash/dist/commands/yq/encoder.js +240 -0
  38. package/packages/safe-bash/dist/commands/yq/encoder.js.map +1 -0
  39. package/packages/safe-bash/dist/commands/yq/errors.d.ts +15 -0
  40. package/packages/safe-bash/dist/commands/yq/errors.d.ts.map +1 -0
  41. package/packages/safe-bash/dist/commands/yq/errors.js +37 -0
  42. package/packages/safe-bash/dist/commands/yq/errors.js.map +1 -0
  43. package/packages/safe-bash/dist/commands/yq/index.browser.js +12 -0
  44. package/packages/safe-bash/dist/commands/yq/index.browser.js.map +7 -0
  45. package/packages/safe-bash/dist/commands/yq/index.d.ts +9 -0
  46. package/packages/safe-bash/dist/commands/yq/index.d.ts.map +1 -0
  47. package/packages/safe-bash/dist/commands/yq/index.js +719 -0
  48. package/packages/safe-bash/dist/commands/yq/index.js.map +1 -0
  49. package/packages/safe-bash/dist/commands/yq/parser.d.ts +5 -0
  50. package/packages/safe-bash/dist/commands/yq/parser.d.ts.map +1 -0
  51. package/packages/safe-bash/dist/commands/yq/parser.js +1326 -0
  52. package/packages/safe-bash/dist/commands/yq/parser.js.map +1 -0
  53. package/packages/safe-bash/dist/commands/yq/toml.d.ts +5 -0
  54. package/packages/safe-bash/dist/commands/yq/toml.d.ts.map +1 -0
  55. package/packages/safe-bash/dist/commands/yq/toml.js +690 -0
  56. package/packages/safe-bash/dist/commands/yq/toml.js.map +1 -0
  57. package/packages/safe-bash/dist/core.browser.js +2828 -7667
  58. package/packages/safe-bash/dist/core.browser.js.map +4 -4
  59. package/packages/safe-bash/dist/core.d.ts +2 -0
  60. package/packages/safe-bash/dist/core.d.ts.map +1 -1
  61. package/packages/safe-bash/dist/core.js +2 -0
  62. package/packages/safe-bash/dist/core.js.map +1 -1
  63. package/packages/safe-bash/dist/plugins/composition.d.ts +2 -0
  64. package/packages/safe-bash/dist/plugins/composition.d.ts.map +1 -1
  65. package/packages/safe-bash/dist/plugins/composition.js +3 -1
  66. package/packages/safe-bash/dist/plugins/composition.js.map +1 -1
  67. package/packages/safe-fs/dist/core.d.ts +2 -0
  68. package/packages/safe-fs/dist/fs/webdav/xml.d.ts +4 -10
  69. package/packages/safe-fs/dist/xml.d.ts +42 -0
  70. package/packages/safe-js/dist/browser/chunks/{chunk-QK4IEGRO.js → chunk-CRKYNANF.js} +304 -67
  71. package/packages/safe-js/dist/browser/chunks/{chunk-QK4IEGRO.js.map → chunk-CRKYNANF.js.map} +4 -4
  72. package/packages/safe-js/dist/browser/safe-fs-core.js +7 -1
  73. package/packages/safe-js/dist/browser/safe-fs.js +7 -1
  74. package/packages/safe-js/dist/chunks/{chunk-BG7WRAD3.js → chunk-7JFJLEHK.js} +3 -3
  75. package/packages/safe-js/dist/chunks/{chunk-XOQ5CVQM.js → chunk-CM4RZVZD.js} +2 -2
  76. package/packages/safe-js/dist/chunks/{chunk-6V4U2JZS.js → chunk-LRGCUDH7.js} +333 -96
  77. package/packages/safe-js/dist/chunks/chunk-LRGCUDH7.js.map +7 -0
  78. package/packages/safe-js/dist/cli.js +3 -3
  79. package/packages/safe-js/dist/index.js +3 -3
  80. package/packages/safe-js/dist/safe-fs-core.js +7 -1
  81. package/packages/safe-js/dist/safe-fs-core.js.map +1 -1
  82. package/packages/safe-js/dist/safe-fs-node.js +2 -2
  83. package/packages/safe-js/dist/safe-fs.js +2 -2
  84. package/packages/safe-js/dist/chunks/chunk-6V4U2JZS.js.map +0 -7
  85. /package/packages/safe-js/dist/chunks/{chunk-BG7WRAD3.js.map → chunk-7JFJLEHK.js.map} +0 -0
  86. /package/packages/safe-js/dist/chunks/{chunk-XOQ5CVQM.js.map → chunk-CM4RZVZD.js.map} +0 -0
@@ -4034,13 +4034,33 @@ function composeAbortSignals(signals) {
4034
4034
  return { signal: controller.signal, dispose };
4035
4035
  }
4036
4036
 
4037
- // packages/safe-fs/src/fs/webdav/xml.ts
4038
- var XmlResponseLimitError = class extends SyntaxError {
4037
+ // packages/safe-fs/src/xml.ts
4038
+ var XmlLimitError = class extends SyntaxError {
4039
+ constructor(limit, message) {
4040
+ super(message);
4041
+ this.limit = limit;
4042
+ }
4043
+ limit;
4039
4044
  };
4045
+ function* find(source, needle, start) {
4046
+ let work = 0;
4047
+ for (let offset = start; offset < source.length; offset++) {
4048
+ if (source.startsWith(needle, offset)) {
4049
+ if (work) yield work;
4050
+ return offset;
4051
+ }
4052
+ if (++work === 512) {
4053
+ yield work;
4054
+ work = 0;
4055
+ }
4056
+ }
4057
+ if (work) yield work;
4058
+ return -1;
4059
+ }
4040
4060
  var xmlNamespace = "http://www.w3.org/XML/1998/namespace";
4041
4061
  var xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
4042
4062
  function invalid(message) {
4043
- throw new SyntaxError(`Invalid WebDAV XML: ${message}`);
4063
+ throw new SyntaxError(`Invalid XML: ${message}`);
4044
4064
  }
4045
4065
  function validCharacter(point) {
4046
4066
  return point === 9 || point === 10 || point === 13 || point >= 32 && point <= 55295 || point >= 57344 && point <= 65533 || point >= 65536 && point <= 1114111;
@@ -4051,22 +4071,42 @@ function nameStart(point) {
4051
4071
  function namePart(point) {
4052
4072
  return nameStart(point) || point === 45 || point === 46 || point === 183 || point >= 48 && point <= 57 || point >= 768 && point <= 879 || point >= 8255 && point <= 8256;
4053
4073
  }
4054
- function qualifiedName(name) {
4055
- const parts = name.split(":");
4056
- if (parts.length > 2 || parts.some((part) => {
4057
- const points = [...part].map((character) => character.codePointAt(0));
4058
- return points.length === 0 || !nameStart(points[0]) || points.slice(1).some((point) => !namePart(point));
4059
- })) invalid("invalid qualified name");
4060
- return parts.length === 1 ? ["", parts[0]] : [parts[0], parts[1]];
4074
+ function* qualifiedName(name) {
4075
+ let prefix = "";
4076
+ let start = 0;
4077
+ let first = true;
4078
+ let work = 0;
4079
+ for (let offset = 0; offset < name.length; ) {
4080
+ const point = name.codePointAt(offset);
4081
+ if (point === 58) {
4082
+ if (start !== 0 || first) invalid("invalid qualified name");
4083
+ prefix = name.slice(0, offset);
4084
+ start = offset + 1;
4085
+ first = true;
4086
+ } else {
4087
+ if (!(first ? nameStart(point) : namePart(point))) invalid("invalid qualified name");
4088
+ first = false;
4089
+ }
4090
+ const width = point > 65535 ? 2 : 1;
4091
+ offset += width;
4092
+ work += width;
4093
+ if (work >= 512) {
4094
+ yield work;
4095
+ work = 0;
4096
+ }
4097
+ }
4098
+ if (first) invalid("invalid qualified name");
4099
+ if (work) yield work;
4100
+ return [prefix, name.slice(start)];
4061
4101
  }
4062
- function entities(text) {
4102
+ function* entities(text) {
4063
4103
  let result = "";
4064
4104
  let offset = 0;
4065
4105
  while (offset < text.length) {
4066
- const start = text.indexOf("&", offset);
4106
+ const start = yield* find(text, "&", offset);
4067
4107
  if (start < 0) return result + text.slice(offset);
4068
4108
  result += text.slice(offset, start);
4069
- const end = text.indexOf(";", start + 1);
4109
+ const end = yield* find(text, ";", start + 1);
4070
4110
  if (end < 0) invalid("unterminated entity");
4071
4111
  const entity = text.slice(start + 1, end);
4072
4112
  const predefined = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
@@ -4074,10 +4114,17 @@ function entities(text) {
4074
4114
  else {
4075
4115
  const hexadecimal = entity.startsWith("#x");
4076
4116
  const digits = entity.slice(hexadecimal ? 2 : 1);
4077
- if (!entity.startsWith("#") || !(hexadecimal ? /^[0-9a-fA-F]+$/ : /^[0-9]+$/).test(digits)) {
4078
- invalid("undeclared entity");
4117
+ if (!entity.startsWith("#") || !digits.length) invalid("undeclared entity");
4118
+ let point = 0;
4119
+ for (let index = 0; index < digits.length; index++) {
4120
+ const code = digits.charCodeAt(index);
4121
+ const digit = code >= 48 && code <= 57 ? code - 48 : hexadecimal && code >= 65 && code <= 70 ? code - 55 : hexadecimal && code >= 97 && code <= 102 ? code - 87 : -1;
4122
+ if (digit < 0) invalid("undeclared entity");
4123
+ point = point * (hexadecimal ? 16 : 10) + digit;
4124
+ if (point > 1114111) invalid("invalid character reference");
4125
+ if ((index + 1) % 512 === 0) yield 512;
4079
4126
  }
4080
- const point = Number.parseInt(digits, hexadecimal ? 16 : 10);
4127
+ if (digits.length % 512) yield digits.length % 512;
4081
4128
  if (!validCharacter(point)) invalid("invalid character reference");
4082
4129
  result += String.fromCodePoint(point);
4083
4130
  }
@@ -4085,149 +4132,336 @@ function entities(text) {
4085
4132
  }
4086
4133
  return result;
4087
4134
  }
4088
- function parseXml(input, limits = {}) {
4135
+ function* validDeclaration(content, expectedEncoding) {
4136
+ let offset = 0;
4137
+ const whitespace = function* () {
4138
+ const start = offset;
4139
+ while (offset < content.length && " \n\r".includes(content[offset])) {
4140
+ offset++;
4141
+ if ((offset - start) % 512 === 0) yield 512;
4142
+ }
4143
+ if ((offset - start) % 512) yield (offset - start) % 512;
4144
+ return offset - start;
4145
+ };
4146
+ const field = function* (name) {
4147
+ if (content.slice(offset, offset + name.length).toLowerCase() !== name) return void 0;
4148
+ offset += name.length;
4149
+ yield name.length;
4150
+ yield* whitespace();
4151
+ if (content[offset++] !== "=") return void 0;
4152
+ yield* whitespace();
4153
+ const quote = content[offset++];
4154
+ if (quote !== "'" && quote !== '"') return void 0;
4155
+ const start = offset;
4156
+ while (offset < content.length && content[offset] !== quote) {
4157
+ offset++;
4158
+ if ((offset - start) % 512 === 0) yield 512;
4159
+ }
4160
+ if ((offset - start) % 512) yield (offset - start) % 512;
4161
+ if (offset >= content.length) return void 0;
4162
+ return content.slice(start, offset++);
4163
+ };
4164
+ if (!(yield* whitespace()) || (yield* field("version")) !== "1.0") return false;
4165
+ let spacing = yield* whitespace();
4166
+ if (content.slice(offset, offset + 8).toLowerCase() === "encoding") {
4167
+ if (!spacing) return false;
4168
+ const encoding = yield* field("encoding");
4169
+ if (encoding === void 0 || encoding.length > 8 || !["utf-8", "utf-16", "utf-16le", "utf-16be"].includes(encoding.toLowerCase())) return false;
4170
+ if (expectedEncoding !== void 0 && encoding.toLowerCase() !== expectedEncoding.toLowerCase()) return false;
4171
+ spacing = yield* whitespace();
4172
+ }
4173
+ if (content.slice(offset, offset + 10).toLowerCase() === "standalone") {
4174
+ if (!spacing) return false;
4175
+ const standalone = yield* field("standalone");
4176
+ if (standalone === void 0 || standalone.length > 3 || !["yes", "no"].includes(standalone.toLowerCase())) return false;
4177
+ yield* whitespace();
4178
+ }
4179
+ return offset === content.length;
4180
+ }
4181
+ function* parseXmlSteps(input, limits = {}) {
4089
4182
  const maxDepth = limits.maxDepth ?? 64;
4090
4183
  const maxNodes = limits.maxNodes ?? 1e5;
4091
4184
  const maxAttributes = limits.maxAttributes ?? 1e4;
4092
- for (const limit of [maxDepth, maxNodes, maxAttributes, ...limits.maxResponses === void 0 ? [] : [limits.maxResponses]]) {
4185
+ const retainContent = limits.retainContent !== false;
4186
+ const maxContentNodes = limits.maxContentNodes ?? (retainContent ? 1e5 : maxNodes);
4187
+ const emptyContent = Object.freeze([]);
4188
+ const emptyAttributes = Object.freeze([]);
4189
+ const emptyNamespaces = /* @__PURE__ */ new Map();
4190
+ const maxAttributesPerElement = limits.maxAttributesPerElement ?? 128;
4191
+ const maxNamespaces = limits.maxNamespaces ?? 256;
4192
+ for (const limit of [maxDepth, maxNodes, maxAttributes, maxContentNodes, maxAttributesPerElement, maxNamespaces]) {
4093
4193
  if (!Number.isSafeInteger(limit) || limit < 1) throw new RangeError("XML limits must be positive integers");
4094
4194
  }
4095
- for (const character of input) {
4096
- if (!validCharacter(character.codePointAt(0))) invalid("invalid character");
4195
+ const chunks = [];
4196
+ let chunk = "";
4197
+ for (let index = input.charCodeAt(0) === 65279 ? 1 : 0; index < input.length; index++) {
4198
+ const point = input.codePointAt(index);
4199
+ if (!validCharacter(point)) invalid("invalid character");
4200
+ if (point === 13) {
4201
+ chunk += "\n";
4202
+ if (input.charCodeAt(index + 1) === 10) index++;
4203
+ } else {
4204
+ chunk += String.fromCodePoint(point);
4205
+ if (point > 65535) index++;
4206
+ }
4207
+ if (chunk.length >= 512) {
4208
+ chunks.push(chunk);
4209
+ chunk = "";
4210
+ yield 512;
4211
+ }
4097
4212
  }
4098
- const source = input.replace(/^\uFEFF/, "").replace(/\r\n?/g, "\n");
4213
+ chunks.push(chunk);
4214
+ if (chunk.length) yield chunk.length;
4215
+ const source = chunks.join("");
4099
4216
  const stack = [];
4100
4217
  let root;
4218
+ let declaration;
4101
4219
  let offset = 0;
4102
4220
  let nodes = 0;
4103
4221
  let attributeCount = 0;
4104
- let responses2 = 0;
4105
- const whitespace = () => {
4106
- while (offset < source.length && " \n\r".includes(source[offset])) offset++;
4222
+ let contentNodes = 0;
4223
+ const admitContent = () => {
4224
+ if (++contentNodes > maxContentNodes) throw new XmlLimitError("maxContentNodes", "XML content node limit exceeded");
4225
+ };
4226
+ const whitespace = function* () {
4227
+ let work = 0;
4228
+ while (offset < source.length && " \n\r".includes(source[offset])) {
4229
+ offset++;
4230
+ if (++work === 512) {
4231
+ yield work;
4232
+ work = 0;
4233
+ }
4234
+ }
4235
+ if (work) yield work;
4107
4236
  };
4108
- const readName = () => {
4237
+ const readName = function* () {
4109
4238
  const start = offset;
4110
- while (offset < source.length && !" \r\n/=>?".includes(source[offset])) offset++;
4239
+ while (offset < source.length && !" \r\n/=>?".includes(source[offset])) {
4240
+ offset++;
4241
+ if ((offset - start) % 512 === 0) yield 512;
4242
+ }
4243
+ if ((offset - start) % 512) yield (offset - start) % 512;
4111
4244
  const name = source.slice(start, offset);
4112
- qualifiedName(name);
4245
+ yield* qualifiedName(name);
4113
4246
  return name;
4114
4247
  };
4115
- const appendText = (text) => {
4248
+ const appendText = function* (text, kind = "text") {
4116
4249
  const parent = stack.at(-1);
4117
- if (parent) parent.element.text += text;
4118
- else if (!/^[ \t\r\n]*$/.test(text)) invalid("text outside the root");
4250
+ if (parent) {
4251
+ parent.element.text += text;
4252
+ if (retainContent && (text.length || kind === "cdata")) {
4253
+ admitContent();
4254
+ parent.content.push({ kind, text });
4255
+ }
4256
+ } else {
4257
+ for (let index = 0; index < text.length; index++) {
4258
+ if (!" \r\n".includes(text[index])) invalid("text outside the root");
4259
+ if ((index + 1) % 512 === 0) yield 512;
4260
+ }
4261
+ if (text.length % 512) yield text.length % 512;
4262
+ }
4119
4263
  };
4120
4264
  while (offset < source.length) {
4265
+ yield 1;
4121
4266
  if (source[offset] !== "<") {
4122
- const next = source.indexOf("<", offset);
4267
+ const next = yield* find(source, "<", offset);
4123
4268
  const text = source.slice(offset, next < 0 ? source.length : next);
4124
- if (text.includes("]]>")) invalid("CDATA terminator in text");
4125
- appendText(entities(text));
4269
+ if ((yield* find(text, "]]>", 0)) >= 0) invalid("CDATA terminator in text");
4270
+ yield* appendText(yield* entities(text));
4126
4271
  offset += text.length;
4127
4272
  } else if (source.startsWith("<!--", offset)) {
4128
- const end = source.indexOf("-->", offset + 4);
4129
- if (end < 0 || source.slice(offset + 4, end).includes("--") || source.slice(offset + 4, end).endsWith("-")) {
4273
+ const end = yield* find(source, "-->", offset + 4);
4274
+ if (end < 0 || (yield* find(source.slice(offset + 4, end), "--", 0)) >= 0 || source.slice(offset + 4, end).endsWith("-")) {
4130
4275
  invalid("malformed comment");
4131
4276
  }
4277
+ const parent = stack.at(-1);
4278
+ if (retainContent && parent) {
4279
+ admitContent();
4280
+ parent.content.push({ kind: "comment", text: source.slice(offset + 4, end) });
4281
+ }
4132
4282
  offset = end + 3;
4133
4283
  } else if (source.startsWith("<![CDATA[", offset)) {
4134
4284
  if (!stack.length) invalid("CDATA outside root");
4135
- const end = source.indexOf("]]>", offset + 9);
4285
+ const end = yield* find(source, "]]>", offset + 9);
4136
4286
  if (end < 0) invalid("unterminated CDATA");
4137
- appendText(source.slice(offset + 9, end));
4287
+ yield* appendText(source.slice(offset + 9, end), "cdata");
4138
4288
  offset = end + 3;
4139
4289
  } else if (source.startsWith("<?", offset)) {
4140
4290
  const start = offset;
4141
4291
  offset += 2;
4142
- const target = readName();
4143
- const end = source.indexOf("?>", offset);
4292
+ const target = yield* readName();
4293
+ const end = yield* find(source, "?>", offset);
4144
4294
  if (end < 0) invalid("unterminated processing instruction");
4145
4295
  const content = source.slice(offset, end);
4146
- if (target.toLowerCase() === "xml") {
4147
- if (start !== 0 || target !== "xml" || !/^\s+version\s*=\s*(['"])1\.0\1(?:\s+encoding\s*=\s*(['"])(?:UTF-8|UTF-16|UTF-16LE|UTF-16BE)\2)?(?:\s+standalone\s*=\s*(['"])(?:yes|no)\3)?\s*$/i.test(content)) {
4296
+ if (target.length === 3 && target.toLowerCase() === "xml") {
4297
+ if (start !== 0 || target !== "xml" || !(yield* validDeclaration(content, limits.expectedEncoding))) {
4148
4298
  invalid("unsupported XML declaration");
4149
4299
  }
4300
+ if (retainContent) declaration = source.slice(start, end + 2);
4150
4301
  } else if (content && !" \n\r".includes(content[0])) invalid("invalid processing instruction");
4302
+ if (!(target.length === 3 && target.toLowerCase() === "xml")) {
4303
+ const parent = stack.at(-1);
4304
+ if (retainContent && parent) {
4305
+ let start2 = 0;
4306
+ while (start2 < content.length && " \n\r".includes(content[start2])) {
4307
+ start2++;
4308
+ if (start2 % 512 === 0) yield 512;
4309
+ }
4310
+ if (start2 % 512) yield start2 % 512;
4311
+ admitContent();
4312
+ parent.content.push({ kind: "processing-instruction", target, text: content.slice(start2) });
4313
+ }
4314
+ }
4151
4315
  offset = end + 2;
4152
4316
  } else if (source.startsWith("<!", offset)) {
4153
4317
  invalid("DTD and entity declarations are forbidden");
4154
4318
  } else if (source.startsWith("</", offset)) {
4155
4319
  offset += 2;
4156
- const name = readName();
4157
- whitespace();
4320
+ const name = yield* readName();
4321
+ yield* whitespace();
4158
4322
  if (source[offset++] !== ">" || stack.pop()?.name !== name) invalid("mismatched closing tag");
4159
4323
  } else {
4160
4324
  offset++;
4161
- const name = readName();
4325
+ const name = yield* readName();
4162
4326
  const attributes = /* @__PURE__ */ new Map();
4163
- const namespaces = new Map(stack.at(-1)?.namespaces ?? [["xml", xmlNamespace]]);
4327
+ let namespaces = stack.at(-1)?.namespaces ?? /* @__PURE__ */ new Map([["xml", xmlNamespace]]);
4328
+ let ownsNamespaces = stack.length === 0;
4164
4329
  while (true) {
4165
4330
  const beforeSpace = offset;
4166
- whitespace();
4331
+ yield* whitespace();
4167
4332
  if (source[offset] === "/" || source[offset] === ">") break;
4168
4333
  if (offset === beforeSpace) invalid("attributes require whitespace");
4169
- const attribute = readName();
4334
+ const attribute = yield* readName();
4170
4335
  if (attributes.has(attribute)) invalid("duplicate attribute");
4171
- if (++attributeCount > maxAttributes || attributes.size >= 128) invalid("XML attribute limit exceeded");
4172
- whitespace();
4336
+ if (++attributeCount > maxAttributes) throw new XmlLimitError("maxAttributes", "XML attribute limit exceeded");
4337
+ if (attributes.size >= maxAttributesPerElement) throw new XmlLimitError("maxAttributesPerElement", "XML attribute limit exceeded");
4338
+ yield* whitespace();
4173
4339
  if (source[offset++] !== "=") invalid("missing attribute equals");
4174
- whitespace();
4340
+ yield* whitespace();
4175
4341
  const quote = source[offset++];
4176
4342
  if (quote !== '"' && quote !== "'") invalid("unquoted attribute");
4177
- const end = source.indexOf(quote, offset);
4343
+ const end = yield* find(source, quote, offset);
4178
4344
  if (end < 0) invalid("unterminated attribute");
4179
4345
  const raw = source.slice(offset, end);
4180
- if (raw.includes("<")) invalid("less-than in attribute");
4181
- const value = entities(raw.replace(/[\t\n\r]/g, " "));
4346
+ if ((yield* find(raw, "<", 0)) >= 0) invalid("less-than in attribute");
4347
+ let normalized = "";
4348
+ for (let index = 0; index < raw.length; index++) {
4349
+ const character = raw[index];
4350
+ normalized += character === " " || character === "\n" || character === "\r" ? " " : character;
4351
+ if ((index + 1) % 512 === 0) yield 512;
4352
+ }
4353
+ if (raw.length % 512) yield raw.length % 512;
4354
+ const value = yield* entities(normalized);
4182
4355
  attributes.set(attribute, value);
4183
4356
  offset = end + 1;
4184
4357
  if (attribute === "xmlns" || attribute.startsWith("xmlns:")) {
4185
4358
  const prefix2 = attribute === "xmlns" ? "" : attribute.slice(6);
4186
4359
  if (prefix2 === "xmlns" || value === xmlnsNamespace || prefix2 === "xml" !== (value === xmlNamespace) || prefix2 !== "" && value === "") invalid("invalid namespace binding");
4360
+ if (!ownsNamespaces) {
4361
+ const copy = /* @__PURE__ */ new Map();
4362
+ for (const [key, uri] of namespaces) {
4363
+ copy.set(key, uri);
4364
+ yield 1;
4365
+ }
4366
+ namespaces = copy;
4367
+ ownsNamespaces = true;
4368
+ }
4187
4369
  namespaces.set(prefix2, value);
4188
- if (namespaces.size > 256) invalid("XML namespace scope limit exceeded");
4370
+ if (namespaces.size > maxNamespaces) throw new XmlLimitError("maxNamespaces", "XML namespace scope limit exceeded");
4189
4371
  }
4190
4372
  }
4191
4373
  const expanded = /* @__PURE__ */ new Set();
4192
4374
  for (const attribute of attributes.keys()) {
4193
4375
  if (attribute === "xmlns" || attribute.startsWith("xmlns:")) continue;
4194
- const [prefix2, localName2] = qualifiedName(attribute);
4376
+ const [prefix2, localName2] = yield* qualifiedName(attribute);
4195
4377
  if (prefix2 && !namespaces.has(prefix2)) invalid("unbound attribute prefix");
4196
4378
  const key = JSON.stringify([prefix2 ? namespaces.get(prefix2) : "", localName2]);
4197
4379
  if (expanded.has(key)) invalid("duplicate expanded attribute");
4198
4380
  expanded.add(key);
4199
4381
  }
4200
- const [prefix, localName] = qualifiedName(name);
4382
+ const [prefix, localName] = yield* qualifiedName(name);
4201
4383
  if (prefix === "xmlns" || prefix && !namespaces.has(prefix)) invalid("unbound element prefix");
4202
- if (++nodes > maxNodes || stack.length + 1 > maxDepth) invalid("XML resource limit exceeded");
4384
+ if (++nodes > maxNodes) throw new XmlLimitError("maxNodes", "XML resource limit exceeded");
4385
+ if (stack.length + 1 > maxDepth) throw new XmlLimitError("maxDepth", "XML resource limit exceeded");
4203
4386
  const namespace = namespaces.get(prefix) ?? "";
4204
- if (limits.maxResponses !== void 0 && stack.length === 1 && root?.namespace === "DAV:" && root.localName === "multistatus" && namespace === "DAV:" && localName === "response" && ++responses2 > limits.maxResponses) {
4205
- throw new XmlResponseLimitError("WebDAV XML response limit exceeded");
4387
+ limits.onElement?.({ name, namespace, localName }, stack.at(-1)?.element, stack.length + 1);
4388
+ admitContent();
4389
+ const retainedAttributes = [];
4390
+ for (const [attribute, value] of retainContent ? attributes : []) {
4391
+ const [prefix2, localName2] = yield* qualifiedName(attribute);
4392
+ admitContent();
4393
+ retainedAttributes.push({
4394
+ name: attribute,
4395
+ localName: localName2,
4396
+ namespace: attribute === "xmlns" || prefix2 === "xmlns" ? xmlnsNamespace : prefix2 ? namespaces.get(prefix2) : "",
4397
+ value
4398
+ });
4399
+ yield 1;
4206
4400
  }
4207
- const element = { namespace, localName, children: [], text: "" };
4401
+ const content = retainContent ? [] : void 0;
4402
+ const element = { kind: "element", name, namespace, localName, children: [], text: "", content: content ?? emptyContent, attributes: retainContent ? retainedAttributes : emptyAttributes, namespaces: retainContent ? namespaces : emptyNamespaces, ...root === void 0 && declaration !== void 0 ? { declaration } : {} };
4208
4403
  const parent = stack.at(-1);
4209
- if (parent) parent.element.children.push(element);
4210
- else if (root) invalid("multiple root elements");
4404
+ if (parent) {
4405
+ parent.element.children.push(element);
4406
+ parent.content?.push(element);
4407
+ } else if (root) invalid("multiple root elements");
4211
4408
  else root = element;
4212
4409
  const empty = source[offset] === "/";
4213
4410
  if (empty) offset++;
4214
4411
  if (source[offset++] !== ">") invalid("unterminated start tag");
4215
- if (!empty) stack.push({ element, name, namespaces });
4412
+ if (!empty) stack.push({ element, content, name, namespaces });
4216
4413
  }
4217
4414
  }
4218
4415
  if (stack.length || !root) invalid("incomplete document");
4219
4416
  return root;
4220
4417
  }
4418
+ function parseXml(input, limits = {}) {
4419
+ const parser = parseXmlSteps(input, limits);
4420
+ let result = parser.next();
4421
+ while (!result.done) result = parser.next();
4422
+ return result.value;
4423
+ }
4424
+
4425
+ // packages/safe-fs/src/fs/webdav/xml.ts
4426
+ var XmlResponseLimitError = class extends SyntaxError {
4427
+ };
4428
+ function invalid2(message) {
4429
+ throw new SyntaxError(`Invalid WebDAV XML: ${message}`);
4430
+ }
4431
+ function parseXml2(input, limits = {}) {
4432
+ const { maxResponses, ...documentLimits } = limits;
4433
+ if (maxResponses !== void 0 && (!Number.isSafeInteger(maxResponses) || maxResponses < 1)) {
4434
+ throw new RangeError("XML limits must be positive integers");
4435
+ }
4436
+ let responses2 = 0;
4437
+ try {
4438
+ return parseXml(input, {
4439
+ ...documentLimits,
4440
+ retainContent: false,
4441
+ onElement(element, parent, depth) {
4442
+ if (maxResponses !== void 0 && depth === 2 && parent?.namespace === "DAV:" && parent.localName === "multistatus" && element.namespace === "DAV:" && element.localName === "response" && ++responses2 > maxResponses) {
4443
+ throw new XmlResponseLimitError("WebDAV XML response limit exceeded");
4444
+ }
4445
+ }
4446
+ });
4447
+ } catch (error) {
4448
+ if (error instanceof XmlLimitError) invalid2(error.message);
4449
+ if (error instanceof SyntaxError && error.message.startsWith("Invalid XML:")) {
4450
+ error.message = error.message.replace("Invalid XML:", "Invalid WebDAV XML:");
4451
+ }
4452
+ throw error;
4453
+ }
4454
+ }
4221
4455
  function davChildren(element, localName) {
4222
4456
  return element.children.filter((child) => child.namespace === "DAV:" && child.localName === localName);
4223
4457
  }
4224
4458
  function davChild(element, localName) {
4225
4459
  const children = davChildren(element, localName);
4226
- if (children.length > 1) invalid(`duplicate DAV:${localName}`);
4460
+ if (children.length > 1) invalid2(`duplicate DAV:${localName}`);
4227
4461
  return children[0];
4228
4462
  }
4229
4463
  function scalar(element) {
4230
- if (element.children.length) invalid("expected text-only element");
4464
+ if (element.children.length) invalid2("expected text-only element");
4231
4465
  return element.text.trim();
4232
4466
  }
4233
4467
 
@@ -4711,7 +4945,7 @@ var WebDavFileSystem = class {
4711
4945
  async xml(response, signal, maxResponses) {
4712
4946
  const data = await this.bytes(response, this.maxXmlBytes, signal);
4713
4947
  const encoding = data[0] === 255 && data[1] === 254 || data[0] === 60 && data[1] === 0 ? "utf-16le" : data[0] === 254 && data[1] === 255 || data[0] === 0 && data[1] === 60 ? "utf-16be" : "utf-8";
4714
- return parseXml(new TextDecoder(encoding, { fatal: true }).decode(data), maxResponses === void 0 ? void 0 : { maxResponses });
4948
+ return parseXml2(new TextDecoder(encoding, { fatal: true }).decode(data), maxResponses === void 0 ? void 0 : { maxResponses });
4715
4949
  }
4716
4950
  async multistatus(response, signal, method = "PROPFIND", path = "") {
4717
4951
  const link = response.headers.get("link");
@@ -6037,7 +6271,10 @@ export {
6037
6271
  FileSystemQuotaError,
6038
6272
  withFileSystemQuota,
6039
6273
  scopeFileSystem,
6274
+ XmlLimitError,
6275
+ parseXmlSteps,
6276
+ parseXml,
6040
6277
  WebDavFileSystem,
6041
6278
  createFsBridge
6042
6279
  };
6043
- //# sourceMappingURL=chunk-QK4IEGRO.js.map
6280
+ //# sourceMappingURL=chunk-CRKYNANF.js.map