imagetools: validate descriptor input for create -f

Return a clear error when -f contains a manifest or index instead of an OCI
content descriptor, and reject descriptors missing a valid digest. Avoids
a nil-pointer panic when piping inspect --raw output into imagetools create.

Fixes #2091


Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>
This commit is contained in:
amarkdotdev
2026-07-06 23:23:25 +03:00
parent dc8fa3045b
commit 89ec9fe9b3
2 changed files with 49 additions and 0 deletions
+22
View File
@@ -357,9 +357,31 @@ func parseSource(in string) (*imagetools.Source, error) {
if err := json.Unmarshal([]byte(in), &s.Desc); err != nil {
return nil, errors.WithStack(err)
}
if err := validateDescriptorJSON(in, s.Desc); err != nil {
return nil, err
}
return &s, nil
}
func validateDescriptorJSON(raw string, desc ocispecs.Descriptor) error {
var meta struct {
SchemaVersion int `json:"schemaVersion"`
}
if err := json.Unmarshal([]byte(raw), &meta); err != nil {
return errors.WithStack(err)
}
if meta.SchemaVersion != 0 {
return errors.Errorf("expected an OCI content descriptor, got a manifest or index (schemaVersion %d)", meta.SchemaVersion)
}
if desc.Digest == "" {
return errors.Errorf("invalid descriptor: digest is required")
}
if _, err := digest.Parse(desc.Digest.String()); err != nil {
return errors.Wrap(err, "invalid descriptor digest")
}
return nil
}
func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
var options createOptions
+27
View File
@@ -0,0 +1,27 @@
package commands
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestParseSourceDescriptorValidation(t *testing.T) {
t.Parallel()
_, err := parseSource(`{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","manifests":[]}`)
require.Error(t, err)
require.Contains(t, err.Error(), "expected an OCI content descriptor")
_, err = parseSource(`{"mediaType":"application/vnd.oci.image.manifest.v1+json"}`)
require.Error(t, err)
require.Contains(t, err.Error(), "digest is required")
_, err = parseSource(`{"digest":"not-a-digest","mediaType":"application/vnd.oci.image.manifest.v1+json","size":123}`)
require.Error(t, err)
require.Contains(t, err.Error(), "invalid descriptor digest")
src, err := parseSource(`{"digest":"sha256:0000000000000000000000000000000000000000000000000000000000000000","mediaType":"application/vnd.oci.image.manifest.v1+json","size":123}`)
require.NoError(t, err)
require.Equal(t, "sha256:0000000000000000000000000000000000000000000000000000000000000000", src.Desc.Digest.String())
}