1
0
mirror of https://github.com/opencontainers/image-spec.git synced 2026-02-05 09:45:41 +01:00

Descriptor size cannot be negative

Signed-off-by: Brandon Mitchell <git@bmitch.net>
This commit is contained in:
Brandon Mitchell
2025-09-05 14:19:51 -04:00
parent 2daaaaf0e7
commit 02ba6e2143
4 changed files with 136 additions and 80 deletions

View File

@@ -34,6 +34,7 @@ The following fields contain the primary properties that constitute a Descriptor
This REQUIRED property specifies the size, in bytes, of the raw content.
This property exists so that a client will have an expected size for the content before processing.
If the length of the retrieved content does not match the specified length, the content SHOULD NOT be trusted.
The size MUST NOT be negative.
- **`urls`** *array of strings*

View File

@@ -10,7 +10,7 @@
},
"size": {
"description": "the size in bytes of the referenced object",
"$ref": "defs.json#/definitions/int64"
"$ref": "defs-descriptor.json#/definitions/size"
},
"digest": {
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",

View File

@@ -7,6 +7,11 @@
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}$"
},
"size": {
"type": "integer",
"minimum": 0,
"maximum": 9223372036854776000
},
"digest": {
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
"type": "string",

View File

@@ -38,6 +38,18 @@ func TestDescriptor(t *testing.T) {
fail: false,
},
// zero length blob
{
descriptor: `
{
"mediaType": "application/octet-stream",
"size": 0,
"digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
`,
fail: false,
},
// expected failure: mediaType missing
{
descriptor: `
@@ -236,111 +248,149 @@ func TestDescriptor(t *testing.T) {
// expected success: artifactType is present and an IANA compliant value
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}
`,
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}
`,
fail: false,
},
// expected failure: artifactType does not match pattern (invalid first subtype character)
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "foo/.bar",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}
`,
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "foo/.bar",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}
`,
fail: true,
},
// expected success: data field is present and has base64 content
{
descriptor: `
{
"mediaType": "text/plain",
"size": 34,
"data": "aHR0cHM6Ly9naXRodWIuY29tL29wZW5jb250YWluZXJzCg==",
"digest": "sha256:2690af59371e9eca9453dc29882643f46e5ca47ec2862bd517b5e17351325153"
}
`,
{
"mediaType": "text/plain",
"size": 34,
"data": "aHR0cHM6Ly9naXRodWIuY29tL29wZW5jb250YWluZXJzCg==",
"digest": "sha256:2690af59371e9eca9453dc29882643f46e5ca47ec2862bd517b5e17351325153"
}
`,
fail: false,
},
{
descriptor: `{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
},
{
descriptor: `{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
},
{
descriptor: `{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
},
// expected success: test for alternate digest algorithm
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
fail: false,
},
// expected success: test for alternate digest algorithm
{
descriptor: `{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8"
}`,
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
fail: false,
},
// expected success: test for alternate digest algorithm
{
// fail: repeated separators in algorithm
descriptor: `{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
fail: false,
},
// expected success: test for alternate digest algorithm
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
fail: false,
},
// expected success: test for alternate digest algorithm
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8"
}`,
fail: false,
},
// fail: repeated separators in algorithm
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 1470,
"digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
}`,
fail: true,
},
{
descriptor: `{
"digest": "sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"size": 1000000,
"mediaType": "application/vnd.oci.image.config.v1+json"
}`,
},
{
// test for those who cannot use modulo arithmetic to recover padding.
descriptor: `{
"digest": "sha256+b64u.unknownlength:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564=",
"size": 1000000,
"mediaType": "application/vnd.oci.image.config.v1+json"
}`,
},
// expected success: test for alternate digest encoding
{
descriptor: `
{
"digest": "sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"size": 1000000,
"mediaType": "application/vnd.oci.image.config.v1+json"
}`,
fail: false,
},
// expected success: test for those who cannot use modulo arithmetic to recover padding.
{
"mediaType": "text/plain",
"size": 34,
"data": "aHR0cHM6Ly9naXRodWIuY29tL29wZW5jb250YWluZXJzCg",
"digest": "sha256:2690af59371e9eca9453dc29882643f46e5ca47ec2862bd517b5e17351325153"
}
`,
descriptor: `
{
"digest": "sha256+b64u.unknownlength:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564=",
"size": 1000000,
"mediaType": "application/vnd.oci.image.config.v1+json"
}`,
},
// expected failure: invalid data base64, missing padding
{
descriptor: `
{
"mediaType": "text/plain",
"size": 34,
"data": "aHR0cHM6Ly9naXRodWIuY29tL29wZW5jb250YWluZXJzCg",
"digest": "sha256:2690af59371e9eca9453dc29882643f46e5ca47ec2862bd517b5e17351325153"
}`,
fail: true,
},
// expected failure: negative size
{
descriptor: `
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": -7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}`,
fail: true,
},
} {