@sanning/proof 0.9.0 → 0.9.1
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.
- package/dist/verifier.js +18 -2
- package/package.json +1 -1
- package/src/verifier.ts +19 -2
package/dist/verifier.js
CHANGED
|
@@ -93,11 +93,27 @@ function resolveToJSON(node, max) {
|
|
|
93
93
|
// bound exists to prevent, reached through the bound (proof#71 review). Copying
|
|
94
94
|
// what was measured is what makes check and use the same value. It also settles
|
|
95
95
|
// a getter, which is read once here and never re-read.
|
|
96
|
+
//
|
|
97
|
+
// Every object copy has a NULL prototype, and that is load-bearing too. RFC
|
|
98
|
+
// 8785 has no reserved member names, and `JSON.parse` keeps `__proto__` as an
|
|
99
|
+
// ordinary own key. On a plain `{}`, `copy["__proto__"] = x` runs the setter
|
|
100
|
+
// inherited from `Object.prototype`: it replaces the copy's prototype and
|
|
101
|
+
// creates no key, so the member and everything under it vanished from the
|
|
102
|
+
// canonical bytes. Content there was covered by no hash and no signature, and
|
|
103
|
+
// this kernel disagreed with the Python and Go kernels on the same bytes
|
|
104
|
+
// (0.9.0; the same bug class as proof#31 and proof#34). With no prototype
|
|
105
|
+
// there is no setter, so every key, `__proto__` included, lands as an own data
|
|
106
|
+
// property. `canonicalize` reads the copy with `Object.keys` and `object[key]`
|
|
107
|
+
// and tests `toJSON instanceof Function`, none of which a prototype affects
|
|
108
|
+
// for JSON data, so no other input's output changes.
|
|
109
|
+
function emptyObject() {
|
|
110
|
+
return Object.create(null);
|
|
111
|
+
}
|
|
96
112
|
function boundedInput(value, max) {
|
|
97
113
|
const root = resolveToJSON(value, max);
|
|
98
114
|
if (root === OVER_DEEP || root === null || typeof root !== "object")
|
|
99
115
|
return root;
|
|
100
|
-
const copy = Array.isArray(root) ? [] :
|
|
116
|
+
const copy = Array.isArray(root) ? [] : emptyObject();
|
|
101
117
|
const stack = [[root, copy, 1]];
|
|
102
118
|
while (stack.length > 0) {
|
|
103
119
|
const [src, dst, depth] = stack.pop();
|
|
@@ -113,7 +129,7 @@ function boundedInput(value, max) {
|
|
|
113
129
|
}
|
|
114
130
|
if (depth + 1 > max)
|
|
115
131
|
return OVER_DEEP; // a container nested past the bound
|
|
116
|
-
const childCopy = Array.isArray(child) ? [] :
|
|
132
|
+
const childCopy = Array.isArray(child) ? [] : emptyObject();
|
|
117
133
|
dst[key] = childCopy;
|
|
118
134
|
stack.push([child, childCopy, depth + 1]);
|
|
119
135
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanning/proof",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "TypeScript kernel of the Sanning verification stack: RFC 8785 (JCS) canonicalization, SHA-256, and Ed25519 verification for Verifiable Event Envelopes. Full-family verifier (inline + external commitment); accepts sanning.agent/v1, sanning.mlflow/v1, sanning.events/v1. Conformance-gated byte-for-byte against the test-vectors corpus.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/verifier.ts
CHANGED
|
@@ -103,10 +103,27 @@ function resolveToJSON(node: unknown, max: number): unknown {
|
|
|
103
103
|
// bound exists to prevent, reached through the bound (proof#71 review). Copying
|
|
104
104
|
// what was measured is what makes check and use the same value. It also settles
|
|
105
105
|
// a getter, which is read once here and never re-read.
|
|
106
|
+
//
|
|
107
|
+
// Every object copy has a NULL prototype, and that is load-bearing too. RFC
|
|
108
|
+
// 8785 has no reserved member names, and `JSON.parse` keeps `__proto__` as an
|
|
109
|
+
// ordinary own key. On a plain `{}`, `copy["__proto__"] = x` runs the setter
|
|
110
|
+
// inherited from `Object.prototype`: it replaces the copy's prototype and
|
|
111
|
+
// creates no key, so the member and everything under it vanished from the
|
|
112
|
+
// canonical bytes. Content there was covered by no hash and no signature, and
|
|
113
|
+
// this kernel disagreed with the Python and Go kernels on the same bytes
|
|
114
|
+
// (0.9.0; the same bug class as proof#31 and proof#34). With no prototype
|
|
115
|
+
// there is no setter, so every key, `__proto__` included, lands as an own data
|
|
116
|
+
// property. `canonicalize` reads the copy with `Object.keys` and `object[key]`
|
|
117
|
+
// and tests `toJSON instanceof Function`, none of which a prototype affects
|
|
118
|
+
// for JSON data, so no other input's output changes.
|
|
119
|
+
function emptyObject(): Record<string, unknown> {
|
|
120
|
+
return Object.create(null) as Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
|
|
106
123
|
function boundedInput(value: unknown, max: number): unknown {
|
|
107
124
|
const root = resolveToJSON(value, max);
|
|
108
125
|
if (root === OVER_DEEP || root === null || typeof root !== "object") return root;
|
|
109
|
-
const copy: Record<string, unknown> | unknown[] = Array.isArray(root) ? [] :
|
|
126
|
+
const copy: Record<string, unknown> | unknown[] = Array.isArray(root) ? [] : emptyObject();
|
|
110
127
|
const stack: Array<[object, Record<string, unknown> | unknown[], number]> = [[root, copy, 1]];
|
|
111
128
|
while (stack.length > 0) {
|
|
112
129
|
const [src, dst, depth] = stack.pop()!;
|
|
@@ -120,7 +137,7 @@ function boundedInput(value: unknown, max: number): unknown {
|
|
|
120
137
|
continue;
|
|
121
138
|
}
|
|
122
139
|
if (depth + 1 > max) return OVER_DEEP; // a container nested past the bound
|
|
123
|
-
const childCopy: Record<string, unknown> | unknown[] = Array.isArray(child) ? [] :
|
|
140
|
+
const childCopy: Record<string, unknown> | unknown[] = Array.isArray(child) ? [] : emptyObject();
|
|
124
141
|
(dst as Record<string, unknown>)[key] = childCopy;
|
|
125
142
|
stack.push([child, childCopy, depth + 1]);
|
|
126
143
|
}
|