Skip to content

Commit 285e137

Browse files
committed
manifest: explicitly error if whitespace reconstruction has failed
This behavior should not break any more use cases than before. Previously, if the mismatch occured, we would actually push a manifest that we then never referred to in the manifest list! If this was done in a new repository, the command would fail with an obscure error from the registry - the content wouldn't exist with the descriptor we expect it to. Signed-off-by: Justin Chadwell <me@jedevc.com>
1 parent 070825b commit 285e137

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

cli/command/manifest/push.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,28 +218,41 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
218218
return mountRequest{}, err
219219
}
220220

221+
// Attempt to reconstruct indentation of the manifest to ensure sha parity
222+
// with the registry.
223+
//
224+
// This is necessary because our previous internal storage format did not
225+
// preserve whitespace. If we don't have the newer format present, we can
226+
// attempt the reconstruction like before, but explicitly error if the
227+
// reconstruction failed!
221228
switch {
222229
case imageManifest.SchemaV2Manifest != nil:
223-
// This indentation has to be added to ensure sha parity with the registry
224230
dt, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
225231
if err != nil {
226232
return mountRequest{}, err
227233
}
228-
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
229-
// and not alter the sha
234+
235+
dig := imageManifest.Descriptor.Digest
236+
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
237+
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
238+
}
239+
230240
var manifest schema2.DeserializedManifest
231241
if err = manifest.UnmarshalJSON(dt); err != nil {
232242
return mountRequest{}, err
233243
}
234244
imageManifest.SchemaV2Manifest = &manifest
235245
case imageManifest.OCIManifest != nil:
236-
// This indentation has to be added to ensure sha parity with the registry
237246
dt, err := json.MarshalIndent(imageManifest.OCIManifest, "", " ")
238247
if err != nil {
239248
return mountRequest{}, err
240249
}
241-
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
242-
// and not alter the sha
250+
251+
dig := imageManifest.Descriptor.Digest
252+
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
253+
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
254+
}
255+
243256
var manifest ocischema.DeserializedManifest
244257
if err = manifest.UnmarshalJSON(dt); err != nil {
245258
return mountRequest{}, err

0 commit comments

Comments
 (0)