@reallyme/codec 0.1.21 → 0.2.0

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/cbor.js CHANGED
@@ -1,14 +1,228 @@
1
1
  // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from "@bufbuild/protobuf";
5
+ import { MAX_CODEC_BOUNDARY_NODES, strictUtf8ByteLength, } from "./boundary.js";
6
+ import { DETERMINISTIC_CBOR_I64_MIN, DETERMINISTIC_CBOR_NEGATIVE_MAX, DETERMINISTIC_CBOR_U64_MAX, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES, MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES, MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES, MAX_DETERMINISTIC_CBOR_INPUT_LEN, MAX_DETERMINISTIC_CBOR_NESTING_DEPTH, MAX_DETERMINISTIC_CBOR_NODES, MAX_DETERMINISTIC_CBOR_OUTPUT_LEN, } from "./deterministicCborBoundary.js";
4
7
  import { ReallyMeCodecError } from "./errors.js";
5
- import { ensureBytesInput, ensureStringValue, readBooleanProperty, readBytesOutput, readObjectOutput, readProtoResultOutput, readStringOutput, readStringProperty, readStringValueProperty, readNumberOutput, } from "./readOutput.js";
8
+ import { CodecDagCborDecodeRequestSchema, CodecDagCborEncodeRequestSchema, CodecDagCborVerifyCidRequestSchema, CodecDeterministicCborArraySchema, CodecDeterministicCborBoolSchema, CodecDeterministicCborBytesSchema, CodecDeterministicCborDecodeRequestSchema, CodecDeterministicCborEncodeRequestSchema, CodecDeterministicCborIntegerSchema, CodecDeterministicCborMapEntrySchema, CodecDeterministicCborMapKeySchema, CodecDeterministicCborMapSchema, CodecDeterministicCborNegativeIntegerSchema, CodecDeterministicCborNullSchema, CodecDeterministicCborTextSchema, CodecDeterministicCborUnsignedIntegerSchema, CodecDeterministicCborValueSchema, CodecOperationRequestSchema, } from "./proto/generated/reallyme/codec/v1/codec_pb.js";
9
+ import { clearGeneratedOperationResult, processGeneratedOperationRequest, } from "./operationContract.js";
10
+ import { ensureBytesInput, ensureStringValue, readBytesOutput, readStringOutput, readNumberOutput, } from "./readOutput.js";
6
11
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
7
- const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12
+ export const ReallyMeDeterministicCbor = {
13
+ null() {
14
+ return { type: "null" };
15
+ },
16
+ bool(value) {
17
+ if (typeof value !== "boolean") {
18
+ return invalidCborInput();
19
+ }
20
+ return { type: "bool", value };
21
+ },
22
+ unsigned(value) {
23
+ if (typeof value !== "bigint" || value < 0n || value > DETERMINISTIC_CBOR_U64_MAX) {
24
+ return invalidCborInput();
25
+ }
26
+ return { type: "integer", value: { type: "unsigned", value } };
27
+ },
28
+ negative(value) {
29
+ if (typeof value !== "bigint" ||
30
+ value < DETERMINISTIC_CBOR_I64_MIN ||
31
+ value > DETERMINISTIC_CBOR_NEGATIVE_MAX) {
32
+ return invalidCborInput();
33
+ }
34
+ return { type: "integer", value: { type: "negative", value } };
35
+ },
36
+ text(value) {
37
+ ensureStringValue(value);
38
+ return { type: "text", value };
39
+ },
40
+ bytes(value) {
41
+ ensureBytesInput(value);
42
+ return { type: "bytes", value: value.slice() };
43
+ },
44
+ array(value) {
45
+ return { type: "array", value: [...value] };
46
+ },
47
+ mapInt(entries) {
48
+ const seen = new Set();
49
+ return {
50
+ type: "map",
51
+ value: entries.map(([key, value]) => {
52
+ if (typeof key !== "bigint" || key < 0n || key > DETERMINISTIC_CBOR_U64_MAX) {
53
+ return invalidCborInput();
54
+ }
55
+ if (seen.has(key)) {
56
+ return invalidCborInput();
57
+ }
58
+ seen.add(key);
59
+ return {
60
+ key: { type: "integer", value: { type: "unsigned", value: key } },
61
+ value,
62
+ };
63
+ }),
64
+ };
65
+ },
66
+ mapText(entries) {
67
+ const seen = new Set();
68
+ return {
69
+ type: "map",
70
+ value: entries.map(([key, value]) => {
71
+ ensureStringValue(key);
72
+ if (seen.has(key)) {
73
+ return invalidCborInput();
74
+ }
75
+ seen.add(key);
76
+ return { key: { type: "text", value: key }, value };
77
+ }),
78
+ };
79
+ },
80
+ intKey(value) {
81
+ if (typeof value !== "bigint") {
82
+ return invalidCborInput();
83
+ }
84
+ if (value >= 0n && value <= DETERMINISTIC_CBOR_U64_MAX) {
85
+ return { type: "integer", value: { type: "unsigned", value } };
86
+ }
87
+ if (value >= DETERMINISTIC_CBOR_I64_MIN && value <= DETERMINISTIC_CBOR_NEGATIVE_MAX) {
88
+ return { type: "integer", value: { type: "negative", value } };
89
+ }
90
+ return invalidCborInput();
91
+ },
92
+ textKey(value) {
93
+ ensureStringValue(value);
94
+ return { type: "text", value };
95
+ },
96
+ entry(key, value) {
97
+ return { key, value };
98
+ },
99
+ };
100
+ export const ReallyMeDagCbor = {
101
+ null() {
102
+ return { type: "null" };
103
+ },
104
+ bool(value) {
105
+ if (typeof value !== "boolean") {
106
+ return invalidCborInput();
107
+ }
108
+ return { type: "bool", value };
109
+ },
110
+ int(value) {
111
+ return { type: "int", value: validateCborInteger(value) };
112
+ },
113
+ unsigned(value) {
114
+ const integer = validateCborInteger(value);
115
+ if ((typeof integer === "bigint" && integer < 0n) ||
116
+ (typeof integer === "number" && integer < 0)) {
117
+ return invalidCborInput();
118
+ }
119
+ return { type: "int", value: integer };
120
+ },
121
+ negative(value) {
122
+ const integer = validateCborInteger(value);
123
+ if ((typeof integer === "bigint" && integer >= 0n) ||
124
+ (typeof integer === "number" && integer >= 0)) {
125
+ return invalidCborInput();
126
+ }
127
+ return { type: "int", value: integer };
128
+ },
129
+ text(value) {
130
+ ensureStringValue(value);
131
+ return { type: "string", value };
132
+ },
133
+ bytes(value) {
134
+ ensureBytesInput(value);
135
+ return { type: "bytes", value: value.slice() };
136
+ },
137
+ array(value) {
138
+ return { type: "array", value: [...value] };
139
+ },
140
+ mapText(entries) {
141
+ const seen = new Set();
142
+ return {
143
+ type: "map",
144
+ value: entries.map(([key, value]) => {
145
+ ensureStringValue(key);
146
+ if (seen.has(key)) {
147
+ return invalidCborInput();
148
+ }
149
+ seen.add(key);
150
+ return { key, value };
151
+ }),
152
+ };
153
+ },
154
+ };
155
+ const invalidCborInput = () => {
156
+ throw new ReallyMeCodecError("invalid-input");
157
+ };
158
+ const isRecord = (value) => {
159
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
160
+ return false;
161
+ }
162
+ const prototype = Object.getPrototypeOf(value);
163
+ return prototype === Object.prototype || prototype === null;
164
+ };
165
+ const readDataProperty = (value, name) => {
166
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
167
+ if (descriptor === undefined || !("value" in descriptor)) {
168
+ return invalidCborInput();
169
+ }
170
+ return descriptor.value;
171
+ };
172
+ const snapshotArray = (value, maximumLength = MAX_CODEC_BOUNDARY_NODES) => {
173
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) {
174
+ return invalidCborInput();
175
+ }
176
+ const rawLength = readDataProperty(value, "length");
177
+ if (typeof rawLength !== "number") {
178
+ return invalidCborInput();
179
+ }
180
+ const length = rawLength;
181
+ if (!Number.isSafeInteger(length) ||
182
+ length < 0 ||
183
+ length > maximumLength) {
184
+ return invalidCborInput();
185
+ }
186
+ const entries = [];
187
+ for (let index = 0; index < length; index += 1) {
188
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
189
+ if (descriptor === undefined || !("value" in descriptor)) {
190
+ return invalidCborInput();
191
+ }
192
+ entries.push(descriptor.value);
193
+ }
194
+ return entries;
195
+ };
8
196
  const i64Min = -(1n << 63n);
9
197
  const i64Max = (1n << 63n) - 1n;
10
198
  const decimalIntegerPattern = /^-?(0|[1-9][0-9]*)$/u;
11
199
  const maxCborContainerDepth = 128;
200
+ const maxDagCborInputLength = 1024 * 1024;
201
+ const wipeDagCborValueBytes = (value) => {
202
+ if (value === undefined) {
203
+ return;
204
+ }
205
+ switch (value.type) {
206
+ case "bytes":
207
+ value.value.fill(0);
208
+ break;
209
+ case "array":
210
+ for (const child of value.value) {
211
+ wipeDagCborValueBytes(child);
212
+ }
213
+ break;
214
+ case "map":
215
+ for (const entry of value.value) {
216
+ wipeDagCborValueBytes(entry.value);
217
+ }
218
+ break;
219
+ case "null":
220
+ case "bool":
221
+ case "int":
222
+ case "string":
223
+ break;
224
+ }
225
+ };
12
226
  const childContainerDepth = (depth) => {
13
227
  const nextDepth = depth + 1;
14
228
  if (nextDepth > maxCborContainerDepth) {
@@ -41,8 +255,16 @@ const validateCborInteger = (value) => {
41
255
  }
42
256
  throw new ReallyMeCodecError("invalid-input");
43
257
  };
44
- const validateCborValue = (value, depth = 0, seen = new WeakSet()) => {
45
- if (!isRecord(value) || typeof value.type !== "string") {
258
+ const validateCborValue = (value, depth = 0, seen = new WeakSet(), state = { nodes: 0, byteStringBytes: 0 }) => {
259
+ if (state.nodes >= MAX_DETERMINISTIC_CBOR_NODES) {
260
+ throw new ReallyMeCodecError("invalid-input");
261
+ }
262
+ state.nodes += 1;
263
+ if (!isRecord(value)) {
264
+ throw new ReallyMeCodecError("invalid-input");
265
+ }
266
+ const type = readDataProperty(value, "type");
267
+ if (typeof type !== "string") {
46
268
  throw new ReallyMeCodecError("invalid-input");
47
269
  }
48
270
  if (seen.has(value)) {
@@ -50,118 +272,1082 @@ const validateCborValue = (value, depth = 0, seen = new WeakSet()) => {
50
272
  }
51
273
  seen.add(value);
52
274
  try {
53
- switch (value.type) {
275
+ switch (type) {
54
276
  case "null":
55
277
  return { type: "null" };
56
- case "bool":
57
- if (typeof value.value !== "boolean") {
278
+ case "bool": {
279
+ const child = readDataProperty(value, "value");
280
+ if (typeof child !== "boolean") {
58
281
  throw new ReallyMeCodecError("invalid-input");
59
282
  }
60
- return { type: "bool", value: value.value };
283
+ return { type: "bool", value: child };
284
+ }
61
285
  case "int":
62
- return { type: "int", value: validateCborInteger(value.value) };
63
- case "string":
64
- case "bytes":
65
- if (typeof value.value !== "string") {
286
+ return {
287
+ type: "int",
288
+ value: validateCborInteger(readDataProperty(value, "value")),
289
+ };
290
+ case "string": {
291
+ const child = readDataProperty(value, "value");
292
+ if (typeof child !== "string") {
293
+ throw new ReallyMeCodecError("invalid-input");
294
+ }
295
+ return { type: "string", value: child };
296
+ }
297
+ case "bytes": {
298
+ const child = readDataProperty(value, "value");
299
+ if (!(child instanceof Uint8Array)) {
66
300
  throw new ReallyMeCodecError("invalid-input");
67
301
  }
68
- return { type: value.type, value: value.value };
69
- case "array":
70
- if (!Array.isArray(value.value)) {
302
+ ensureBytesInput(child);
303
+ if (child.length >
304
+ MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES - state.byteStringBytes) {
71
305
  throw new ReallyMeCodecError("invalid-input");
72
306
  }
307
+ state.byteStringBytes += child.length;
308
+ return { type: "bytes", value: child.slice() };
309
+ }
310
+ case "array": {
311
+ const children = snapshotArray(readDataProperty(value, "value"), MAX_DETERMINISTIC_CBOR_NODES - state.nodes);
312
+ const normalizedChildren = [];
313
+ try {
314
+ for (const entry of children) {
315
+ normalizedChildren.push(validateCborValue(entry, childContainerDepth(depth), seen, state));
316
+ }
317
+ return {
318
+ type: "array",
319
+ value: normalizedChildren,
320
+ };
321
+ }
322
+ catch (error) {
323
+ for (const child of normalizedChildren) {
324
+ wipeDagCborValueBytes(child);
325
+ }
326
+ throw error;
327
+ }
328
+ }
329
+ case "map": {
330
+ const entries = snapshotArray(readDataProperty(value, "value"), MAX_DETERMINISTIC_CBOR_NODES - state.nodes);
331
+ state.nodes += entries.length;
332
+ const keys = new Set();
333
+ const normalizedEntries = [];
334
+ try {
335
+ for (const entry of entries) {
336
+ if (!isRecord(entry)) {
337
+ throw new ReallyMeCodecError("invalid-input");
338
+ }
339
+ const key = readDataProperty(entry, "key");
340
+ if (typeof key !== "string" || keys.has(key)) {
341
+ throw new ReallyMeCodecError("invalid-input");
342
+ }
343
+ keys.add(key);
344
+ normalizedEntries.push({
345
+ key,
346
+ value: validateCborValue(readDataProperty(entry, "value"), childContainerDepth(depth), seen, state),
347
+ });
348
+ }
349
+ return {
350
+ type: "map",
351
+ value: normalizedEntries,
352
+ };
353
+ }
354
+ catch (error) {
355
+ for (const entry of normalizedEntries) {
356
+ wipeDagCborValueBytes(entry.value);
357
+ }
358
+ throw error;
359
+ }
360
+ }
361
+ default:
362
+ throw new ReallyMeCodecError("invalid-input");
363
+ }
364
+ }
365
+ finally {
366
+ seen.delete(value);
367
+ }
368
+ };
369
+ const deterministicCborMapKeySet = () => ({
370
+ integerKeys: new Set(),
371
+ textKeys: new Set(),
372
+ });
373
+ const recordDeterministicCborMapKey = (key, keys, duplicate) => {
374
+ switch (key.type) {
375
+ case "integer":
376
+ // The supported positive and negative domains do not overlap, so the
377
+ // bigint itself is the exact semantic integer-key identity.
378
+ if (keys.integerKeys.has(key.value.value)) {
379
+ duplicate();
380
+ }
381
+ keys.integerKeys.add(key.value.value);
382
+ break;
383
+ case "text":
384
+ // Valid JavaScript scalar strings compare equal exactly when their
385
+ // UTF-8 encodings do. Deliberately do not normalize or locale-fold PII.
386
+ if (keys.textKeys.has(key.value)) {
387
+ duplicate();
388
+ }
389
+ keys.textKeys.add(key.value);
390
+ break;
391
+ }
392
+ };
393
+ const deterministicCborValidationState = () => ({
394
+ nodes: 0,
395
+ textBytes: 0,
396
+ byteStringBytes: 0,
397
+ ownedBytes: [],
398
+ });
399
+ const wipeOwnedByteSnapshots = (state) => {
400
+ for (const value of state.ownedBytes) {
401
+ value.fill(0);
402
+ }
403
+ };
404
+ const consumeDeterministicCborBudget = (current, amount, maximum) => {
405
+ if (!Number.isSafeInteger(amount) ||
406
+ amount < 0 ||
407
+ current > maximum - amount) {
408
+ return invalidCborInput();
409
+ }
410
+ return current + amount;
411
+ };
412
+ const consumeDeterministicCborText = (state, value) => {
413
+ // Every UTF-16 code unit requires at least one UTF-8 byte. Reject an
414
+ // impossible aggregate before walking an attacker-sized managed string.
415
+ if (state.textBytes >
416
+ MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES - value.length) {
417
+ invalidCborInput();
418
+ }
419
+ state.textBytes = consumeDeterministicCborBudget(state.textBytes, strictUtf8ByteLength(value), MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES);
420
+ };
421
+ const requireDeterministicCborObject = (value, allowedKeys) => {
422
+ if (!isRecord(value)) {
423
+ return invalidCborInput();
424
+ }
425
+ const properties = new Map();
426
+ for (const key of Reflect.ownKeys(value)) {
427
+ if (typeof key !== "string" || !allowedKeys.includes(key)) {
428
+ return invalidCborInput();
429
+ }
430
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
431
+ if (descriptor === undefined || !("value" in descriptor)) {
432
+ return invalidCborInput();
433
+ }
434
+ if (properties.has(key)) {
435
+ return invalidCborInput();
436
+ }
437
+ properties.set(key, descriptor.value);
438
+ }
439
+ return { owner: value, properties };
440
+ };
441
+ const readDeterministicCborDataProperty = (properties, key) => {
442
+ if (!properties.has(key)) {
443
+ return invalidCborInput();
444
+ }
445
+ return properties.get(key);
446
+ };
447
+ const snapshotDeterministicCborArray = (value) => {
448
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) {
449
+ return invalidCborInput();
450
+ }
451
+ const properties = new Map();
452
+ for (const key of Reflect.ownKeys(value)) {
453
+ if (typeof key !== "string") {
454
+ return invalidCborInput();
455
+ }
456
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
457
+ if (descriptor === undefined || !("value" in descriptor) || properties.has(key)) {
458
+ return invalidCborInput();
459
+ }
460
+ properties.set(key, descriptor.value);
461
+ }
462
+ const rawLength = readDeterministicCborDataProperty(properties, "length");
463
+ if (typeof rawLength !== "number") {
464
+ return invalidCborInput();
465
+ }
466
+ const length = rawLength;
467
+ if (!Number.isSafeInteger(length) ||
468
+ length < 0 ||
469
+ length > MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES) {
470
+ return invalidCborInput();
471
+ }
472
+ if (properties.size !== length + 1) {
473
+ return invalidCborInput();
474
+ }
475
+ const entries = [];
476
+ for (let index = 0; index < length; index += 1) {
477
+ entries.push(readDeterministicCborDataProperty(properties, String(index)));
478
+ }
479
+ return entries;
480
+ };
481
+ const uint8ArraySubarray = Uint8Array.prototype.subarray;
482
+ const uint8ArraySet = Uint8Array.prototype.set;
483
+ /**
484
+ * Copies one bounded, fixed-length view and then revalidates the source view.
485
+ * This avoids allocating from a second attacker-controlled length observation
486
+ * when a length-tracking resizable buffer changes during validation.
487
+ */
488
+ const snapshotDeterministicCborBytes = (value, maximum) => {
489
+ const expectedLength = value.length;
490
+ if (expectedLength > maximum) {
491
+ return invalidCborInput();
492
+ }
493
+ let snapshot;
494
+ try {
495
+ const boundedView = uint8ArraySubarray.call(value, 0, expectedLength);
496
+ if (boundedView.length !== expectedLength) {
497
+ return invalidCborInput();
498
+ }
499
+ snapshot = new Uint8Array(expectedLength);
500
+ uint8ArraySet.call(snapshot, boundedView, 0);
501
+ if (value.length !== expectedLength ||
502
+ boundedView.length !== expectedLength ||
503
+ snapshot.length !== expectedLength) {
504
+ snapshot.fill(0);
505
+ return invalidCborInput();
506
+ }
507
+ return snapshot;
508
+ }
509
+ catch (error) {
510
+ snapshot?.fill(0);
511
+ if (error instanceof ReallyMeCodecError) {
512
+ throw error;
513
+ }
514
+ return invalidCborInput();
515
+ }
516
+ };
517
+ const requireDeterministicCborDepth = (depth) => {
518
+ const nextDepth = depth + 1;
519
+ if (nextDepth > MAX_DETERMINISTIC_CBOR_NESTING_DEPTH) {
520
+ return invalidCborInput();
521
+ }
522
+ return nextDepth;
523
+ };
524
+ const validateDeterministicCborInteger = (value) => {
525
+ const object = requireDeterministicCborObject(value, ["type", "value"]);
526
+ const type = readDeterministicCborDataProperty(object.properties, "type");
527
+ const rawValue = readDeterministicCborDataProperty(object.properties, "value");
528
+ if (typeof type !== "string" || typeof rawValue !== "bigint") {
529
+ return invalidCborInput();
530
+ }
531
+ switch (type) {
532
+ case "unsigned":
533
+ if (rawValue < 0n || rawValue > DETERMINISTIC_CBOR_U64_MAX) {
534
+ return invalidCborInput();
535
+ }
536
+ return { type: "unsigned", value: rawValue };
537
+ case "negative":
538
+ if (rawValue < DETERMINISTIC_CBOR_I64_MIN ||
539
+ rawValue > DETERMINISTIC_CBOR_NEGATIVE_MAX) {
540
+ return invalidCborInput();
541
+ }
542
+ return { type: "negative", value: rawValue };
543
+ default:
544
+ return invalidCborInput();
545
+ }
546
+ };
547
+ const validateDeterministicCborMapKey = (value, state) => {
548
+ state.nodes = consumeDeterministicCborBudget(state.nodes, 1, MAX_DETERMINISTIC_CBOR_NODES);
549
+ const object = requireDeterministicCborObject(value, ["type", "value"]);
550
+ const type = readDeterministicCborDataProperty(object.properties, "type");
551
+ if (typeof type !== "string") {
552
+ return invalidCborInput();
553
+ }
554
+ switch (type) {
555
+ case "integer":
556
+ return {
557
+ type: "integer",
558
+ value: validateDeterministicCborInteger(readDeterministicCborDataProperty(object.properties, "value")),
559
+ };
560
+ case "text": {
561
+ const text = readDeterministicCborDataProperty(object.properties, "value");
562
+ if (typeof text !== "string") {
563
+ return invalidCborInput();
564
+ }
565
+ consumeDeterministicCborText(state, text);
566
+ return { type: "text", value: text };
567
+ }
568
+ default:
569
+ return invalidCborInput();
570
+ }
571
+ };
572
+ const validateDeterministicCborValue = (value, depth, seen, state) => {
573
+ state.nodes = consumeDeterministicCborBudget(state.nodes, 1, MAX_DETERMINISTIC_CBOR_NODES);
574
+ const object = requireDeterministicCborObject(value, ["type", "value"]);
575
+ const type = readDeterministicCborDataProperty(object.properties, "type");
576
+ if (typeof type !== "string" || seen.has(object.owner)) {
577
+ return invalidCborInput();
578
+ }
579
+ seen.add(object.owner);
580
+ try {
581
+ switch (type) {
582
+ case "null":
583
+ if (object.properties.has("value")) {
584
+ return invalidCborInput();
585
+ }
586
+ return { type: "null" };
587
+ case "bool": {
588
+ const child = readDeterministicCborDataProperty(object.properties, "value");
589
+ if (typeof child !== "boolean") {
590
+ return invalidCborInput();
591
+ }
592
+ return { type: "bool", value: child };
593
+ }
594
+ case "integer":
73
595
  return {
74
- type: "array",
75
- value: value.value.map((entry) => validateCborValue(entry, childContainerDepth(depth), seen)),
596
+ type: "integer",
597
+ value: validateDeterministicCborInteger(readDeterministicCborDataProperty(object.properties, "value")),
76
598
  };
77
- case "map":
78
- if (!Array.isArray(value.value)) {
79
- throw new ReallyMeCodecError("invalid-input");
599
+ case "text": {
600
+ const child = readDeterministicCborDataProperty(object.properties, "value");
601
+ if (typeof child !== "string") {
602
+ return invalidCborInput();
603
+ }
604
+ consumeDeterministicCborText(state, child);
605
+ return { type: "text", value: child };
606
+ }
607
+ case "bytes": {
608
+ const child = readDeterministicCborDataProperty(object.properties, "value");
609
+ if (!(child instanceof Uint8Array)) {
610
+ return invalidCborInput();
80
611
  }
612
+ const copy = snapshotDeterministicCborBytes(child, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
613
+ // Register ownership before any subsequent budget check can fail so
614
+ // the outer cleanup scope wipes this snapshot on every error path.
615
+ state.ownedBytes.push(copy);
616
+ state.byteStringBytes = consumeDeterministicCborBudget(state.byteStringBytes, copy.length, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
617
+ return { type: "bytes", value: copy };
618
+ }
619
+ case "array": {
620
+ const children = snapshotDeterministicCborArray(readDeterministicCborDataProperty(object.properties, "value"));
621
+ return {
622
+ type: "array",
623
+ value: children.map((entry) => validateDeterministicCborValue(entry, requireDeterministicCborDepth(depth), seen, state)),
624
+ };
625
+ }
626
+ case "map": {
627
+ const entries = snapshotDeterministicCborArray(readDeterministicCborDataProperty(object.properties, "value"));
628
+ const keys = deterministicCborMapKeySet();
81
629
  return {
82
630
  type: "map",
83
- value: value.value.map((entry) => {
84
- if (!isRecord(entry) || typeof entry.key !== "string") {
85
- throw new ReallyMeCodecError("invalid-input");
86
- }
631
+ value: entries.map((entry) => {
632
+ const mapEntry = requireDeterministicCborObject(entry, [
633
+ "key",
634
+ "value",
635
+ ]);
636
+ const key = validateDeterministicCborMapKey(readDeterministicCborDataProperty(mapEntry.properties, "key"), state);
637
+ recordDeterministicCborMapKey(key, keys, invalidCborInput);
87
638
  return {
88
- key: entry.key,
89
- value: validateCborValue(entry.value, childContainerDepth(depth), seen),
639
+ key,
640
+ value: validateDeterministicCborValue(readDeterministicCborDataProperty(mapEntry.properties, "value"), requireDeterministicCborDepth(depth), seen, state),
90
641
  };
91
642
  }),
92
643
  };
644
+ }
93
645
  default:
94
- throw new ReallyMeCodecError("invalid-input");
646
+ return invalidCborInput();
95
647
  }
96
648
  }
97
649
  finally {
98
- seen.delete(value);
650
+ seen.delete(object.owner);
99
651
  }
100
652
  };
101
- const cborValueForJson = (value) => {
653
+ const normalizeDeterministicCborValue = (value) => {
654
+ const state = deterministicCborValidationState();
655
+ try {
656
+ return validateDeterministicCborValue(value, 0, new WeakSet(), state);
657
+ }
658
+ catch (error) {
659
+ wipeOwnedByteSnapshots(state);
660
+ if (error instanceof ReallyMeCodecError) {
661
+ throw error;
662
+ }
663
+ return invalidCborInput();
664
+ }
665
+ };
666
+ const deterministicCborIntegerToProto = (integer) => {
667
+ switch (integer.type) {
668
+ case "unsigned":
669
+ return create(CodecDeterministicCborIntegerSchema, {
670
+ value: {
671
+ case: "unsignedValue",
672
+ value: create(CodecDeterministicCborUnsignedIntegerSchema, {
673
+ value: integer.value,
674
+ }),
675
+ },
676
+ });
677
+ case "negative":
678
+ return create(CodecDeterministicCborIntegerSchema, {
679
+ value: {
680
+ case: "negativeValue",
681
+ value: create(CodecDeterministicCborNegativeIntegerSchema, {
682
+ value: integer.value,
683
+ }),
684
+ },
685
+ });
686
+ }
687
+ };
688
+ const deterministicCborMapKeyToProto = (key) => {
689
+ switch (key.type) {
690
+ case "integer":
691
+ return create(CodecDeterministicCborMapKeySchema, {
692
+ key: {
693
+ case: "integerKey",
694
+ value: deterministicCborIntegerToProto(key.value),
695
+ },
696
+ });
697
+ case "text":
698
+ return create(CodecDeterministicCborMapKeySchema, {
699
+ key: {
700
+ case: "textKey",
701
+ value: create(CodecDeterministicCborTextSchema, { value: key.value }),
702
+ },
703
+ });
704
+ }
705
+ };
706
+ const deterministicCborValueToProto = (value) => {
102
707
  switch (value.type) {
103
708
  case "null":
104
- return { type: "null" };
709
+ return create(CodecDeterministicCborValueSchema, {
710
+ value: {
711
+ case: "nullValue",
712
+ value: create(CodecDeterministicCborNullSchema),
713
+ },
714
+ });
105
715
  case "bool":
106
- case "string":
716
+ return create(CodecDeterministicCborValueSchema, {
717
+ value: {
718
+ case: "boolValue",
719
+ value: create(CodecDeterministicCborBoolSchema, { value: value.value }),
720
+ },
721
+ });
722
+ case "integer":
723
+ return create(CodecDeterministicCborValueSchema, {
724
+ value: {
725
+ case: "integerValue",
726
+ value: deterministicCborIntegerToProto(value.value),
727
+ },
728
+ });
729
+ case "text":
730
+ return create(CodecDeterministicCborValueSchema, {
731
+ value: {
732
+ case: "textValue",
733
+ value: create(CodecDeterministicCborTextSchema, { value: value.value }),
734
+ },
735
+ });
107
736
  case "bytes":
108
- return value;
109
- case "int":
110
- return {
111
- type: "int",
112
- value: typeof value.value === "bigint" ? value.value.toString() : value.value,
113
- };
737
+ return create(CodecDeterministicCborValueSchema, {
738
+ value: {
739
+ case: "bytesValue",
740
+ value: create(CodecDeterministicCborBytesSchema, { value: value.value }),
741
+ },
742
+ });
114
743
  case "array":
115
- return { type: "array", value: value.value.map(cborValueForJson) };
744
+ return create(CodecDeterministicCborValueSchema, {
745
+ value: {
746
+ case: "arrayValue",
747
+ value: create(CodecDeterministicCborArraySchema, {
748
+ values: value.value.map(deterministicCborValueToProto),
749
+ }),
750
+ },
751
+ });
116
752
  case "map":
753
+ return create(CodecDeterministicCborValueSchema, {
754
+ value: {
755
+ case: "mapValue",
756
+ value: create(CodecDeterministicCborMapSchema, {
757
+ entries: value.value.map((entry) => create(CodecDeterministicCborMapEntrySchema, {
758
+ key: deterministicCborMapKeyToProto(entry.key),
759
+ value: deterministicCborValueToProto(entry.value),
760
+ })),
761
+ }),
762
+ },
763
+ });
764
+ }
765
+ };
766
+ const providerFailure = () => {
767
+ throw new ReallyMeCodecError("provider-failure");
768
+ };
769
+ const requireNoProviderUnknownFields = (message) => {
770
+ if (message.$unknown !== undefined && message.$unknown.length !== 0) {
771
+ providerFailure();
772
+ }
773
+ };
774
+ const consumeProviderDeterministicCborBudget = (current, amount, maximum) => {
775
+ if (!Number.isSafeInteger(amount) ||
776
+ amount < 0 ||
777
+ current > maximum - amount) {
778
+ return providerFailure();
779
+ }
780
+ return current + amount;
781
+ };
782
+ const providerDeterministicCborUtf8ByteLength = (value) => {
783
+ try {
784
+ return strictUtf8ByteLength(value);
785
+ }
786
+ catch (_error) {
787
+ return providerFailure();
788
+ }
789
+ };
790
+ const consumeProviderDeterministicCborText = (state, value) => {
791
+ if (state.textBytes >
792
+ MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES - value.length) {
793
+ providerFailure();
794
+ }
795
+ state.textBytes = consumeProviderDeterministicCborBudget(state.textBytes, providerDeterministicCborUtf8ByteLength(value), MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES);
796
+ };
797
+ const deterministicCborIntegerFromProto = (integer) => {
798
+ requireNoProviderUnknownFields(integer);
799
+ switch (integer.value.case) {
800
+ case "unsignedValue": {
801
+ requireNoProviderUnknownFields(integer.value.value);
802
+ const value = integer.value.value.value;
803
+ if (value < 0n || value > DETERMINISTIC_CBOR_U64_MAX) {
804
+ return providerFailure();
805
+ }
806
+ return { type: "unsigned", value };
807
+ }
808
+ case "negativeValue": {
809
+ requireNoProviderUnknownFields(integer.value.value);
810
+ const value = integer.value.value.value;
811
+ if (value < DETERMINISTIC_CBOR_I64_MIN ||
812
+ value > DETERMINISTIC_CBOR_NEGATIVE_MAX) {
813
+ return providerFailure();
814
+ }
815
+ return { type: "negative", value };
816
+ }
817
+ case undefined:
818
+ return providerFailure();
819
+ }
820
+ };
821
+ const deterministicCborMapKeyFromProto = (key, state) => {
822
+ requireNoProviderUnknownFields(key);
823
+ state.nodes = consumeProviderDeterministicCborBudget(state.nodes, 1, MAX_DETERMINISTIC_CBOR_NODES);
824
+ switch (key.key.case) {
825
+ case "integerKey":
826
+ return {
827
+ type: "integer",
828
+ value: deterministicCborIntegerFromProto(key.key.value),
829
+ };
830
+ case "textKey": {
831
+ requireNoProviderUnknownFields(key.key.value);
832
+ consumeProviderDeterministicCborText(state, key.key.value.value);
833
+ return { type: "text", value: key.key.value.value };
834
+ }
835
+ case undefined:
836
+ return providerFailure();
837
+ }
838
+ };
839
+ const deterministicCborValueFromProto = (value, depth, state) => {
840
+ if (value === undefined) {
841
+ return providerFailure();
842
+ }
843
+ requireNoProviderUnknownFields(value);
844
+ state.nodes = consumeProviderDeterministicCborBudget(state.nodes, 1, MAX_DETERMINISTIC_CBOR_NODES);
845
+ switch (value.value.case) {
846
+ case "nullValue":
847
+ requireNoProviderUnknownFields(value.value.value);
848
+ return { type: "null" };
849
+ case "boolValue":
850
+ requireNoProviderUnknownFields(value.value.value);
851
+ return { type: "bool", value: value.value.value.value };
852
+ case "integerValue":
853
+ return {
854
+ type: "integer",
855
+ value: deterministicCborIntegerFromProto(value.value.value),
856
+ };
857
+ case "textValue": {
858
+ requireNoProviderUnknownFields(value.value.value);
859
+ const text = value.value.value.value;
860
+ consumeProviderDeterministicCborText(state, text);
861
+ return { type: "text", value: text };
862
+ }
863
+ case "bytesValue": {
864
+ requireNoProviderUnknownFields(value.value.value);
865
+ const bytes = value.value.value.value;
866
+ state.byteStringBytes = consumeProviderDeterministicCborBudget(state.byteStringBytes, bytes.length, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
867
+ const copy = bytes.slice();
868
+ state.ownedBytes.push(copy);
869
+ return { type: "bytes", value: copy };
870
+ }
871
+ case "arrayValue": {
872
+ requireNoProviderUnknownFields(value.value.value);
873
+ const values = value.value.value.values;
874
+ if (values.length > MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES ||
875
+ depth >= MAX_DETERMINISTIC_CBOR_NESTING_DEPTH) {
876
+ return providerFailure();
877
+ }
878
+ return {
879
+ type: "array",
880
+ value: values.map((entry) => deterministicCborValueFromProto(entry, depth + 1, state)),
881
+ };
882
+ }
883
+ case "mapValue": {
884
+ requireNoProviderUnknownFields(value.value.value);
885
+ const entries = value.value.value.entries;
886
+ if (entries.length > MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES ||
887
+ depth >= MAX_DETERMINISTIC_CBOR_NESTING_DEPTH) {
888
+ return providerFailure();
889
+ }
890
+ const keys = deterministicCborMapKeySet();
117
891
  return {
118
892
  type: "map",
119
- value: value.value.map((entry) => ({
120
- key: entry.key,
121
- value: cborValueForJson(entry.value),
122
- })),
893
+ value: entries.map((entry) => {
894
+ requireNoProviderUnknownFields(entry);
895
+ if (entry.key === undefined) {
896
+ return providerFailure();
897
+ }
898
+ const key = deterministicCborMapKeyFromProto(entry.key, state);
899
+ recordDeterministicCborMapKey(key, keys, providerFailure);
900
+ return {
901
+ key,
902
+ value: deterministicCborValueFromProto(entry.value, depth + 1, state),
903
+ };
904
+ }),
123
905
  };
906
+ }
907
+ case undefined:
908
+ return providerFailure();
909
+ }
910
+ };
911
+ const wipeDeterministicCborValueBytes = (value) => {
912
+ switch (value.type) {
913
+ case "bytes":
914
+ value.value.fill(0);
915
+ break;
916
+ case "array":
917
+ for (const child of value.value) {
918
+ wipeDeterministicCborValueBytes(child);
919
+ }
920
+ break;
921
+ case "map":
922
+ for (const entry of value.value) {
923
+ wipeDeterministicCborValueBytes(entry.value);
924
+ }
925
+ break;
926
+ case "null":
927
+ case "bool":
928
+ case "integer":
929
+ case "text":
930
+ break;
124
931
  }
125
932
  };
126
- const readCborValue = (json) => {
127
- const parsed = JSON.parse(json);
128
- return validateCborValue(parsed);
933
+ const wipeProtoDeterministicCborValueBytes = (value) => {
934
+ if (value === undefined) {
935
+ return;
936
+ }
937
+ switch (value.value.case) {
938
+ case "bytesValue":
939
+ value.value.value.value.fill(0);
940
+ break;
941
+ case "arrayValue":
942
+ for (const child of value.value.value.values) {
943
+ wipeProtoDeterministicCborValueBytes(child);
944
+ }
945
+ break;
946
+ case "mapValue":
947
+ for (const entry of value.value.value.entries) {
948
+ wipeProtoDeterministicCborValueBytes(entry.value);
949
+ }
950
+ break;
951
+ case "nullValue":
952
+ case "boolValue":
953
+ case "integerValue":
954
+ case "textValue":
955
+ case undefined:
956
+ break;
957
+ }
129
958
  };
130
- const readCidVerification = (value) => {
131
- const object = readObjectOutput(value);
132
- return {
133
- valid: readBooleanProperty(object, "valid"),
134
- expectedCid: readStringProperty(object, "expectedCid"),
135
- actualCid: readStringValueProperty(object, "actualCid"),
136
- };
959
+ const dagCborIntegerToProto = (value) => {
960
+ const integer = typeof value === "bigint" ? value : BigInt(value);
961
+ if (integer < i64Min || integer > i64Max) {
962
+ return invalidCborInput();
963
+ }
964
+ if (integer < 0n) {
965
+ return create(CodecDeterministicCborIntegerSchema, {
966
+ value: {
967
+ case: "negativeValue",
968
+ value: create(CodecDeterministicCborNegativeIntegerSchema, {
969
+ value: integer,
970
+ }),
971
+ },
972
+ });
973
+ }
974
+ return create(CodecDeterministicCborIntegerSchema, {
975
+ value: {
976
+ case: "unsignedValue",
977
+ value: create(CodecDeterministicCborUnsignedIntegerSchema, {
978
+ value: integer,
979
+ }),
980
+ },
981
+ });
982
+ };
983
+ const dagCborValueToProto = (value) => {
984
+ switch (value.type) {
985
+ case "null":
986
+ return create(CodecDeterministicCborValueSchema, {
987
+ value: {
988
+ case: "nullValue",
989
+ value: create(CodecDeterministicCborNullSchema),
990
+ },
991
+ });
992
+ case "bool":
993
+ return create(CodecDeterministicCborValueSchema, {
994
+ value: {
995
+ case: "boolValue",
996
+ value: create(CodecDeterministicCborBoolSchema, { value: value.value }),
997
+ },
998
+ });
999
+ case "int":
1000
+ return create(CodecDeterministicCborValueSchema, {
1001
+ value: {
1002
+ case: "integerValue",
1003
+ value: dagCborIntegerToProto(value.value),
1004
+ },
1005
+ });
1006
+ case "string":
1007
+ return create(CodecDeterministicCborValueSchema, {
1008
+ value: {
1009
+ case: "textValue",
1010
+ value: create(CodecDeterministicCborTextSchema, { value: value.value }),
1011
+ },
1012
+ });
1013
+ case "bytes": {
1014
+ const bytes = value.value.slice();
1015
+ try {
1016
+ const bytesValue = create(CodecDeterministicCborBytesSchema, { value: bytes });
1017
+ return create(CodecDeterministicCborValueSchema, {
1018
+ value: {
1019
+ case: "bytesValue",
1020
+ value: bytesValue,
1021
+ },
1022
+ });
1023
+ }
1024
+ catch (error) {
1025
+ bytes.fill(0);
1026
+ throw error;
1027
+ }
1028
+ }
1029
+ case "array": {
1030
+ const values = [];
1031
+ try {
1032
+ for (const child of value.value) {
1033
+ values.push(dagCborValueToProto(child));
1034
+ }
1035
+ return create(CodecDeterministicCborValueSchema, {
1036
+ value: {
1037
+ case: "arrayValue",
1038
+ value: create(CodecDeterministicCborArraySchema, { values }),
1039
+ },
1040
+ });
1041
+ }
1042
+ catch (error) {
1043
+ for (const child of values) {
1044
+ wipeProtoDeterministicCborValueBytes(child);
1045
+ }
1046
+ throw error;
1047
+ }
1048
+ }
1049
+ case "map": {
1050
+ const entries = [];
1051
+ try {
1052
+ for (const entry of value.value) {
1053
+ const entryValue = dagCborValueToProto(entry.value);
1054
+ try {
1055
+ entries.push(create(CodecDeterministicCborMapEntrySchema, {
1056
+ key: create(CodecDeterministicCborMapKeySchema, {
1057
+ key: {
1058
+ case: "textKey",
1059
+ value: create(CodecDeterministicCborTextSchema, {
1060
+ value: entry.key,
1061
+ }),
1062
+ },
1063
+ }),
1064
+ value: entryValue,
1065
+ }));
1066
+ }
1067
+ catch (error) {
1068
+ wipeProtoDeterministicCborValueBytes(entryValue);
1069
+ throw error;
1070
+ }
1071
+ }
1072
+ return create(CodecDeterministicCborValueSchema, {
1073
+ value: {
1074
+ case: "mapValue",
1075
+ value: create(CodecDeterministicCborMapSchema, { entries }),
1076
+ },
1077
+ });
1078
+ }
1079
+ catch (error) {
1080
+ for (const entry of entries) {
1081
+ wipeProtoDeterministicCborValueBytes(entry.value);
1082
+ }
1083
+ throw error;
1084
+ }
1085
+ }
1086
+ }
1087
+ };
1088
+ const dagCborValueFromDeterministic = (value) => {
1089
+ switch (value.type) {
1090
+ case "null":
1091
+ return { type: "null" };
1092
+ case "bool":
1093
+ return { type: "bool", value: value.value };
1094
+ case "integer": {
1095
+ const integer = value.value.value;
1096
+ if (integer < i64Min || integer > i64Max) {
1097
+ return providerFailure();
1098
+ }
1099
+ return { type: "int", value: integer };
1100
+ }
1101
+ case "text":
1102
+ return { type: "string", value: value.value };
1103
+ case "bytes":
1104
+ return { type: "bytes", value: value.value.slice() };
1105
+ case "array": {
1106
+ const values = [];
1107
+ try {
1108
+ for (const child of value.value) {
1109
+ values.push(dagCborValueFromDeterministic(child));
1110
+ }
1111
+ return {
1112
+ type: "array",
1113
+ value: values,
1114
+ };
1115
+ }
1116
+ catch (error) {
1117
+ for (const child of values) {
1118
+ wipeDagCborValueBytes(child);
1119
+ }
1120
+ throw error;
1121
+ }
1122
+ }
1123
+ case "map": {
1124
+ const entries = [];
1125
+ try {
1126
+ for (const entry of value.value) {
1127
+ if (entry.key.type !== "text") {
1128
+ return providerFailure();
1129
+ }
1130
+ entries.push({
1131
+ key: entry.key.value,
1132
+ value: dagCborValueFromDeterministic(entry.value),
1133
+ });
1134
+ }
1135
+ return {
1136
+ type: "map",
1137
+ value: entries,
1138
+ };
1139
+ }
1140
+ catch (error) {
1141
+ for (const entry of entries) {
1142
+ wipeDagCborValueBytes(entry.value);
1143
+ }
1144
+ throw error;
1145
+ }
1146
+ }
1147
+ }
137
1148
  };
138
1149
  export const dagCborEncode = (value) => {
139
- const normalized = validateCborValue(value);
140
- return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborEncode(JSON.stringify(cborValueForJson(normalized))));
1150
+ let normalized;
1151
+ try {
1152
+ normalized = validateCborValue(value);
1153
+ }
1154
+ catch (error) {
1155
+ if (error instanceof ReallyMeCodecError) {
1156
+ throw error;
1157
+ }
1158
+ return invalidCborInput();
1159
+ }
1160
+ let protoValue;
1161
+ try {
1162
+ protoValue = dagCborValueToProto(normalized);
1163
+ const operationResult = processGeneratedOperationRequest(create(CodecOperationRequestSchema, {
1164
+ operation: {
1165
+ case: "dagCborEncode",
1166
+ value: create(CodecDagCborEncodeRequestSchema, {
1167
+ value: protoValue,
1168
+ }),
1169
+ },
1170
+ }));
1171
+ if (operationResult.result.case !== "dagCborEncode") {
1172
+ clearGeneratedOperationResult(operationResult);
1173
+ throw new ReallyMeCodecError("provider-failure");
1174
+ }
1175
+ const result = operationResult.result.value;
1176
+ try {
1177
+ requireNoProviderUnknownFields(result);
1178
+ if (result.encoded.length === 0 ||
1179
+ result.encoded.length > maxDagCborInputLength) {
1180
+ return providerFailure();
1181
+ }
1182
+ return result.encoded.slice();
1183
+ }
1184
+ catch (error) {
1185
+ if (error instanceof ReallyMeCodecError) {
1186
+ throw error;
1187
+ }
1188
+ throw new ReallyMeCodecError("provider-failure");
1189
+ }
1190
+ finally {
1191
+ result.encoded.fill(0);
1192
+ }
1193
+ }
1194
+ finally {
1195
+ wipeProtoDeterministicCborValueBytes(protoValue);
1196
+ wipeDagCborValueBytes(normalized);
1197
+ }
141
1198
  };
142
1199
  export const dagCborDecode = (bytes) => {
143
1200
  ensureBytesInput(bytes);
144
- return readCborValue(readStringOutput(requireReallyMeCodecWasmProvider().dagCborDecode(bytes)));
1201
+ if (bytes.length > maxDagCborInputLength) {
1202
+ throw new ReallyMeCodecError("invalid-input");
1203
+ }
1204
+ const requestBytes = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
1205
+ try {
1206
+ const operationResult = processGeneratedOperationRequest(create(CodecOperationRequestSchema, {
1207
+ operation: {
1208
+ case: "dagCborDecode",
1209
+ value: create(CodecDagCborDecodeRequestSchema, {
1210
+ encoded: requestBytes,
1211
+ }),
1212
+ },
1213
+ }));
1214
+ if (operationResult.result.case !== "dagCborDecode") {
1215
+ clearGeneratedOperationResult(operationResult);
1216
+ throw new ReallyMeCodecError("provider-failure");
1217
+ }
1218
+ const result = operationResult.result.value;
1219
+ const state = deterministicCborValidationState();
1220
+ let normalized;
1221
+ try {
1222
+ requireNoProviderUnknownFields(result);
1223
+ normalized = deterministicCborValueFromProto(result.value, 0, state);
1224
+ return dagCborValueFromDeterministic(normalized);
1225
+ }
1226
+ catch (error) {
1227
+ if (error instanceof ReallyMeCodecError) {
1228
+ throw error;
1229
+ }
1230
+ throw new ReallyMeCodecError("provider-failure");
1231
+ }
1232
+ finally {
1233
+ wipeOwnedByteSnapshots(state);
1234
+ if (normalized !== undefined) {
1235
+ wipeDeterministicCborValueBytes(normalized);
1236
+ }
1237
+ wipeProtoDeterministicCborValueBytes(result.value);
1238
+ }
1239
+ }
1240
+ finally {
1241
+ requestBytes.fill(0);
1242
+ }
145
1243
  };
146
- export const dagCborComputeCid = (bytes) => {
147
- ensureBytesInput(bytes);
148
- return readStringOutput(requireReallyMeCodecWasmProvider().dagCborComputeCid(bytes));
1244
+ export const deterministicCborEncode = (value) => {
1245
+ const normalized = normalizeDeterministicCborValue(value);
1246
+ let protoValue;
1247
+ try {
1248
+ protoValue = deterministicCborValueToProto(normalized);
1249
+ const operationResult = processGeneratedOperationRequest(create(CodecOperationRequestSchema, {
1250
+ operation: {
1251
+ case: "deterministicCborEncode",
1252
+ value: create(CodecDeterministicCborEncodeRequestSchema, {
1253
+ value: protoValue,
1254
+ }),
1255
+ },
1256
+ }));
1257
+ if (operationResult.result.case !== "deterministicCborEncode") {
1258
+ clearGeneratedOperationResult(operationResult);
1259
+ throw new ReallyMeCodecError("provider-failure");
1260
+ }
1261
+ const result = operationResult.result.value;
1262
+ try {
1263
+ requireNoProviderUnknownFields(result);
1264
+ if (result.encoded.length === 0 ||
1265
+ result.encoded.length > MAX_DETERMINISTIC_CBOR_OUTPUT_LEN) {
1266
+ throw new ReallyMeCodecError("provider-failure");
1267
+ }
1268
+ return result.encoded.slice();
1269
+ }
1270
+ finally {
1271
+ result.encoded.fill(0);
1272
+ }
1273
+ }
1274
+ finally {
1275
+ wipeProtoDeterministicCborValueBytes(protoValue);
1276
+ wipeDeterministicCborValueBytes(normalized);
1277
+ }
149
1278
  };
150
- export const dagCborVerifyCid = (cid, bytes) => {
151
- ensureStringValue(cid);
1279
+ export const deterministicCborDecode = (bytes) => {
152
1280
  ensureBytesInput(bytes);
153
- return readCidVerification(requireReallyMeCodecWasmProvider().dagCborVerifyCid(cid, bytes));
1281
+ if (bytes.length > MAX_DETERMINISTIC_CBOR_INPUT_LEN) {
1282
+ throw new ReallyMeCodecError("invalid-input");
1283
+ }
1284
+ const requestBytes = snapshotDeterministicCborBytes(bytes, MAX_DETERMINISTIC_CBOR_INPUT_LEN);
1285
+ try {
1286
+ const operationResult = processGeneratedOperationRequest(create(CodecOperationRequestSchema, {
1287
+ operation: {
1288
+ case: "deterministicCborDecode",
1289
+ value: create(CodecDeterministicCborDecodeRequestSchema, {
1290
+ encoded: requestBytes,
1291
+ }),
1292
+ },
1293
+ }));
1294
+ if (operationResult.result.case !== "deterministicCborDecode") {
1295
+ clearGeneratedOperationResult(operationResult);
1296
+ throw new ReallyMeCodecError("provider-failure");
1297
+ }
1298
+ const result = operationResult.result.value;
1299
+ const state = deterministicCborValidationState();
1300
+ try {
1301
+ requireNoProviderUnknownFields(result);
1302
+ return deterministicCborValueFromProto(result.value, 0, state);
1303
+ }
1304
+ catch (error) {
1305
+ wipeOwnedByteSnapshots(state);
1306
+ throw error;
1307
+ }
1308
+ finally {
1309
+ wipeProtoDeterministicCborValueBytes(result.value);
1310
+ }
1311
+ }
1312
+ finally {
1313
+ requestBytes.fill(0);
1314
+ }
154
1315
  };
155
- export const dagCborVerifyCidProto = (cid, bytes) => {
156
- ensureStringValue(cid);
1316
+ export const dagCborComputeCid = (bytes) => {
157
1317
  ensureBytesInput(bytes);
158
- return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborVerifyCidProto(cid, bytes));
1318
+ return readStringOutput(requireReallyMeCodecWasmProvider().dagCborComputeCid(bytes));
159
1319
  };
160
- export const dagCborVerifyCidProtoResult = (cid, bytes) => {
1320
+ export const dagCborVerifyCid = (cid, bytes) => {
161
1321
  ensureStringValue(cid);
162
1322
  ensureBytesInput(bytes);
163
- return readProtoResultOutput(requireReallyMeCodecWasmProvider().dagCborVerifyCidProtoResult(cid, bytes));
1323
+ const payloadSnapshot = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
1324
+ try {
1325
+ const operationResult = processGeneratedOperationRequest(dagCborVerifyCidRequest(cid, payloadSnapshot));
1326
+ if (operationResult.result.case !== "dagCborVerifyCid") {
1327
+ clearGeneratedOperationResult(operationResult);
1328
+ throw new ReallyMeCodecError("provider-failure");
1329
+ }
1330
+ const result = operationResult.result.value;
1331
+ requireNoProviderUnknownFields(result);
1332
+ return {
1333
+ valid: result.valid,
1334
+ expectedCid: result.expectedCid,
1335
+ actualCid: result.actualCid,
1336
+ };
1337
+ }
1338
+ finally {
1339
+ payloadSnapshot.fill(0);
1340
+ }
164
1341
  };
1342
+ const dagCborVerifyCidRequest = (cid, bytes) => create(CodecOperationRequestSchema, {
1343
+ operation: {
1344
+ case: "dagCborVerifyCid",
1345
+ value: create(CodecDagCborVerifyCidRequestSchema, {
1346
+ cid,
1347
+ payload: bytes,
1348
+ }),
1349
+ },
1350
+ });
165
1351
  export const dagCborSha256ContentHash = (bytes) => {
166
1352
  ensureBytesInput(bytes);
167
1353
  return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborSha256ContentHash(bytes));