Skip to content

Commit dcc974c

Browse files
committed
Fix possible Nullpointer on digest validation
1 parent b129d47 commit dcc974c

3 files changed

Lines changed: 30 additions & 3 deletions

File tree

src/main/java/land/oras/Registry.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,9 @@ public Descriptor getDescriptor(ContainerRef containerRef) {
590590
public Descriptor probeDescriptor(ContainerRef ref) {
591591
Map<String, String> headers = getHeaders(ref);
592592
String digest = validateDockerContentDigest(headers);
593-
SupportedAlgorithm.fromDigest(digest);
593+
if (digest != null) {
594+
SupportedAlgorithm.fromDigest(digest);
595+
}
594596
String contentType = headers.get(Const.CONTENT_TYPE_HEADER.toLowerCase());
595597
return Descriptor.of(digest, 0L, contentType);
596598
}
@@ -640,12 +642,19 @@ private void validateDockerContentDigest(HttpClient.ResponseWrapper<Path> respon
640642
ensureDigest(digest, computedDigest);
641643
}
642644

643-
private String validateDockerContentDigest(HttpClient.ResponseWrapper<?> response) {
645+
private @Nullable String validateDockerContentDigest(HttpClient.ResponseWrapper<?> response) {
644646
return validateDockerContentDigest(response.headers());
645647
}
646648

647-
private String validateDockerContentDigest(Map<String, String> headers) {
649+
private @Nullable String validateDockerContentDigest(Map<String, String> headers) {
648650
String digest = headers.get(Const.DOCKER_CONTENT_DIGEST_HEADER.toLowerCase());
651+
// This might happen when blob are hosted other storage.
652+
// We need a way to propagate the headers like scoped.
653+
// For now just skip validation
654+
if (digest == null) {
655+
LOG.warn("Docker-Content-Digest header not found in response. Skipping validation.");
656+
return null;
657+
}
649658
SupportedAlgorithm.fromDigest(digest);
650659
return digest;
651660
}

src/test/java/land/oras/HarborS3ITCase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ void shouldPullOneBlob() {
4444
Layer oneLayer = manifest.getLayers().get(0);
4545
registry.fetchBlob(containerRef1.withDigest(oneLayer.getDigest()), tempDir.resolve("my-blob"));
4646
assertNotNull(tempDir.resolve("my-blob"));
47+
registry.pullArtifact(containerRef1, tempDir, true);
4748
}
4849
}

src/test/java/land/oras/RegistryWireMockTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,23 @@ void shouldValidateDockerContentDigestMismatch(WireMockRuntimeInfo wmRuntimeInfo
598598
e.getMessage());
599599
}
600600

601+
@Test
602+
void shouldNotValidateDockerContentDigestWhenProbingDescriptor(WireMockRuntimeInfo wmRuntimeInfo) {
603+
WireMock wireMock = wmRuntimeInfo.getWireMock();
604+
String registryUrl = wmRuntimeInfo.getHttpBaseUrl().replace("http://", "");
605+
wireMock.register(head(urlEqualTo("/v2/library/validate-digest/manifests/latest"))
606+
.willReturn(aResponse().withStatus(200).withBody("blob-data")));
607+
608+
// Test
609+
Registry registry = Registry.Builder.builder()
610+
.withAuthProvider(authProvider)
611+
.withInsecure(true)
612+
.build();
613+
ContainerRef containerRef = ContainerRef.parse("%s/library/validate-digest".formatted(registryUrl));
614+
Descriptor descriptor = registry.probeDescriptor(containerRef);
615+
assertNotNull(descriptor, "Descriptor should not be null");
616+
}
617+
601618
@Test
602619
void shouldFollowRedirectAfterRequestingToken(WireMockRuntimeInfo wmRuntimeInfo) {
603620

0 commit comments

Comments
 (0)