Skip to content

Commit 884b0ff

Browse files
authored
fix(kernel): json deserialization fails on null value (#4000)
The JSON serialization class is a quasi-synonym for `Map<string, any>`, except it is meant to accept any valid JSON object, including one with `null` values. The serializer was however interpreting these as `Map<string, JSON>` when wired as a `$jsii.map` envelope, and this serialization class does NOT allow for null values. Addresses the "easy" part of aws/aws-cdk#14639 (more complicated is that it would need to preserve `null` across the process boundary, which is currently not possible). --- By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license]. [Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
1 parent 536f79a commit 884b0ff

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

packages/@jsii/kernel/src/serialization.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ interface Serializer {
111111
value: unknown,
112112
type: OptionalValueOrVoid,
113113
host: SerializerHost,
114+
options?: { allowNullishMapValue?: boolean },
114115
): any;
115116
}
116117

@@ -236,7 +237,6 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
236237
return SERIALIZERS[SerializationClass.Map].deserialize(
237238
value,
238239
{
239-
optional: false,
240240
type: {
241241
collection: {
242242
kind: spec.CollectionKind.Map,
@@ -245,6 +245,7 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
245245
},
246246
},
247247
host,
248+
{ allowNullishMapValue: true },
248249
);
249250
}
250251

@@ -266,9 +267,7 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
266267
host,
267268
'deserialize',
268269
toMap,
269-
{
270-
type: { primitive: spec.PrimitiveType.Json },
271-
},
270+
{ type: { primitive: spec.PrimitiveType.Json } },
272271
typeof key === 'string' ? `key ${inspect(key)}` : `index ${key}`,
273272
);
274273
}
@@ -387,7 +386,12 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
387386
),
388387
};
389388
},
390-
deserialize(value, optionalValue, host) {
389+
deserialize(
390+
value,
391+
optionalValue,
392+
host,
393+
{ allowNullishMapValue = false } = {},
394+
) {
391395
if (nullAndOk(value, optionalValue)) {
392396
return undefined;
393397
}
@@ -401,7 +405,10 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
401405
host,
402406
'deserialize',
403407
v,
404-
{ type: mapType.collection.elementtype },
408+
{
409+
optional: allowNullishMapValue,
410+
type: mapType.collection.elementtype,
411+
},
405412
`key ${inspect(key)}`,
406413
),
407414
);
@@ -411,7 +418,10 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
411418
host,
412419
'deserialize',
413420
v,
414-
{ type: mapType.collection.elementtype },
421+
{
422+
optional: allowNullishMapValue,
423+
type: mapType.collection.elementtype,
424+
},
415425
`key ${inspect(key)}`,
416426
),
417427
);
@@ -1112,7 +1122,7 @@ export function process(
11121122
context: string,
11131123
) {
11141124
const wireTypes = serializationType(type, host.lookupType);
1115-
host.debug(serde, value, wireTypes);
1125+
host.debug(serde, value, ...wireTypes);
11161126

11171127
const errors = new Array<any>();
11181128
for (const { serializationClass, typeRef } of wireTypes) {

0 commit comments

Comments
 (0)