Skip to content

Commit 0f695ef

Browse files
committed
Handle null values in sparse map serialization and deserialization
1 parent b001a74 commit 0f695ef

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

awscli/botocore/parsers.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,12 @@ def _handle_map(self, shape, value):
709709
value_shape = shape.value
710710
for key, value in value.items():
711711
actual_key = self._parse_shape(key_shape, key)
712-
actual_value = self._parse_shape(value_shape, value)
712+
# Treat all maps as sparse during parsing to safely handle null
713+
# values that may be present in service responses.
714+
if value is None:
715+
actual_value = None
716+
else:
717+
actual_value = self._parse_shape(value_shape, value)
713718
parsed[actual_key] = actual_value
714719
return parsed
715720

@@ -891,8 +896,7 @@ def _parse_map(self, stream, additional_info):
891896
def _parse_key_value_pair(self, stream, items):
892897
key = self.parse_data_item(stream)
893898
value = self.parse_data_item(stream)
894-
if value is not None:
895-
items[key] = value
899+
items[key] = value
896900

897901
# Major type 6 is tags. The only tag we currently support is tag 1 for unix
898902
# timestamps

awscli/botocore/serialize.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -416,19 +416,27 @@ def _serialize_type_map(self, serialized, value, shape, key):
416416
map_obj = self.MAP_TYPE()
417417
serialized[key] = map_obj
418418
for sub_key, sub_value in value.items():
419-
self._serialize(map_obj, sub_value, shape.value, sub_key)
419+
if sub_value is None:
420+
map_obj[sub_key] = None
421+
else:
422+
self._serialize(map_obj, sub_value, shape.value, sub_key)
420423

421424
def _serialize_type_list(self, serialized, value, shape, key):
422425
list_obj = []
423426
serialized[key] = list_obj
424427
for list_item in value:
425-
wrapper = {}
426-
# The JSON list serialization is the only case where we aren't
427-
# setting a key on a dict. We handle this by using
428-
# a __current__ key on a wrapper dict to serialize each
429-
# list item before appending it to the serialized list.
430-
self._serialize(wrapper, list_item, shape.member, "__current__")
431-
list_obj.append(wrapper["__current__"])
428+
if list_item is None:
429+
list_obj.append(None)
430+
else:
431+
wrapper = {}
432+
# The JSON list serialization is the only case where we aren't
433+
# setting a key on a dict. We handle this by using
434+
# a __current__ key on a wrapper dict to serialize each
435+
# list item before appending it to the serialized list.
436+
self._serialize(
437+
wrapper, list_item, shape.member, "__current__"
438+
)
439+
list_obj.append(wrapper["__current__"])
432440

433441
def _default_serialize(self, serialized, value, shape, key):
434442
serialized[key] = value
@@ -539,7 +547,14 @@ def _serialize_type_list(self, serialized, value, shape, key):
539547
else:
540548
serialized.extend(initial_byte + length.to_bytes(num_bytes, "big"))
541549
for item in value:
542-
self._serialize_data_item(serialized, item, shape.member)
550+
if item is None:
551+
serialized.extend(
552+
self._get_initial_byte(
553+
self.FLOAT_AND_SIMPLE_MAJOR_TYPE, 22
554+
)
555+
)
556+
else:
557+
self._serialize_data_item(serialized, item, shape.member)
543558

544559
def _serialize_type_map(self, serialized, value, shape, key):
545560
length = len(value)
@@ -555,7 +570,14 @@ def _serialize_type_map(self, serialized, value, shape, key):
555570
serialized.extend(initial_byte + length.to_bytes(num_bytes, "big"))
556571
for key_item, item in value.items():
557572
self._serialize_data_item(serialized, key_item, shape.key)
558-
self._serialize_data_item(serialized, item, shape.value)
573+
if item is None:
574+
serialized.extend(
575+
self._get_initial_byte(
576+
self.FLOAT_AND_SIMPLE_MAJOR_TYPE, 22
577+
)
578+
)
579+
else:
580+
self._serialize_data_item(serialized, item, shape.value)
559581

560582
def _serialize_type_structure(self, serialized, value, shape, key):
561583
if key is not None:

0 commit comments

Comments
 (0)