Skip to content

Commit 21d3c60

Browse files
committed
11 remaining test cases
1 parent ea43f67 commit 21d3c60

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

packages/core/src/submodules/cbor/cbor.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,15 @@ describe("cbor", () => {
176176
const bytes = toBytes(input);
177177
const jsObject = translateTestData(_expect);
178178

179-
xit(`serialization for ${description}`, () => {
179+
it(`serialization for ${description}`, () => {
180180
const serialized = cbor.serialize(jsObject);
181-
expect(serialized).toEqual(bytes);
181+
const redeserialized = cbor.deserialize(serialized);
182+
/**
183+
* We cannot assert that serialized == bytes,
184+
* because there are multiple serializations
185+
* that deserialize to the same object.
186+
*/
187+
expect(redeserialized).toEqual(jsObject);
182188
});
183189
it(`deserialization for ${description}`, () => {
184190
const deserialized = cbor.deserialize(bytes);

packages/core/src/submodules/cbor/cbor.ts

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ import { fromUtf8, toUtf8 } from "@smithy/util-utf8";
1010
/**
1111
*
1212
*/
13-
type CborItemType = undefined | boolean | number | [CborSliceType, Uint64Imprecise] | string | CborTagType;
13+
type CborItemType =
14+
| undefined
15+
| boolean
16+
| number
17+
| [CborUnstructuredByteStringType, Uint64Imprecise]
18+
| string
19+
| CborTagType;
1420
type CborTagType = {
1521
tag: Uint64Imprecise;
1622
value: CborValueType;
1723
};
18-
type CborSliceType = Uint8Array;
24+
type CborUnstructuredByteStringType = Uint8Array;
1925
type CborListType<T = any> = Array<T>;
2026
type CborMapType<T = any> = Record<string, T>;
2127
type CborCollectionType<T = any> = CborMapType<T> | CborListType<T>;
@@ -174,38 +180,43 @@ const decodeNegativeInt = (payload: Uint8Array): [Uint64Imprecise, CborArgumentL
174180
return [-1 - i, offset];
175181
};
176182

183+
const decodeUnstructuredByteString = (payload: Uint8Array): [CborUnstructuredByteStringType, CborOffset] => {
184+
return decodeString(payload, majorUnstructuredByteString);
185+
};
186+
187+
const decodeUtf8String = (payload: Uint8Array): [string, CborOffset] => {
188+
return decodeString(payload, majorUtf8String);
189+
};
190+
177191
const decodeString = <M extends typeof majorUtf8String | typeof majorUnstructuredByteString>(
178192
payload: Uint8Array,
179193
inner: M
180-
): [M extends typeof majorUtf8String ? string : CborSliceType, CborOffset] => {
194+
): [M extends typeof majorUtf8String ? string : CborUnstructuredByteStringType, CborOffset] => {
181195
const minor = peekMinor(payload);
196+
182197
if (minor === minorIndefinite) {
183-
return decodeUnstructuredByteStringIndefinite(payload) as [
184-
M extends typeof majorUtf8String ? string : CborSliceType,
198+
const [decoded, offset] = decodeStringIndefinite(payload, inner);
199+
return (inner === majorUnstructuredByteString ? [decoded, offset] : [toUtf8(decoded), offset]) as [
200+
M extends typeof majorUtf8String ? string : CborUnstructuredByteStringType,
185201
CborOffset,
186202
];
187203
}
188204

189205
const [length, offset] = decodeArgument(payload);
190206
payload = payload.subarray(offset);
191207
if (payload.length < length) {
192-
throw new Error(`slice len ${length} greater than remaining buf len.`);
208+
throw new Error(`unstructured byte string len ${length} greater than remaining buf len.`);
193209
}
194210

195211
const value =
196212
inner === majorUnstructuredByteString ? payload.subarray(0, length) : toUtf8(payload.subarray(0, length));
197-
return [value as M extends typeof majorUtf8String ? string : CborSliceType, offset + length];
213+
return [value as M extends typeof majorUtf8String ? string : CborUnstructuredByteStringType, offset + length];
198214
};
199215

200-
const decodeUnstructuredByteString = (payload: Uint8Array): [CborSliceType, CborOffset] => {
201-
return decodeString(payload, majorUnstructuredByteString);
202-
};
203-
204-
const decodeUtf8String = (payload: Uint8Array): [string, CborOffset] => {
205-
return decodeString(payload, majorUtf8String);
206-
};
207-
208-
const decodeUnstructuredByteStringIndefinite = (payload: Uint8Array): [CborSliceType, CborOffset] => {
216+
const decodeStringIndefinite = <I extends typeof majorUtf8String | typeof majorUnstructuredByteString>(
217+
payload: Uint8Array,
218+
inner: I
219+
): [CborUnstructuredByteStringType, CborOffset] => {
209220
payload = payload.subarray(1);
210221

211222
const buffer = [];
@@ -217,18 +228,24 @@ const decodeUnstructuredByteStringIndefinite = (payload: Uint8Array): [CborSlice
217228

218229
const major = peekMajor(payload);
219230
const minor = peekMinor(payload);
220-
if (major !== majorUnstructuredByteString) {
221-
throw new Error(`unexpected major type ${major} in indefinite slice.`);
231+
if (major !== inner) {
232+
throw new Error(`unexpected major type ${major} in indefinite string.`);
222233
}
223234
if (minor === minorIndefinite) {
224-
throw new Error("nested indefinite slice.");
235+
throw new Error("nested indefinite string.");
225236
}
226237

227-
const [byteString, length] = decodeUnstructuredByteString(payload);
228-
payload = payload.subarray(length);
229-
230-
buffer.push(byteString);
231-
offset += length;
238+
if (inner === majorUtf8String) {
239+
const [str, length] = decodeUtf8String(payload);
240+
payload = payload.subarray(length);
241+
buffer.push(fromUtf8(str));
242+
offset += length;
243+
} else {
244+
const [byteString, length] = decodeUnstructuredByteString(payload);
245+
payload = payload.subarray(length);
246+
buffer.push(byteString);
247+
offset += length;
248+
}
232249
}
233250
throw new Error("expected break marker.");
234251
};
@@ -530,6 +547,11 @@ const encode = (input: any, buffer: Uint8Array): CborOffset => {
530547
offset += encode(vv, buffer.subarray(offset));
531548
}
532549
return offset;
550+
} else if (input instanceof Uint8Array) {
551+
// serialize as UnstructuredByteString
552+
const offset = encodeHeader(majorUnstructuredByteString, input.length, buffer);
553+
buffer.subarray(offset).set(input);
554+
return offset + input.length;
533555
} else if (typeof input === "object") {
534556
const entries = Object.entries(input).filter(([, v]) => {
535557
return v !== undefined;

0 commit comments

Comments
 (0)