Skip to content

Commit 541a18f

Browse files
authored
fix(core/cbor): fix date deserialization in schema mode (#1800)
1 parent 3d686c0 commit 541a18f

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

.changeset/sixty-colts-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smithy/core": patch
3+
---
4+
5+
fix for CBOR date deserialization

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

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { NormalizedSchema } from "@smithy/core/schema";
2-
import type { StaticSimpleSchema, StaticStructureSchema, StringSchema } from "@smithy/types";
2+
import type { StaticSimpleSchema, StaticStructureSchema, StringSchema, TimestampDefaultSchema } from "@smithy/types";
33
import { describe, expect, it } from "vitest";
44

55
import { cbor } from "./cbor";
66
import { CborCodec, CborShapeSerializer } from "./CborCodec";
7+
import { tagSymbol } from "./cbor-types";
78

89
describe(CborShapeSerializer.name, () => {
910
const codec = new CborCodec();
@@ -22,6 +23,16 @@ describe(CborShapeSerializer.name, () => {
2223
];
2324

2425
const serializer = codec.createSerializer();
26+
const deserializer = codec.createDeserializer();
27+
28+
const dateSchema = [
29+
3,
30+
"ns",
31+
"DateContainer",
32+
0,
33+
["timestamp"],
34+
[4 satisfies TimestampDefaultSchema],
35+
] satisfies StaticStructureSchema;
2536

2637
describe("serialization", () => {
2738
it("should generate an idempotency token when the input for such a member is undefined", () => {
@@ -69,12 +80,25 @@ describe(CborShapeSerializer.name, () => {
6980
}
7081
}
7182
});
83+
84+
it("should serialize Dates to tags if the schema is a timestamp", () => {
85+
serializer.write(dateSchema, { timestamp: new Date(1) });
86+
const serialization = serializer.flush();
87+
88+
const parsedWithoutSchema = cbor.deserialize(serialization);
89+
expect(parsedWithoutSchema).toEqual({
90+
timestamp: {
91+
tag: 1,
92+
value: 0.001,
93+
[tagSymbol]: true,
94+
},
95+
});
96+
});
7297
});
7398

7499
describe("deserialization", () => {
75100
it("should not create undefined values", async () => {
76101
const struct = [3, "ns", "Struct", 0, ["sessionId", "tokenId"], [0, 0]] satisfies StaticStructureSchema;
77-
const deserializer = codec.createDeserializer();
78102

79103
const data = cbor.serialize({
80104
sessionId: "abcd",
@@ -88,5 +112,21 @@ describe(CborShapeSerializer.name, () => {
88112

89113
expect("tokenId" in deserialized).toEqual(false);
90114
});
115+
116+
it("should deserialize tags to dates if the schema is a timestamp", async () => {
117+
const decoded = {
118+
timestamp: {
119+
tag: 1,
120+
value: 0.001,
121+
[tagSymbol]: true,
122+
},
123+
};
124+
125+
const deserialized = await deserializer.read(dateSchema, cbor.serialize(decoded));
126+
127+
expect(deserialized).toEqual({
128+
timestamp: new Date(1),
129+
});
130+
});
91131
});
92132
});

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,16 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
130130
public readValue(_schema: Schema, value: any): any {
131131
const ns = NormalizedSchema.of(_schema);
132132

133-
if (ns.isTimestampSchema() && typeof value === "number") {
134-
// format is ignored.
135-
return _parseEpochTimestamp(value);
133+
if (ns.isTimestampSchema()) {
134+
// timestampFormat is ignored.
135+
if (typeof value === "number") {
136+
return _parseEpochTimestamp(value);
137+
}
138+
if (typeof value === "object") {
139+
if (value.tag === 1 && "value" in value) {
140+
return _parseEpochTimestamp(value.value);
141+
}
142+
}
136143
}
137144

138145
if (ns.isBlobSchema()) {
@@ -151,7 +158,7 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
151158
typeof value === "symbol"
152159
) {
153160
return value;
154-
} else if (typeof value === "function" || typeof value === "object") {
161+
} else if (typeof value === "object") {
155162
if (value === null) {
156163
return null;
157164
}

0 commit comments

Comments
 (0)