@blamejs/pki 0.6.14 → 0.6.16

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 (112) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/lib/acme.js +59 -815
  3. package/lib/asn1-der.js +7 -245
  4. package/lib/attrcert-sign.js +12 -260
  5. package/lib/attrcert-verify.js +1 -7
  6. package/lib/byte-reader.js +0 -8
  7. package/lib/byte-writer.js +0 -11
  8. package/lib/cbor-det.js +0 -54
  9. package/lib/cmc-build.js +15 -357
  10. package/lib/cmc-verify.js +6 -239
  11. package/lib/cmp-build.js +41 -317
  12. package/lib/cmp-session.js +73 -760
  13. package/lib/cmp-verify.js +32 -488
  14. package/lib/cms-compress.js +3 -32
  15. package/lib/cms-decrypt.js +29 -294
  16. package/lib/cms-encrypt.js +14 -234
  17. package/lib/cms-sign.js +29 -324
  18. package/lib/cms-verify.js +9 -500
  19. package/lib/composite-kem.js +2 -102
  20. package/lib/composite-sig.js +1 -77
  21. package/lib/constants.js +0 -249
  22. package/lib/crl-sign.js +9 -237
  23. package/lib/crl-verify.js +1 -10
  24. package/lib/crmf-sign.js +19 -198
  25. package/lib/crmf-verify.js +1 -12
  26. package/lib/csr-sign.js +3 -34
  27. package/lib/csr-verify.js +1 -12
  28. package/lib/ct.js +28 -253
  29. package/lib/edwards-point.js +10 -44
  30. package/lib/est.js +28 -764
  31. package/lib/framework-error.js +4 -182
  32. package/lib/guard-all.js +1 -58
  33. package/lib/guard-async.js +1 -36
  34. package/lib/guard-bytes.js +6 -650
  35. package/lib/guard-compress.js +5 -102
  36. package/lib/guard-crypto.js +1 -40
  37. package/lib/guard-der.js +2 -93
  38. package/lib/guard-encoding.js +2 -60
  39. package/lib/guard-header.js +1 -36
  40. package/lib/guard-identifier.js +7 -531
  41. package/lib/guard-intrinsic.js +1 -150
  42. package/lib/guard-json.js +10 -73
  43. package/lib/guard-limits.js +1 -77
  44. package/lib/guard-list.js +1 -49
  45. package/lib/guard-name.js +3 -209
  46. package/lib/guard-parsed.js +7 -335
  47. package/lib/guard-range.js +1 -71
  48. package/lib/guard-secret.js +1 -102
  49. package/lib/guard-text.js +1 -64
  50. package/lib/guard-time.js +1 -97
  51. package/lib/hpke.js +3 -105
  52. package/lib/http-digest.js +14 -142
  53. package/lib/http-retry-after.js +1 -47
  54. package/lib/http-transport.js +21 -131
  55. package/lib/inspect.js +30 -284
  56. package/lib/ip-utils.js +6 -47
  57. package/lib/jose.js +7 -142
  58. package/lib/key.js +2 -67
  59. package/lib/lint.js +9 -194
  60. package/lib/merkle.js +1 -27
  61. package/lib/mime.js +9 -82
  62. package/lib/ocsp-request-verify.js +1 -14
  63. package/lib/ocsp-verify.js +1 -82
  64. package/lib/ocsp.js +11 -169
  65. package/lib/oid.js +5 -337
  66. package/lib/path-validate.js +103 -1492
  67. package/lib/pbes2.js +2 -89
  68. package/lib/pkcs12-build.js +31 -379
  69. package/lib/pki-build.js +64 -290
  70. package/lib/rc2.js +2 -18
  71. package/lib/rfc3339.js +4 -27
  72. package/lib/scep.js +140 -286
  73. package/lib/schema-all.js +0 -122
  74. package/lib/schema-attrcert.js +4 -146
  75. package/lib/schema-c509.js +153 -802
  76. package/lib/schema-cmc.js +5 -220
  77. package/lib/schema-cmp.js +2 -223
  78. package/lib/schema-cms.js +13 -427
  79. package/lib/schema-crl.js +5 -68
  80. package/lib/schema-crmf.js +6 -167
  81. package/lib/schema-csr.js +1 -54
  82. package/lib/schema-csrattrs.js +2 -87
  83. package/lib/schema-engine.js +0 -152
  84. package/lib/schema-ocsp.js +0 -117
  85. package/lib/schema-pkcs12.js +2 -93
  86. package/lib/schema-pkcs8.js +3 -35
  87. package/lib/schema-pkix.js +24 -655
  88. package/lib/schema-smime.js +0 -54
  89. package/lib/schema-tsp.js +3 -99
  90. package/lib/schema-x509.js +4 -63
  91. package/lib/shbs.js +11 -95
  92. package/lib/sign-scheme.js +2 -97
  93. package/lib/sigstore.js +9 -169
  94. package/lib/sleep.js +2 -8
  95. package/lib/smime.js +15 -408
  96. package/lib/tls-cert-compress.js +0 -62
  97. package/lib/trust.js +19 -185
  98. package/lib/tsp-sign.js +16 -270
  99. package/lib/validator-all.js +1 -30
  100. package/lib/validator-attcert.js +2 -46
  101. package/lib/validator-cose.js +2 -153
  102. package/lib/validator-keydesc.js +1 -37
  103. package/lib/validator-sig.js +1 -46
  104. package/lib/validator-tls.js +1 -88
  105. package/lib/validator-tpm.js +19 -122
  106. package/lib/verify-seam.js +1 -24
  107. package/lib/webauthn-mds.js +3 -400
  108. package/lib/webauthn.js +12 -833
  109. package/lib/webcrypto.js +5 -485
  110. package/lib/x509-sign.js +4 -108
  111. package/package.json +1 -1
  112. package/sbom.cdx.json +6 -6
@@ -3,40 +3,8 @@
3
3
  "use strict";
4
4
  var intrinsic = require("./guard-intrinsic");
5
5
  var util = { types: intrinsic.types };
6
- //
7
- // @internal -- no operator-facing namespace. The documented surface is the
8
- // consumers whose identifier-string integrity composes this guard (pki.oid
9
- // name/arc resolution, pki.asn1 OID encoding, pki.path.validate requiredEku /
10
- // userInitialPolicySet key checking).
11
- //
12
- // guard-identifier -- fail-closed canonicalization of the structured-identifier
13
- // STRINGS the toolkit compares and encodes. An identifier used as a lookup /
14
- // comparison key must be in one canonical form, or the string form and the
15
- // decoded form of the same identifier silently disagree.
16
- //
17
- // Defends the canonicalization-divergence class (CWE-20): a dotted-decimal OID
18
- // with a leading-zero arc ("2.05.29.15") round-trips to a DIFFERENT OID
19
- // ("2.5.29.15"), and an arc outside the X.660 bounds can never DER-encode at all.
20
- // A hand-rolled string check that accepts either lets `build.oid` emit bytes that
21
- // decode to a different OID than the string names, or lets a non-canonical policy /
22
- // EKU key compare unequal to the canonical decoder output it is matched against (a
23
- // silent false-reject). Every string-form identifier check routes through here so
24
- // the string and DER forms cannot diverge.
6
+ // @internal
25
7
 
26
- // Everything this module reads from the runtime, taken at load. `util.types` above is the slot
27
- // predicate set, which answers whether a value is a Proxy -- the question that decides whether an
28
- // options bag can be asked honestly what it holds at all.
29
- //
30
- // The array test decides whether a value is walked as a list, so one answering `false` makes the
31
- // index scan report nothing and every index rule keyed on that scan applies to nothing, which is
32
- // how an accessor under index 0 reaches a copy loop the refusal should have turned the call away
33
- // for. The reflective operations are this module's honesty walk itself: `getOwnPropertyDescriptor`
34
- // learns whether a field is an accessor, `getPrototypeOf` and `ownKeys` walk a chain, and a
35
- // replacement for either lets an options bag report one shape while answering as another. The array
36
- // and collection operations run on lists and sets this module owns, where `Array.prototype` and
37
- // `Set.prototype` are what a caller can still reach: a `forEach` replaced with a no-op makes the
38
- // name scan report nothing over perfectly real keys, and a `has` answering `true` ends a chain walk
39
- // at the first prototype. See guard-intrinsic for the whole captured set.
40
8
  var _isArray = intrinsic.isArray;
41
9
  var _create = intrinsic.create;
42
10
  var _getPrototypeOf = intrinsic.getPrototypeOf;
@@ -64,65 +32,33 @@ var _Set = intrinsic.Set;
64
32
  var _Map = intrinsic.Map;
65
33
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
66
34
  var _strSplit = intrinsic.uncurry(String.prototype.split);
67
- // This module's whole job is deciding whether a caller's name is in a known set, and that decision
68
- // is one `hasOwnProperty` call. Reading it and its `call` off their prototypes leaves the answer
69
- // with whoever replaced either, which classifies an unknown option as an allowed one.
70
35
  var _hasOwn = intrinsic.hasOwn;
71
- // The index test below IS `String(Number(k)) === k`, and the readable-index scan orders and bounds
72
- // its results with the same two conversions. Both are writable properties of globalThis: one
73
- // replacement decides which own names this module reports as elements, in what order, and where the
74
- // scan stops -- which is what every consumer's density and accessor refusal is built on.
75
36
  var _String = intrinsic.String;
76
37
  var _Number = intrinsic.Number;
77
38
  var _BigInt = intrinsic.BigInt;
78
39
  var _Object = intrinsic.Object;
79
40
  var _BufferProto = intrinsic.BufferProto;
80
- // Appended by index rather than through `push`, so the growth reads no prototype method at all.
81
41
  function _append(arr, v) { _defineProperty(arr, arr.length, { value: v, writable: true, enumerable: true, configurable: true }); }
82
42
 
83
- // The dotted-decimal grammar, walked instead of matched. `(0|[1-9]\d*)(\.(0|[1-9]\d*))+`
84
- // nests a quantified group inside a quantified group with an alternation in each,
85
- // which is the shape whose cost on a rejecting string is a property of the pattern
86
- // and not of the length, and this guard's whole job is to be handed strings that
87
- // reject. Walking the string is one pass, one comparison per character, and it
88
- // states the two rules plainly: an arc is one or more digits, and an arc longer than
89
- // one digit does not start with zero (the leading-zero form round-trips to a
90
- // DIFFERENT OID, which is the divergence this guard exists to stop).
91
43
  function _isDottedDecimal(str) {
92
44
  if (str.length === 0) return false;
93
45
  var arcs = 0, digits = 0, leadingZero = false;
94
46
  for (var i = 0; i < str.length; i++) {
95
47
  var c = _charCodeAt(str, i);
96
- if (c === 0x2e) { // "."
97
- if (digits === 0 || leadingZero) return false; // empty arc, or "01"
48
+ if (c === 0x2e) {
49
+ if (digits === 0 || leadingZero) return false;
98
50
  arcs++; digits = 0; leadingZero = false;
99
51
  continue;
100
52
  }
101
- if (c < 0x30 || c > 0x39) return false; // not a digit
53
+ if (c < 0x30 || c > 0x39) return false;
102
54
  if (digits === 1 && _charCodeAt(str, i - 1) === 0x30) leadingZero = true;
103
55
  digits++;
104
56
  }
105
- if (digits === 0 || leadingZero) return false; // trailing "." or a final "01"
106
- return arcs >= 1; // two or more arcs
57
+ if (digits === 0 || leadingZero) return false;
58
+ return arcs >= 1;
107
59
  }
108
60
 
109
- // assertCanonicalOid(str, E, code, label, boundsCode) -> str | throws
110
- // A canonical dotted-decimal object identifier string: two or more arcs, each a
111
- // non-negative decimal integer with no leading zero (the syntax), and, unless
112
- // bounds are waived, the root arc 0..2 with the second arc 0..39 under roots 0
113
- // and 1 (the X.660 encodability bounds: the first two arcs pack into a single
114
- // sub-identifier as 40*root+second). E is the (code, message) typed-error factory:
115
- // - a syntax fault always throws E(code, ...).
116
- // - boundsCode === null waives the arc-bound check, for a lookup key (oid.name
117
- // / oid.has), where a well-formed but non-encodable OID is simply not
118
- // registered (a miss) and not an error.
119
- // - otherwise an out-of-range arc throws E(boundsCode, ...) (boundsCode defaults
120
- // to code), so a caller distinguishing the two reasons (oid.js: oid/bad-input
121
- // syntax vs oid/bad-arc bounds) keeps both codes.
122
61
  // @enforced-by behavioral -- string-form OID canonicalization has no rename-proof
123
- // code shape distinct from the arc-based bounds check oid.js legitimately keeps
124
- // for the arc path; the divergence RED vectors (build.oid / oid.toArcs / requiredEku
125
- // reject a non-canonical OID) driving the composing consumers are the guard.
126
62
  function assertCanonicalOid(str, E, code, label, boundsCode) {
127
63
  var who = label || "OID";
128
64
  if (typeof str !== "string" || !_isDottedDecimal(str)) {
@@ -130,13 +66,7 @@ function assertCanonicalOid(str, E, code, label, boundsCode) {
130
66
  }
131
67
  if (boundsCode === null) return str;
132
68
  var bcode = boundsCode === undefined ? code : boundsCode;
133
- // The arc bound below is a bound on THESE parts, so the split that produces them settles it. One
134
- // returning different pieces has the check read a first and second arc the identifier does not
135
- // carry, and an out-of-range OID passes a range test performed on other numbers.
136
69
  var parts = _strSplit(str, ".");
137
- // Captured: these two arcs are what the bound below is a bound ON, and `BigInt` is a writable
138
- // property of globalThis, so a replacement returns whatever it likes for the arcs and the range
139
- // test is then performed on numbers the identifier does not carry.
140
70
  var root = _BigInt(parts[0]);
141
71
  var second = _BigInt(parts[1]);
142
72
  if (root > 2n) throw E(bcode, who + " root arc must be 0, 1, or 2 (X.660)");
@@ -144,63 +74,18 @@ function assertCanonicalOid(str, E, code, label, boundsCode) {
144
74
  return str;
145
75
  }
146
76
 
147
- // assertKnownKeys(obj, known, E, code, label): every own key of `obj` must appear in `known`.
148
- //
149
- // The shape this replaces was hand-written in a dozen callers, and it is worth one home because
150
- // getting it wrong fails open in the quietest possible way: an options object whose key is
151
- // misspelled silently carries the default, so a caller who asked for a stricter check gets the
152
- // looser behavior and no error. Two details are easy to lose in a re-inline and are fixed here.
153
- // `known` is consulted with hasOwnProperty and not a truthiness test, so an inherited Object
154
- // member ("constructor", "toString") cannot read as a recognized key; and the walk is over own
155
- // enumerable keys, so a `__proto__` arriving from JSON is inspected instead of skipped.
156
- //
157
77
  // @enforced-by behavioral -- an options-shape walk has no rename-proof code shape; the RED vectors
158
- // (an unknown key, an inherited name, a JSON-borne __proto__) are the guard.
159
- //
160
- // `message` is the caller's own wording, so routing an existing check through this guard changes
161
- // what is checked, never what the operator reads: a string is the prefix the quoted key is appended
162
- // to, and a function (key) -> string builds the whole sentence, for the many callers that name the
163
- // key mid-sentence and follow it with the hint that says what to pass instead.
164
- //
165
- // `known` and `message` are the module's own, and `obj` is the only argument here that a caller
166
- // supplies. Questions asked of `obj` are typed, since a caller can answer them with a trap or a
167
- // getter that throws; questions asked of the other two are not, because a table or a wording that
168
- // throws is this toolkit's own wiring mistake. Handing either one a value off a caller would put
169
- // an untyped exception on a boundary that promises a typed one, so neither takes one.
170
- //
171
78
  // @enforced-by guard-shape-reinlined
172
- // The shape requires the throw: an identical walk whose body filters on the same table (copying the
173
- // recognized keys onward instead of rejecting the unrecognized ones) is a different operation with
174
- // no fail-open risk, and must not be dragged through a guard that only knows how to reject.
175
79
  // @guard-shape Object\.keys\(\w+(?:\.\w+)*\)\.forEach\(function \((\w+)\) \{\s*if \(![\w.]+\[\1\]\) (?:\{\s*)?throw
176
80
  function assertKnownKeys(obj, known, E, code, message) {
177
81
  _refuseUnenumerable(obj, E, code, "the options");
178
82
  var describe = typeof message === "function" ? message : function (k) { return message + _stringify(k); };
179
83
  _forEach(_readableNames(obj), function (k) {
180
84
  if (_hasOwn(known, k)) return;
181
- // A Symbol reaches the message as its description, before either form of `message` sees it.
182
- // JSON.stringify returns undefined for one, so a caller's own builder (which stringifies the
183
- // key itself) would name the refused option "undefined" and leave nothing to search for.
184
- // Normalizing here rather than in the default builder keeps both forms reading the same.
185
85
  throw E(code, describe(typeof k === "symbol" ? _String(k) : k));
186
86
  });
187
87
  }
188
88
 
189
- // What Object.prototype carries, per ECMA-262, written out rather than read from the runtime.
190
- //
191
- // Stopping the walk at Object.prototype excludes the whole object, so a runtime whose prototype
192
- // carries `Object.prototype.password = "pw"` answers `opts.password` on a plain `{}` and
193
- // `pki.key.export` hands back an unprotected key for a bag holding nothing. Naming the members
194
- // instead reports anything else there.
195
- //
196
- // Reading the names off the live Object.prototype at load looks equivalent and is not: it is the
197
- // runtime under attack answering the question, so a name planted before this module loads is
198
- // captured as a built-in and is thereafter invisible. The spec list holds whoever loaded first.
199
- // A guard-identifier test asserts it against the live object, so an engine that adds a member
200
- // fails there rather than silently reporting it to every caller as an unknown option.
201
- //
202
- // The residual is a planted function REPLACING one of these twelve. No verb reads `opts.toString`
203
- // as an option, so that smuggles nothing; it breaks the runtime at large, not this check.
204
89
  var _PRISTINE_OBJECT_PROTO = (function () {
205
90
  var s = _create(null);
206
91
  _forEach(["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString",
@@ -209,33 +94,10 @@ var _PRISTINE_OBJECT_PROTO = (function () {
209
94
  return s;
210
95
  })();
211
96
 
212
- // Is this descriptor shaped like a member of Object.prototype rather than a planted value? Every
213
- // real one is a data property holding a function, or the `__proto__` accessor. Nothing there is a
214
- // data property holding a string, a number or an object, so a planted `password: "pw"` fails this
215
- // test whatever the snapshot above says about its name.
216
97
  function _looksBuiltIn(d) {
217
98
  return !!d && (!!d.get || !!d.set || typeof d.value === "function");
218
99
  }
219
100
 
220
- // Can this object be asked honestly what it holds?
221
- //
222
- // A Proxy answers `ownKeys` and `get` from two independent traps, so the two need not agree. One
223
- // reporting no keys while its `get` returns "pw" for `password` presents an object that every
224
- // enumeration calls empty and every read calls populated. No walk can close that: the readable
225
- // names are whatever the trap decides at the moment it is asked, and asking again may differ.
226
- // So the enumeration is not made more thorough, the object is refused. That is the same rule
227
- // guard-bytes states for a value it cannot copy: there are two honest outcomes for a caller's
228
- // argument, and "read it and hope the enumeration was truthful" is not one of them.
229
- //
230
- // The check is by identity through `util.types.isProxy`, never by behavior. Probing traps to
231
- // catch a liar is a race a liar wins: it can answer consistently until the check is over.
232
- // The WHOLE chain, not the object. `obj.password` resolves through every prototype above it, so a
233
- // plain object inheriting from a lying Proxy answers the read while enumerating empty and is not
234
- // itself a Proxy. Testing only the object handed in leaves that one line of indirection open.
235
- // The error factory is validated before it is needed, for the same reason a guard taking a bound
236
- // validates the bound: the one moment it is called is the moment something has already gone
237
- // wrong, and a factory that is not one turns the refusal into a TypeError from inside the guard.
238
- // This is a caller's wiring mistake rather than untrusted input, so it throws plainly.
239
101
  function _requireFactory(E) {
240
102
  if (typeof E !== "function") {
241
103
  throw new TypeError("guard.identifier needs an error factory called as E(code, message); " +
@@ -255,18 +117,6 @@ function _refuseUnenumerable(v, E, code, label) {
255
117
  }
256
118
  }
257
119
 
258
- // Does the prototype chain above `from` supply `k` as a data property holding `fn`? That is what
259
- // makes `k` a method. Asking it by value identity is what makes the answer survive
260
- // guard.bytes.snapshotDeep.
261
- //
262
- // The snapshot copies every readable name onto the copy and keeps the prototype, so a class's
263
- // method arrives as an own property while the identical function is still reachable above it. A
264
- // rule that asks "is this name own?" therefore calls the same method an option on the copy and
265
- // behavior on the original, and every check running after a snapshot refuses an options bag that
266
- // is an instance of the caller's own class.
267
- //
268
- // The walk stops at an object already seen, since a prototype chain is finite only while it is
269
- // acyclic and a Proxy can make it otherwise. See the note on _readableNames.
270
120
  function _isMethodOf(from, k, fn) {
271
121
  var visited = new _Set();
272
122
  for (var o = from; o && !_setHas(visited, o); o = _getPrototypeOf(o)) {
@@ -278,92 +128,16 @@ function _isMethodOf(from, k, fn) {
278
128
  return false;
279
129
  }
280
130
 
281
- // Every name that can supply a value to a later `obj.foo`. `Object.keys` reports a subset of
282
- // those: own enumerable names only. Four ordinary object shapes answer the lookup while showing
283
- // that enumeration nothing. A value on the prototype (`_create({ password: "pw" })`). A
284
- // non-enumerable own value (`_defineProperty(o, "password", { enumerable: false })`). A
285
- // class getter, which class syntax also defines non-enumerable. And a polluted
286
- // `Object.prototype`. On each of them `pki.key.export` accepts the bag, ignores the password it
287
- // can read, and returns the private key in the clear, which is the case the refusal exists to
288
- // prevent.
289
- //
290
131
  // @enforced-by behavioral -- a property-surface walk has no rename-proof code shape. The RED
291
- // vectors are the guard, and they are the shapes that got past it in turn: a prototype data
292
- // property, a non-enumerable own property, a class getter, a polluted Object.prototype, and a
293
- // prototype method that must still be allowed through.
294
- //
295
- // So the walk covers the whole chain and skips one thing: a method, meaning a data property
296
- // holding a function that the chain above it also supplies under that name. A method is behavior
297
- // the bag's class defines. This repository has settled that an instance of a caller's own class
298
- // is a legitimate options bag, since guard.bytes.snapshotDeep copies one and keeps its prototype
299
- // so its methods resolve, and flagging them would reject calls that work today.
300
- //
301
- // Neither enumerability nor ownness decides that test. Each records how the name arrived, which
302
- // is a different question from what it means. Enumerability records how a method was written,
303
- // and the two ways differ: class syntax defines methods non-enumerable while `Proto.m = fn`
304
- // defines them enumerable, so a rule keyed on it accepts one style and rejects the other.
305
- // Ownness records whether the object has been through a snapshot, which flips the same method
306
- // from inherited to own, so a rule keyed on it calls that method behavior at one check site and
307
- // an unknown option at the next. Value identity against the chain above answers the same on both
308
- // sides, which is what lets a check sit before or after a snapshot and reach one verdict.
309
- //
310
- // An accessor is never a method, whichever way it was written. A getter exists to answer with a
311
- // value, which is exactly what an option does.
312
- //
313
- // One case is traded away, and it is written down here rather than left implicit. An unknown
314
- // option supplied as a method is not reported: its value would have to be a function, and the
315
- // prototype chain would have to supply that same function under that name. So `class Options {
316
- // typo() {} }` passes, and `opts.typo` does resolve. The function-valued options here
317
- // (revocationChecker, verifier, transport) are passed as own properties, so reaching the hole
318
- // needs a caller to misspell one AND define it as a method rather than assign it. That is the
319
- // price of keeping class instances usable, which this repository has settled, and it is the one
320
- // gap in "every name a later obj.foo can resolve is reported".
321
- // Is this string an array index, as the language defines one: an integer in [0, 2^32 - 2] whose
322
- // canonical decimal spelling is the string itself?
323
- //
324
- // `String(Number(k)) === k` looks like that test and is not. It also admits "-1", "1.5", "NaN",
325
- // "Infinity" and "4294967295" (one past the last index), every one of which is an ordinary named
326
- // property on an array rather than an element. Treating them as structure means an unknown option
327
- // under one of those names is passed over here and dropped by the copy in guard-bytes, so it
328
- // reaches neither the check nor the verb. A leading zero is excluded by the same comparison,
329
- // since "01" is a named property too.
330
132
  function _isArrayIndex(k) {
331
133
  var n = _Number(k);
332
134
  return _isInteger(n) && n >= 0 && n < 4294967295 && _String(n) === k;
333
135
  }
334
136
 
335
- // Is this value one whose own `length` and indices are structure rather than supplied names?
336
- //
337
- // The value itself, never anything it inherits from. An object merely sitting over an array is a
338
- // plain object: a `0` or a `length` of its own is a field its caller wrote, and reading the kind
339
- // off the chain suppressed exactly those. What such a bag inherits from the array beneath it is a
340
- // separate question, answered by the level test in the walk.
341
- //
342
- // A DataView is a byte view and is not one of these. It reads its bytes through methods and has no
343
- // integer-indexed elements and no `length`, so `dv.length = 9` and `dv[0] = "x"` are ordinary
344
- // properties that stay set and answer on a later read. Counting it as indexed drops both from the
345
- // names reported and from the copy the verb is handed.
346
137
  function _isIndexedKind(v) {
347
138
  return _isArray(v) || (_isView(v) && !util.types.isDataView(v));
348
139
  }
349
140
 
350
- // The names the built-in collection kinds define on their prototypes, written out rather than
351
- // read from the runtime, for the same reason the root's twelve are: reading a prototype to learn
352
- // what belongs on it asks the polluted object to vouch for itself.
353
- //
354
- // One set covering every kind, because a LEVEL is what gets read and a level's kind cannot be
355
- // established without asking a prototype who it is. `_create(Map.prototype)` holds no map
356
- // and inherits `size`; a foreign array's prototype is not this realm's. Both are answered by
357
- // asking whether the NAME is one a kind defines, which no realm and no lookalike changes.
358
- //
359
- // Being on the list is not enough on its own: the member also has to be shaped like one, so a
360
- // planted `Array.prototype.password` is reported while `Array.prototype.length` is not.
361
- // One list per prototype, holding exactly what THAT prototype defines. Sharing a list across
362
- // kinds that merely resemble each other exempts a name its holder never had, which is a caller's
363
- // option passed over in silence: a weak collection counts nothing and has no `size`, a
364
- // SharedArrayBuffer is `growable` where an ArrayBuffer is `resizable` and `detached`, a DataView
365
- // has no `length`, and `BYTES_PER_ELEMENT` belongs to a concrete typed array rather than the
366
- // prototype they share.
367
141
  var _ARRAY_PROTO_MEMBERS = ["length", Symbol.unscopables];
368
142
  var _REGEXP_PROTO_MEMBERS = ["source", "flags", "global", "ignoreCase", "multiline",
369
143
  "dotAll", "unicode", "unicodeSets", "sticky", "hasIndices"];
@@ -375,16 +149,8 @@ var _SHARED_PROTO_MEMBERS = ["byteLength", "maxByteLength", "growable", Symbol.t
375
149
  var _DATAVIEW_PROTO_MEMBERS = ["buffer", "byteLength", "byteOffset", Symbol.toStringTag];
376
150
  var _TYPED_PROTO_MEMBERS = ["buffer", "byteLength", "byteOffset", "length", Symbol.toStringTag];
377
151
  var _CONCRETE_TYPED_MEMBERS = ["BYTES_PER_ELEMENT"];
378
- // Node puts these two on Buffer.prototype, beneath the ECMAScript typed-array prototype.
379
152
  var _BUFFER_PROTO_MEMBERS = ["parent", "offset"];
380
153
 
381
- // What a whole kind carries, as against what one prototype defines. This is what answers for a
382
- // value whose chain holds no prototype of this realm, where the level cannot be recognized and
383
- // the kind read from the value's own slot is all there is.
384
- // A kind carries what its own prototypes hold and nothing a neighboring kind holds. Answering a
385
- // buffer with both buffer kinds' members exempts `growable` on an ArrayBuffer and `detached` on a
386
- // SharedArrayBuffer, neither of which the language defines there, so a caller's getter under
387
- // either name is passed over.
388
154
  var _ARRAY_MEMBERS = _ARRAY_PROTO_MEMBERS;
389
155
  var _REGEXP_MEMBERS = ["lastIndex"].concat(_REGEXP_PROTO_MEMBERS);
390
156
  var _VIEW_MEMBERS = _TYPED_PROTO_MEMBERS.concat(_CONCRETE_TYPED_MEMBERS);
@@ -393,27 +159,6 @@ var _DATAVIEW_MEMBERS = _DATAVIEW_PROTO_MEMBERS;
393
159
  var _ARRAYBUFFER_MEMBERS = _ARRAYBUFFER_PROTO_MEMBERS;
394
160
  var _SHARED_MEMBERS = _SHARED_PROTO_MEMBERS;
395
161
 
396
- // Which of those a value carries, taken from its internal slot.
397
- //
398
- // The value's own kind, not the union, because a name belongs to a kind and a caller's accessor
399
- // can borrow one that a different kind defines. `class Opts extends Array { get buffer() {} }` is
400
- // an array, `buffer` is a byte view's member and not an array's, so that getter is the caller's
401
- // option and gets reported.
402
- //
403
- // A value with no collection slot answers with nothing. `_create(Map.prototype)` holds no
404
- // map and still inherits `size`, and that is settled by the level test in the walk, which reads
405
- // the members off the prototype the name was found on.
406
- // The prototypes this realm installs a kind's members on. A level that IS one carries the
407
- // language's members whatever the value in front of it turns out to be, which is how
408
- // `_create(Map.prototype)` keeps `size` while holding no map.
409
- //
410
- // Typed arrays are recognized through the prototype they all share rather than by naming each
411
- // constructor, so a kind the list never mentioned is covered: `Float16Array` arrived on Node 24
412
- // and an enumeration would have gone on reporting its `BYTES_PER_ELEMENT` as a caller's option.
413
- // Each one paired with the members IT defines, never the union of every kind's. A level carries
414
- // only its own: `size` on `Array.prototype` is nothing the language put there, so exempting it
415
- // because some other kind has a member by that name hands back the hole this walk exists to
416
- // close, for anyone who plants it in a shape that reads as built-in.
417
162
  var _TYPED_ARRAY_PROTO = _getPrototypeOf(Uint8Array.prototype);
418
163
  var _INTRINSIC_HOLDERS = (function () {
419
164
  var m = new _Map([[_TYPED_ARRAY_PROTO, _TYPED_PROTO_MEMBERS]]);
@@ -426,19 +171,6 @@ var _INTRINSIC_HOLDERS = (function () {
426
171
  pair(typeof SharedArrayBuffer === "function" ? SharedArrayBuffer : null, _SHARED_PROTO_MEMBERS);
427
172
  pair(DataView, _DATAVIEW_PROTO_MEMBERS);
428
173
  pair(Buffer, _BUFFER_PROTO_MEMBERS);
429
- // Every concrete typed-array kind the runtime actually provides, found by asking it rather than
430
- // by naming them, so a kind added later is covered the day it lands -- Float16Array was.
431
- //
432
- // Registered as identities. Recognizing them by their PARENT instead admitted anything a caller
433
- // built over `%TypedArray%.prototype`, and a bag inheriting `BYTES_PER_ELEMENT` from such an
434
- // object then read as an intrinsic member rather than as the unknown option it was.
435
- //
436
- // Read the DESCRIPTOR, never the value through the runtime. `globalThis[n]` invokes a getter, and a
437
- // host may define one that warns on read -- Node exposes `localStorage` and `WASI` as lazy accessors
438
- // that emit an ExperimentalWarning the moment they are touched, so a plain read here printed that
439
- // warning on every import -- or one that throws. A typed-array constructor is a plain data property, so
440
- // taking `d.value` finds every concrete kind without ever invoking an accessor, which also means such
441
- // an accessor can neither warn nor fault this load over a name it does not need.
442
174
  _forEach(_getOwnPropertyNames(globalThis), function (n) {
443
175
  var d = _getOwnPropertyDescriptor(globalThis, n);
444
176
  if (!d || typeof d.value !== "function") return;
@@ -450,22 +182,10 @@ var _INTRINSIC_HOLDERS = (function () {
450
182
  return m;
451
183
  })();
452
184
 
453
- // The members a chain level defines, or null where the level is not one the language installs
454
- // members on. Membership is by identity: every prototype the language installs members on is in
455
- // the table above, the concrete typed-array ones included, so an object that merely sits over one
456
- // of them is a caller's and its names are theirs.
457
185
  function _holderMembers(o) {
458
186
  return _mapHas(_INTRINSIC_HOLDERS, o) ? _mapGet(_INTRINSIC_HOLDERS, o) : null;
459
187
  }
460
188
 
461
- // Is this one of Node's Buffers? A byte view whose chain reaches `Buffer.prototype`, asked by
462
- // walking it rather than through `Buffer.isBuffer`.
463
- //
464
- // `Buffer.isBuffer` is an `instanceof`, and `Buffer` is an ordinary extensible function, so
465
- // defining `Buffer[Symbol.hasInstance]` on it hands the answer to whoever did. That is the same
466
- // pollution this walk exists to survive on `Object.prototype` and `Array.prototype`, and it can
467
- // throw as well as lie: a caller's argument then leaves a door whose contract is a typed error
468
- // carrying somebody else's exception. A prototype identity is not writable from outside.
469
189
  function _isNodeBuffer(v) {
470
190
  if (!util.types.isUint8Array(v)) return false;
471
191
  var visited = new _Set();
@@ -477,9 +197,6 @@ function _isNodeBuffer(v) {
477
197
  }
478
198
 
479
199
  function _kindMembers(v) {
480
- // The value's own slot, never a kind it merely inherits from. Whatever a real intrinsic
481
- // prototype in the chain supplies is handled by the level test at the walk; a name that only
482
- // looks like a member, on a class of the caller's, is the option they wrote.
483
200
  if (v === null || v === undefined) return [];
484
201
  if (_isArray(v)) return _ARRAY_MEMBERS;
485
202
  if (_isNodeBuffer(v)) return _BUFFER_KIND_MEMBERS;
@@ -493,36 +210,15 @@ function _kindMembers(v) {
493
210
  return [];
494
211
  }
495
212
 
496
- // The names a kind puts on the value itself rather than on its prototype, which are structure the
497
- // same way an array's `length` is: `opts.lastIndex` on a RegExp answers with the match position
498
- // whatever a caller meant by it, so no option can be supplied under that name.
499
213
  function _isOwnStructuralName(v, k) {
500
214
  return util.types.isRegExp(v) && k === "lastIndex";
501
215
  }
502
216
 
503
- // The shape a member the language put there has, and a planted one does not: an accessor, a
504
- // function, or a data property the language pinned. `Symbol.toStringTag` and `BYTES_PER_ELEMENT`
505
- // are non-writable; `Array.prototype.length` is writable and non-configurable. A name added by
506
- // assignment or by an ordinary defineProperty is neither, so it stays reported.
507
217
  function _looksIntrinsic(d) {
508
218
  return !!d && (!!d.get || !!d.set || typeof d.value === "function" ||
509
219
  d.writable === false || d.configurable === false);
510
220
  }
511
221
 
512
- // The member descriptors this realm's collection prototypes actually carry, taken at load and
513
- // keyed by the accessor or value they hold.
514
- //
515
- // The name and the shape together are not enough on their own: a caller's class can extend a
516
- // collection and define one of its own members over the top, and
517
- // `class Opts extends Map { get size() {} }` is then an accessor named `size` on a value that is
518
- // a Map. What tells the two apart is where the name sits, and that answers in any realm: the
519
- // language installs a member once, so an intrinsic one is the only level of the chain carrying
520
- // that name, while an override shadows the intrinsic still sitting above it. A name found twice
521
- // is a caller's.
522
- //
523
- // Reading it that way also settles a kind this list would have to be extended for. `Float16Array`
524
- // is on Node 24 and was not among the constructors named here, and the moment a typed array of an
525
- // unlisted kind arrived its `BYTES_PER_ELEMENT` read as an option its caller never wrote.
526
222
  function _shadowsAnother(v, k, holder) {
527
223
  var visited = new _Set();
528
224
  var past = false;
@@ -537,100 +233,30 @@ function _shadowsAnother(v, k, holder) {
537
233
  function _readableNames(obj) {
538
234
  var seen = _create(null);
539
235
  var out = [];
540
- // A primitive supplies no option names, and `Reflect.ownKeys` refuses one outright. The walk
541
- // starts above it rather than on it, so a caller who hands a number or a string where an
542
- // options bag belongs gets their own verb's refusal for the wrong type from the door that
543
- // checks types, instead of a raw TypeError from in here about a reflection method they never
544
- // called. `null` and `undefined` have no chain at all and stop immediately.
545
- // Boxed through the captured `Object`. This decides which names the scan below then examines, so
546
- // a replacement wraps a primitive as an object of its own choosing and the guard reads a name set
547
- // and a prototype chain the caller supplied rather than the value's.
548
236
  var o = (obj === null || obj === undefined) ? null : _Object(obj);
549
- // Whether the value's own `length` and indices are structure. That is true of an array and a
550
- // byte view and of nothing else: a Map, a Set and an ArrayBuffer have no own `length`, so
551
- // skipping the name there would discard one the caller had put on themselves.
552
- //
553
- // A verb reads an option by name whatever the argument's type, and `opts = []; opts.pem = true`
554
- // is an options bag as far as `opts.pem` is concerned, so these kinds have to work. Their
555
- // prototypes carry names the caller did not supply, and the per-level test below is what
556
- // handles those. Refusing to read the chain at all leaves a bag whose chain holds nothing
557
- // intrinsic unread.
558
237
  var indexedSelf = _isIndexedKind(o);
559
238
  var members = _kindMembers(o);
560
- // A prototype chain is finite only while it is acyclic, and a Proxy can make it otherwise.
561
- // While its target stays extensible a `getPrototypeOf` trap may return the proxy itself. The
562
- // walk therefore stops at an object it has already visited. A second lap over the same objects
563
- // yields no name the first did not, so the reported names stay complete. Without the test a
564
- // caller's argument hangs the verb before a single option has been read.
565
239
  var visited = new _Set();
566
240
  while (o && !_setHas(visited, o)) {
567
241
  _setAdd(visited, o);
568
242
  var inherited = (o !== obj);
569
243
  var above = _getPrototypeOf(o);
570
- // The root of the chain is the last level before null, which is what `Object.prototype` is.
571
- // Its position holds in every realm. A value built in a `vm` context or a worker thread
572
- // carries that realm's root above it, so an identity test against the local object misses it
573
- // and the foreign `__proto__` accessor reads as a name the caller supplied.
574
- //
575
- // The level has to be an inherited one. A caller's own `_create(null)` has no prototype
576
- // either, and treating the bag itself as a root skips the names they set on it.
577
244
  var atObjectProto = inherited && above === null;
578
- // A kind's own prototype gets no exemption as a level. Passing one over whole hides anything
579
- // added to it, and `Array.prototype.password = "pw"` is then invisible while `opts.password`
580
- // resolves, which handed `pki.key.export` an unprotected private key for `[]` as the bag.
581
- // Object.prototype was already read for that reason; every level is now read the same way,
582
- // and what a kind puts on its prototype is passed over by name below.
583
- //
584
- // Reflect.ownKeys, because Object.getOwnPropertyNames never returns a Symbol key and a
585
- // caller can write one. Such a name cannot answer `opts.password`, so it reaches no verb,
586
- // but it is still an option supplied and not read, which is the whole thing being refused.
587
245
  _forEach(_ownKeys(o), function (k) {
588
246
  if (seen[k]) return;
589
- // The indices of an array or a byte view are its structure, whichever level they are read
590
- // from. Both kinds answer an integer-keyed read from their elements before any prototype is
591
- // consulted, so no caller can supply an option under such a name.
592
247
  if (indexedSelf && typeof k === "string" && _isArrayIndex(k)) return;
593
- // `length` is structure only where the language puts it on the value itself, which an array
594
- // does and a byte view does not. On an array it is an own non-configurable property that no
595
- // prototype can shadow, so `opts.length` is always the count. A byte view carries it as a
596
- // prototype accessor, and `class Opts extends Uint8Array { get length() {} }` shadows that
597
- // one: `opts.length` then answers with what the caller wrote, so it is an option they
598
- // supplied. Passing the name over for both kinds hid exactly that. Left to the level test
599
- // below, which exempts the accessor where the language installed it and reports an override.
600
248
  if (indexedSelf && k === "length" && !inherited) return;
601
249
  if (_isOwnStructuralName(obj, k)) return;
602
250
  var d = _getOwnPropertyDescriptor(o, k);
603
- // A name a built-in kind defines, on a level above the value and shaped the way the
604
- // language leaves it. Own is deliberately excluded: an own `detached` on a buffer shadows
605
- // the intrinsic getter, so `opts.detached` answers with what the caller wrote, and
606
- // pki.cms.sign reads an option under exactly that name.
607
- // A member of the value's own kind, or one sitting on a prototype the language installs
608
- // members on. The second is what carries `_create(Map.prototype)`, which holds no map
609
- // and inherits `size` all the same. Neither alone is enough: without the level test a class
610
- // of the caller's could name a getter after any kind's member and have it passed over.
611
251
  var here = _holderMembers(o);
612
252
  if (inherited && _looksIntrinsic(d) && !_shadowsAnother(obj, k, o) &&
613
253
  (here === null ? _indexOf(members, k) !== -1 : _indexOf(here, k) !== -1)) return;
614
- // Object.prototype is decided here and nowhere else. A member is one of the twelve the spec
615
- // names, still shaped like one: a data property holding a function, or the `__proto__`
616
- // accessor. Anything else on it was planted and is reported.
617
- //
618
- // The method rule below must not run on it. That rule exempts an inherited function so a
619
- // caller's class keeps its methods, and a planted `password` function is inherited and a
620
- // function, so the rule would rescue exactly the value this check exists to find. A class
621
- // defines its methods on its own prototype, and nothing legitimate puts one on the root.
622
254
  if (atObjectProto) {
623
255
  if (_PRISTINE_OBJECT_PROTO[k] && _looksBuiltIn(d)) return;
624
256
  seen[k] = 1;
625
257
  _append(out, k);
626
258
  return;
627
259
  }
628
- // A method: a data property holding a function that is either inherited, where a class
629
- // defines one, or also supplied under that name by the chain above, where a snapshot has
630
- // copied one down onto the object. Both readings are needed. The first alone calls a
631
- // promoted method an option. The second alone misses a method at the level that defines
632
- // it, where nothing above carries the same function. An accessor is never a method,
633
- // whichever way it was written, since a getter exists to answer with a value.
634
260
  if (d && !d.get && !d.set && typeof d.value === "function" &&
635
261
  (inherited || _isMethodOf(above, k, d.value))) return;
636
262
  seen[k] = 1;
@@ -641,50 +267,13 @@ function _readableNames(obj) {
641
267
  return out;
642
268
  }
643
269
 
644
- // The exported form of the property walk, which takes the caller's error factory like every
645
- // other guard function.
646
- //
647
- // The internal walk reads the prototype chain, and reading a chain runs a `getPrototypeOf` trap,
648
- // so a hostile one throws its own raw error out of a module whose whole contract is a typed one.
649
- // `assertKnownKeys` and `optionsObject` refuse a Proxy before they walk; this door has to do the
650
- // same, because a caller reaching for the names directly is exactly the caller who has not
651
- // already checked. Taking `(E, code, label)` is what makes that possible, and it puts the one
652
- // guard function that did not follow the family convention back inside it.
653
- //
654
270
  // @enforced-by behavioral -- a missing refusal has no rename-proof code shape; the RED vector
655
- // (a hostile trap escaping as its own Error from this door) is the guard.
656
271
  function readableNames(obj, E, code, label) {
657
272
  _refuseUnenumerable(obj, E, code, label);
658
273
  return _readableNames(obj);
659
274
  }
660
275
 
661
- // The indices an ordinary read on an array resolves, ascending, own and inherited.
662
- //
663
- // The name walk above drops every index of an indexed kind, since an index is structure rather
664
- // than a name a caller supplied. Something still has to answer which indices there ARE, and the
665
- // answer is not `Reflect.ownKeys`: an array consults its prototype chain for a hole, so
666
- // `_setPrototypeOf([,], {0: signer})` reads `[signer]` to a `for` loop, to `forEach`, and to
667
- // every consumer of the value, while its own keys report an empty array. A copy built from the own
668
- // keys alone holds a hole where the original answers, which is the same divergence between the
669
- // value checked and the value used that this family exists to close - here it silently shortens a
670
- // signer list rather than lengthening it.
671
- //
672
- // Arrays only. A typed array answers a canonical index from its elements and never consults the
673
- // chain, in bounds or out, so its indices are exactly its own. A DataView is an ordinary object
674
- // whose numeric keys ARE caller-supplied names, and the name walk above already reports them.
675
- //
676
- // `length` is read off the own descriptor, which for an array is the non-configurable count the
677
- // language maintains and no prototype can shadow. Inherited indices at or above it are left out:
678
- // a read past `length` resolves, but no length-bounded traversal reaches it, and carrying one
679
- // across would lengthen the copy past what the caller passed.
680
- //
681
- // The work stays bounded by what the value and its chain actually hold, so a caller who writes
682
- // `a.length = 4e9` costs what a sparse array costs and not four billion steps. The walk stops at
683
- // an object already visited for the reason the name walk does: a `getPrototypeOf` trap can hand
684
- // back a fresh proxy forever, and a chain that never ends hangs the verb.
685
- //
686
276
  // @enforced-by behavioral -- an enumeration gap has no rename-proof code shape; the RED vector
687
- // (a length-one array holding its only element on its prototype, copied to a hole) is the guard.
688
277
  function readableIndices(obj, E, code, label) {
689
278
  _refuseUnenumerable(obj, E, code, label);
690
279
  if (!_isArray(obj)) return [];
@@ -705,22 +294,6 @@ function readableIndices(obj, E, code, label) {
705
294
  return _sort(out, function (a, b) { return _Number(a) - _Number(b); });
706
295
  }
707
296
 
708
- // The object kinds that are never an options bag, named so the refusal says which mistake was
709
- // made. Buffer is handled beside the type check, being the argument-order slip.
710
- //
711
- // A boxed primitive is the one that has to be here rather than left to the unknown-option check.
712
- // `new Number(0)` and `new Boolean(false)` carry no readable name at all, so nothing is reported
713
- // and they pass as a bag with no options in it: the same silence `0` and `false` used to buy,
714
- // one wrapper away. The rest carry names the language installed, so each is refused already; what
715
- // they gain is a message that names the argument rather than one of the engine's own fields.
716
- //
717
- // Every one read off the value's slot, so a lookalike built over the prototype does not answer for
718
- // one, a real one from a `vm` context or a worker thread does, and the value is asked nothing.
719
- //
720
- // That last part is the reason none of these is a type tag. `Object.prototype.toString` reads
721
- // `Symbol.toStringTag`, which a caller can back with a getter that throws, so classifying a bag
722
- // that way put the caller's own exception on a boundary whose contract is a typed error, and a
723
- // caller could name any object an arguments object by writing the tag themselves.
724
297
  function _notAnOptionsBag(v) {
725
298
  if (util.types.isBoxedPrimitive(v)) return "a boxed primitive";
726
299
  if (util.types.isNativeError(v)) return "an Error";
@@ -729,22 +302,6 @@ function _notAnOptionsBag(v) {
729
302
  return null;
730
303
  }
731
304
 
732
- // Normalize a verb's options argument and return it. The order of the two steps decides whether
733
- // the check runs on the caller's value, and returning is what makes the safe order the easy one.
734
- //
735
- // The idiom this replaces was `opts = opts || {}` followed by a type check. That reads as though
736
- // it validates, and does not: `||` treats `false`, `0`, `""` and `NaN` as absent too, so those
737
- // four were rewritten to `{}` before the check could see them and sailed through as valid
738
- // options. Every entry point that reached for the idiom inherited the hole, including three that
739
- // had shipped with it.
740
- //
741
- // Only `null` and `undefined` mean "no options given". Anything else non-object is a caller
742
- // error and says so. A Buffer is excluded because it is an object and is never an options bag --
743
- // passing one is an argument-order mistake, which is worth naming rather than treating as empty.
744
- //
745
- // A built-in exotic whose data lives in internal slots rather than own enumerable keys, recognized by
746
- // identity so a cross-realm instance is caught too. `util.types` covers each such kind; an array is not
747
- // among them and is checked separately by the caller.
748
305
  function _isBuiltinExotic(v) {
749
306
  var t = util.types;
750
307
  return t.isDate(v) || t.isMap(v) || t.isSet(v) || t.isWeakMap(v) || t.isWeakSet(v) || t.isRegExp(v) ||
@@ -752,44 +309,17 @@ function _isBuiltinExotic(v) {
752
309
  t.isBoxedPrimitive(v) || t.isNativeError(v) || t.isArgumentsObject(v) || t.isGeneratorObject(v);
753
310
  }
754
311
 
755
- // assertPlainRecord(v, E, code, label): v MUST be a plain data record -- a non-null object that is not an
756
- // array, a Buffer, a Proxy, or a built-in exotic (a Date, Map, Set, boxed primitive, ...). A caller's
757
- // `typeof v === "object"` gate admits an array or a Date, which then passes assertKnownKeys with no own
758
- // key to reject and reads as a keyless record -- every field `undefined` and silently defaulted. This
759
- // door refuses that shape, so a malformed container is a refusal rather than a request assembled from
760
- // defaults. Composes BEFORE assertKnownKeys, which only
761
- // judges the keys that are present, not whether the value is a record at all.
762
- //
763
- // The prototype is NOT consulted, so a record built by a caller's own class, or one from another realm
764
- // (a vm context, a worker) whose prototype is a different Object.prototype, is accepted -- it holds its
765
- // fields as own enumerable properties like any record. Only a built-in exotic that keeps its data in
766
- // internal slots (a Date, Map, Set, boxed primitive, ...), an array (index-keyed), a Buffer, or a Proxy
767
- // is refused, each recognized by identity through `util.types` / `Array.isArray` so a cross-realm
768
- // instance is caught where an `instanceof` or a prototype check would miss it.
769
- //
770
312
  // @enforced-by behavioral -- a plain-record refusal has no single rename-proof code shape worth a
771
- // tree-wide detector; the RED vectors (an array, a Date, and a Proxy at each routed entry point, and a
772
- // cross-realm/subclass record that must still be ACCEPTED) are the guard.
773
313
  function assertPlainRecord(v, E, code, label) {
774
314
  _requireFactory(E);
775
315
  if (v === null || typeof v !== "object" || _isNodeBuffer(v) || _isArray(v)) throw E(code, label + " must be a plain object");
776
- _refuseUnenumerable(v, E, code, label); // a Proxy's reported keys need not match what it answers
316
+ _refuseUnenumerable(v, E, code, label);
777
317
  if (_isBuiltinExotic(v)) throw E(code, label + " must be a plain object (a built-in exotic such as a Date or Map is refused)");
778
318
  }
779
319
 
780
320
  // @enforced-by behavioral -- the defect is an ordering, which has no rename-proof code shape; the
781
- // RED vector (a verb handed `false` accepting it as `{}`) is the guard.
782
321
  function optionsObject(opts, E, code, label) {
783
- // No options supplied gets a bag with NO prototype, so it inherits nothing. A plain `{}` here
784
- // would inherit whatever Object.prototype carries, and on a runtime where that has been
785
- // polluted the caller is then refused for a name they never wrote. A caller who does pass `{}`
786
- // is a different case and keeps the refusal: `opts.password` answers on their object, so the
787
- // option is readable and unread, which is exactly what is being refused.
788
322
  if (opts === null || opts === undefined) return _create(null);
789
- // `typeof` asks the value nothing, so it is safe on any argument. Every question after it comes
790
- // once the value has been refused as a Proxy, because each one walks the prototype chain and so
791
- // runs a `getPrototypeOf` trap, which took this door out through the caller's own exception
792
- // rather than the typed one it promises.
793
323
  if (typeof opts !== "object") throw E(code, label + " must be an object");
794
324
  _refuseUnenumerable(opts, E, code, label);
795
325
  if (_isNodeBuffer(opts)) throw E(code, label + " must be an object");
@@ -798,42 +328,6 @@ function optionsObject(opts, E, code, label) {
798
328
  return _settle(opts, E, code, label);
799
329
  }
800
330
 
801
- // The caller's bag, once its option names have been shown to hold still while they are read.
802
- //
803
- // Reading an option can run a caller's getter, and a getter can add a name to the bag it was read
804
- // from. `{ get format() { this.password = "pw"; return "der"; } }` shows only `format` while the
805
- // unknown-option check runs, and grows `password` when the verb reads `format` afterwards, so the
806
- // names that were checked are not the names the verb ends up carrying. `pki.key.export` took such
807
- // a bag and returned a private key in the clear, which is the case the check exists to prevent.
808
- //
809
- // Every readable name is therefore read here, before anything is checked, and the names are taken
810
- // again afterwards. A bag that grew or dropped one is refused, because a bag that rewrites itself
811
- // as it is read has no set of names that can be checked at all.
812
- //
813
- // The bag itself is handed back, never a copy of it. Which names a caller supplied is decided by
814
- // where they sit: own is theirs, inherited is machinery unless the chain says otherwise. Copying
815
- // the readable ones onto a new object destroys exactly that, and every attempt to keep it turned
816
- // into its own defect: a bare copy dropped `pki.path.build`'s inherited `transport` and sent the
817
- // verb to the network the caller meant to replace, and a copy built over the original inherited
818
- // native accessors onto a receiver with no slot behind them, so an `ArrayBuffer` options bag
819
- // raised a raw TypeError from `opts.detached`.
820
- //
821
- // An accessor cannot be one, and that is the whole rule: a getter answers a different question
822
- // every time it is asked, so a name checked once says nothing about what the verb reads next.
823
- //
824
- // Every narrower attempt to keep them was measured and each carried its own defect. Reading once
825
- // and re-taking the names catches a getter that mutates immediately and misses one that waits for
826
- // a later read. Freezing the bag closes that and then throws a raw TypeError on a non-empty typed
827
- // array, which cannot be frozen at all, while still leaving a mutable PROTOTYPE for an inherited
828
- // getter to grow. Copying the bag instead loses which names were the caller's own, drops an
829
- // inherited option a verb reads, and leaves a native accessor on a receiver with no slot for it.
830
- //
831
- // Refusing is the one rule with nothing behind it. A plain object, a class instance with methods,
832
- // a collection, a bag from another realm are all still options bags; what is asked is that the
833
- // options themselves be values. The names are read once even so, since an accessor can hide on a
834
- // prototype and this is where that gets found.
835
- // The descriptor a name resolves to, from wherever on the chain it is found. Only the first
836
- // level carrying it matters, since that is the one a read reaches.
837
331
  function _descriptorHolder(v, k) {
838
332
  var visited = new _Set();
839
333
  for (var o = v; o !== null && o !== undefined && !_setHas(visited, o); o = _getPrototypeOf(o)) {
@@ -844,15 +338,7 @@ function _descriptorHolder(v, k) {
844
338
  return null;
845
339
  }
846
340
 
847
- // refuseAccessorFields(obj, names, E, code, label) -> undefined | throws E(code, msg)
848
- //
849
- // Every door that decides what a caller supplied asks this, because a door that reads an accessor
850
- // before another door checks for one leaves nothing behind to find: guard.bytes.snapshotDeep runs
851
- // a spec's getters while copying and writes what they returned as plain data, so the option check
852
- // that follows sees values and cannot tell there was ever an accessor there.
853
- //
854
341
  // @enforced-by behavioral -- reading an accessor before it is refused has no rename-proof code
855
- // shape; the RED vectors (a getter on an options bag and on a signing spec) are the guard.
856
342
  function refuseAccessorFields(obj, names, E, code, label) {
857
343
  for (var i = 0; i < names.length; i++) {
858
344
  var holder = _descriptorHolder(obj, names[i]);
@@ -866,8 +352,6 @@ function refuseAccessorFields(obj, names, E, code, label) {
866
352
  }
867
353
 
868
354
  function _settle(opts, E, code, label) {
869
- // A caller's accessor can throw, and that fault gets this boundary's typed code rather than
870
- // escaping as itself from a verb the caller called for something else.
871
355
  function readAll(names) {
872
356
  for (var i = 0; i < names.length; i++) {
873
357
  try { void opts[names[i]]; }
@@ -890,20 +374,12 @@ function _settle(opts, E, code, label) {
890
374
  return opts;
891
375
  }
892
376
 
893
- // Frozen for the reason the family header gives: a boundary reads its guard off this object at the
894
- // call, so a writable export would let a caller replace the check rather than pass it.
895
377
  module.exports = intrinsic.freeze({
896
378
  assertCanonicalOid: assertCanonicalOid,
897
379
  assertKnownKeys: assertKnownKeys,
898
380
  assertPlainRecord: assertPlainRecord,
899
381
  optionsObject: optionsObject,
900
382
  refuseAccessorFields: refuseAccessorFields,
901
- // Exported so a caller that forwards an options bag copies the same surface this module
902
- // accepts. A narrower enumeration such as `Object.keys` admits a name here and then drops
903
- // it on the way, which is worse than refusing it. The option is reported valid and then
904
- // does nothing at the place it was meant to act.
905
383
  readableNames: readableNames,
906
- // Exported for the same reason as its sibling: a caller copying an array has to reach the
907
- // elements a read reaches, and the own keys are not that set.
908
384
  readableIndices: readableIndices
909
385
  });