Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions src/main/java/land/oras/OCILayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,16 +342,22 @@ public Descriptor fetchBlobDescriptor(LayoutRef ref) {

@Override
public Layer pushBlob(LayoutRef ref, Path blob, Map<String, String> annotations) {
ensureDigest(ref, blob);
Path blobPath = getBlobPath(ref);
String digest = ref.getAlgorithm().digest(blob);
if (ref.getTag() == null) {
throw new OrasException("Missing ref");
}
if (!SupportedAlgorithm.isSupported(ref.getTag())) {
throw new OrasException("Unsupported digest: %s".formatted(ref.getTag()));
}
String digest = ref.getTag();
ensureAlgorithmPath(digest);
Path blobPath = getBlobPath(ref);
LOG.trace("Digest: {}", digest);
try {
if (Files.exists(blobPath)) {
LOG.info("Blob already exists: {}", digest);
return Layer.fromFile(blobPath, ref.getAlgorithm()).withAnnotations(annotations);
}
ensureDigest(ref, blob);
Files.copy(blob, blobPath);
Layer layer = Layer.fromFile(blobPath, ref.getAlgorithm()).withAnnotations(annotations);
packToTar();
Expand Down Expand Up @@ -394,12 +400,26 @@ public Layer pushBlob(LayoutRef ref, long size, Supplier<InputStream> stream, Ma
@Override
public Layer pushBlob(LayoutRef ref, byte[] data) {
try {
Path path = Files.createTempFile("oras", "blob");
Files.write(path, data);
ensureDigest(ref, path);
if (ref.getTag() == null) {
throw new OrasException("Missing ref");
}
if (!SupportedAlgorithm.isSupported(ref.getTag())) {
throw new OrasException("Unsupported digest: %s".formatted(ref.getTag()));
}
String digest = ref.getAlgorithm().digest(data);
if (!ref.getTag().equals(digest)) {
throw new OrasException("Digest mismatch: %s != %s".formatted(ref.getTag(), digest));
}
ensureAlgorithmPath(digest);
return pushBlob(ref, path, Map.of());
Path blobPath = getBlobAlgorithmPath(digest).resolve(SupportedAlgorithm.getDigest(digest));
if (Files.exists(blobPath)) {
LOG.info("Blob already exists: {}", digest);
return Layer.fromFile(blobPath, ref.getAlgorithm()).withAnnotations(Map.of());
}
Files.write(blobPath, data);
packToTar();
LOG.debug("Blob pushed to OCI layout: {}", digest);
return Layer.fromFile(blobPath, ref.getAlgorithm()).withAnnotations(Map.of());
} catch (IOException e) {
throw new OrasException("Failed to push blob to OCI layout", e);
}
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/land/oras/OCILayoutTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,24 @@ void cannotPushBlobWithoutTagOrDigest() throws IOException {
});
}

@Test
void cannotPushBlobFromPathWithoutTagOrDigest() throws IOException {
Path invalidBlobPushDir = layoutPath.resolve("cannotPushBlobFromPathWithoutTagOrDigest");
OCILayout ociLayout =
OCILayout.Builder.builder().defaults(invalidBlobPushDir).build();
Path blobFile = blobDir.resolve("cannotPushBlobFromPathWithoutTagOrDigest.txt");
Files.writeString(blobFile, "hello");

LayoutRef noTagLayout = LayoutRef.of(ociLayout);
OrasException e1 = assertThrows(OrasException.class, () -> ociLayout.pushBlob(noTagLayout, blobFile, Map.of()));
assertEquals("Missing ref", e1.getMessage());

LayoutRef noDigestLayout = LayoutRef.of(ociLayout, "latest");
OrasException e2 =
assertThrows(OrasException.class, () -> ociLayout.pushBlob(noDigestLayout, blobFile, Map.of()));
assertEquals("Unsupported digest: latest", e2.getMessage());
}

@Test
void cannotPushWithInvalidDigest() {
Path invalidBlobPushDir = layoutPath.resolve("cannotPushWithInvalidDigest");
Expand Down
Binary file modified src/test/resources/oci/artifact.tar
Binary file not shown.
Binary file modified src/test/resources/oci/subject.tar
Binary file not shown.
Loading