From b1b68d7c6205ef2cbc5fbfbbddfa63001134b4e0 Mon Sep 17 00:00:00 2001
From: Emmanuel Hugonnet <ehugonne@redhat.com>
Date: Wed, 15 Nov 2023 11:25:09 +0100
Subject: [PATCH] fix: when trying to open a jarUrl to compute a SHA if the
 target archive is the jar itself and not an embedded archive opening the
 stream will fail.

Signed-off-by: Emmanuel Hugonnet <ehugonne@redhat.com>
---
 .../com/redhat/insights/jars/JarUtils.java    | 22 ++++++++++++-------
 .../redhat/insights/jars/TestJarUtils.java    | 13 ++++++++++-
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/api/src/main/java/com/redhat/insights/jars/JarUtils.java b/api/src/main/java/com/redhat/insights/jars/JarUtils.java
index 2f85d70b..62267d44 100644
--- a/api/src/main/java/com/redhat/insights/jars/JarUtils.java
+++ b/api/src/main/java/com/redhat/insights/jars/JarUtils.java
@@ -40,27 +40,33 @@ private static Map<String, String> getEmbeddedFormatToExtension(String... fileEx
    * @throws IOException
    */
   public static InputStream getInputStream(URL url) throws IOException {
-
+    String jarLocation = url.toExternalForm();
+    URL jarURL = url;
     for (Entry<String, String> entry : EMBEDDED_FORMAT_TO_EXTENSION.entrySet()) {
-      int index = url.toExternalForm().indexOf(entry.getKey());
-      if (index > 0) {
+      int index = jarLocation.indexOf(entry.getKey());
+      // if the target is the jar file then we can't use openStream as it is there to look into the jar content. 
+      if (index > 0 && (index + entry.getKey().length()) < jarLocation.length()) {
         String path = url.toExternalForm().substring(index + entry.getKey().length());
         // add 1 to skip past the `.` and the value length, which is the length of the file
         // extension
-        url = new URL(url.toExternalForm().substring(0, index + 1 + entry.getValue().length()));
-        InputStream inputStream = url.openStream();
+        jarURL =
+            new URL(jarURL.toExternalForm().substring(0, index + 1 + entry.getValue().length()));
+        InputStream inputStream = jarURL.openStream();
         JarInputStream jarStream = new JarInputStream(inputStream);
 
         if (!readToEntry(jarStream, path)) {
           inputStream.close();
           throw new IOException(
-              "Unable to open stream for " + path + " in " + url.toExternalForm());
+              "Unable to open stream for " + path + " in " + jarURL.toExternalForm());
         }
         return jarStream;
       }
     }
-
-    return url.openStream();
+    if (jarLocation.startsWith("jar:") && jarLocation.endsWith("!/")) {
+      String jarLoc = jarLocation.substring(4, jarLocation.length() - 2);
+      jarURL = new URL(jarLoc);
+    }
+    return jarURL.openStream();
   }
 
   /**
diff --git a/api/src/test/java/com/redhat/insights/jars/TestJarUtils.java b/api/src/test/java/com/redhat/insights/jars/TestJarUtils.java
index e7073563..5b69e0bb 100644
--- a/api/src/test/java/com/redhat/insights/jars/TestJarUtils.java
+++ b/api/src/test/java/com/redhat/insights/jars/TestJarUtils.java
@@ -10,6 +10,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.NoSuchAlgorithmException;
 import org.junit.jupiter.api.Test;
@@ -26,7 +27,7 @@ public void basicHashTest() throws IOException, NoSuchAlgorithmException {
   }
 
   @Test
-  public void basicCheckJars() throws NoSuchAlgorithmException, IOException {
+  public void basicCheckJars() throws NoSuchAlgorithmException, IOException, URISyntaxException {
     URL jar1URL = getURL(JAR_PATH);
     URL jar2URL = getURL(JAR_PATH_2);
 
@@ -43,4 +44,14 @@ private byte[] readAllBytes(InputStream inputStream) throws IOException {
       return buffer.toByteArray();
     }
   }
+
+  @Test
+  public void basicCheckJarUrls() throws NoSuchAlgorithmException, IOException, URISyntaxException {
+    String file = "jar:" + getURL(JAR_PATH).toExternalForm() + "!/";
+    try {
+      computeSha(new URL(file));
+    } catch (Exception ex) {
+      fail(ex);
+    }
+  }
 }