From 097311f36048c6dfecfbb2597c9bb43f037b42f5 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Tue, 5 Feb 2019 18:06:03 -0500 Subject: [PATCH] Handle additional error cases in the manifest schema 1 implementation --- image/docker/schema1.py | 8 ++++++-- image/docker/test/test_schema1.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/image/docker/schema1.py b/image/docker/schema1.py index 6f8660e61..337c9547d 100644 --- a/image/docker/schema1.py +++ b/image/docker/schema1.py @@ -377,7 +377,11 @@ class DockerSchema1Manifest(ManifestInterface): metadata_string = history_obj[DOCKER_SCHEMA1_V1_COMPAT_KEY] - v1_metadata = json.loads(metadata_string) + try: + v1_metadata = json.loads(metadata_string) + except (ValueError, TypeError): + raise MalformedSchema1Manifest('Could not parse metadata string: %s' % metadata_string) + command_list = v1_metadata.get('container_config', {}).get('Cmd', None) command = to_canonical_json(command_list) if command_list else None @@ -536,7 +540,7 @@ class DockerSchema1ManifestBuilder(object): DOCKER_SCHEMA1_BLOB_SUM_KEY: layer_digest, }) self._history.append({ - DOCKER_SCHEMA1_V1_COMPAT_KEY: v1_json_metadata, + DOCKER_SCHEMA1_V1_COMPAT_KEY: v1_json_metadata or '{}', }) return self diff --git a/image/docker/test/test_schema1.py b/image/docker/test/test_schema1.py index 4392ae8cb..0fd473b6a 100644 --- a/image/docker/test/test_schema1.py +++ b/image/docker/test/test_schema1.py @@ -197,3 +197,19 @@ def test_validate_manifest_with_emoji(with_key): # Ensure the manifest can be reloaded. built_bytes = built.bytes.as_encoded_str() DockerSchema1Manifest(Bytes.for_string_or_unicode(built_bytes)) + + +@pytest.mark.parametrize('with_key', [ + None, + docker_v2_signing_key, +]) +def test_validate_manifest_with_none_metadata_layer(with_key): + builder = DockerSchema1ManifestBuilder('somenamespace', 'somerepo', 'sometag') + builder.add_layer('sha256:abcde', None) + + built = builder.build(with_key, ensure_ascii=False) + built._validate() + + # Ensure the manifest can be reloaded. + built_bytes = built.bytes.as_encoded_str() + DockerSchema1Manifest(Bytes.for_string_or_unicode(built_bytes))