Skip to content

Commit c1593d3

Browse files
committed
fix: improved implementation of compatibility mode based on #209
1 parent d66a1fb commit c1593d3

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

packages/core/src/molecule/codec.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class Codec<Encodable, Decoded = Encodable> {
4949
}
5050
return encoded;
5151
},
52-
(decodable, config = { isExtraFieldIgnored: false }) => {
52+
(decodable, config) => {
5353
const decodableBytes = bytesFrom(decodable);
5454
if (
5555
byteLength !== undefined &&
@@ -75,7 +75,7 @@ export class Codec<Encodable, Decoded = Encodable> {
7575
return new Codec(
7676
(encodable) =>
7777
this.encode((inMap ? inMap(encodable) : encodable) as Encodable),
78-
(buffer, config = { isExtraFieldIgnored: false }) =>
78+
(buffer, config) =>
7979
(outMap
8080
? outMap(this.decode(buffer, config))
8181
: this.decode(buffer, config)) as NewDecoded,
@@ -388,15 +388,38 @@ export function table<
388388
);
389389
}
390390
const byteLength = uint32From(value.slice(0, 4));
391+
const headerLength = uint32From(value.slice(4, 8));
392+
const actualFieldCount = (headerLength - 4) / 4;
393+
391394
if (byteLength !== value.byteLength) {
392395
throw new Error(
393396
`table: invalid buffer size, expected ${byteLength}, but got ${value.byteLength}`,
394397
);
395398
}
399+
400+
if (actualFieldCount < keys.length) {
401+
throw new Error(
402+
`table: invalid field count, expected ${keys.length}, but got ${actualFieldCount}`,
403+
);
404+
}
405+
406+
if (actualFieldCount > keys.length && !config?.isExtraFieldIgnored) {
407+
throw new Error(
408+
`table: invalid field count, expected ${keys.length}, but got ${actualFieldCount}, and extra fields are not allowed in the current configuration. If you want to ignore extra fields, set isExtraFieldIgnored to true.`,
409+
);
410+
}
396411
const offsets = keys.map((_, index) =>
397412
uint32From(value.slice(4 + index * 4, 8 + index * 4)),
398413
);
399-
offsets.push(byteLength);
414+
// If there are extra fields, add the last offset to the offsets array
415+
if (actualFieldCount > keys.length) {
416+
offsets.push(
417+
uint32From(value.slice(4 + keys.length * 4, 8 + keys.length * 4)),
418+
);
419+
} else {
420+
// If there are no extra fields, add the byte length to the offsets array
421+
offsets.push(byteLength);
422+
}
400423
const object = {};
401424
for (let i = 0; i < offsets.length - 1; i++) {
402425
const start = offsets[i];
@@ -408,11 +431,7 @@ export function table<
408431
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
409432
Object.assign(object, { [field]: codec.decode(payload, config) });
410433
} catch (_e: unknown) {
411-
if (config?.isExtraFieldIgnored) {
412-
Object.assign(object, { [field]: null });
413-
} else {
414-
throw new Error(`table.${field}(${_e?.toString()})`);
415-
}
434+
throw new Error(`table.${field}(${_e?.toString()})`);
416435
}
417436
}
418437
return object as Decoded;

0 commit comments

Comments
 (0)