changeset 459:138e2837d0e5

Applet-tags now ignore any invalid (eg corrupt) jars icedtea-web now skips over any jars that are corrupt or not actually jars. This is how the proprietary plugin treats this situation.
author Adam Domurad <adomurad@redhat.com>
date Mon, 09 Jul 2012 10:42:24 -0400
parents f7191afb7ab9
children 6f1d7f30246a
files netx/net/sourceforge/jnlp/cache/ResourceTracker.java netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
diffstat 2 files changed, 77 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/netx/net/sourceforge/jnlp/cache/ResourceTracker.java	Tue Jul 03 17:00:49 2012 -0400
+++ b/netx/net/sourceforge/jnlp/cache/ResourceTracker.java	Mon Jul 09 10:42:24 2012 -0400
@@ -184,7 +184,7 @@
      */
     public void addResource(URL location, Version version, DownloadOptions options, UpdatePolicy updatePolicy) {
         if (location == null)
-            throw new IllegalArgumentException("location==null");
+            throw new IllegalResourceDescriptorException("location==null");
         try {
             location = normalizeUrl(location, JNLPRuntime.isDebug());
         } catch (Exception ex) {
@@ -225,7 +225,7 @@
      * not required as resources are reclaimed when the tracker is
      * collected.
      *
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public void removeResource(URL location) {
         synchronized (resources) {
@@ -351,7 +351,7 @@
      *
      * @param location the resource location
      * @return the resource, or null if it could not be downloaded
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      * @see CacheUtil#isCacheable
      */
     public URL getCacheURL(URL location) {
@@ -378,7 +378,7 @@
      *
      * @param location the resource location
      * @return a local file containing the resource, or null
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      * @see CacheUtil#isCacheable
      */
     public File getCacheFile(URL location) {
@@ -418,7 +418,7 @@
      * the cache.
      *
      * @throws IOException if there was an error opening the stream
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public InputStream getInputStream(URL location) throws IOException {
         try {
@@ -442,7 +442,7 @@
      * @param urls the resources to wait for
      * @param timeout the time in ms to wait before returning, 0 for no timeout
      * @return whether the resources downloaded before the timeout
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public boolean waitForResources(URL urls[], long timeout) throws InterruptedException {
         Resource resources[] = new Resource[urls.length];
@@ -468,7 +468,7 @@
      * @param timeout the timeout, or 0 to wait until completed
      * @return whether the resource downloaded before the timeout
      * @throws InterruptedException if another thread interrupted the wait
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public boolean waitForResource(URL location, long timeout) throws InterruptedException {
         return wait(new Resource[] { getResource(location) }, timeout);
@@ -479,7 +479,7 @@
      *
      * @param location the resource location
      * @return the number of bytes transferred
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public long getAmountRead(URL location) {
         // not atomic b/c transferred is a long, but so what (each
@@ -491,7 +491,7 @@
      * Returns whether a resource is available for use (ie, can be
      * accessed with the getCacheFile method).
      *
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public boolean checkResource(URL location) {
         return getResource(location).isSet(DOWNLOADED | ERROR); // isSet atomic
@@ -505,7 +505,7 @@
      * resource at a time to conserve system resources.
      *
      * @return true if the resource is already downloaded (or an error occurred)
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public boolean startResource(URL location) {
         Resource resource = getResource(location);
@@ -518,7 +518,7 @@
      * enqueues the resource if not already started.
      *
      * @return true if the resource is already downloaded (or an error occurred)
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     private boolean startResource(Resource resource) {
         boolean enqueue = false;
@@ -550,7 +550,7 @@
      *
      * @param location the resource location
      * @return the number of bytes, or -1
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     public long getTotalSize(URL location) {
         return getResource(location).size; // atomic
@@ -606,7 +606,7 @@
     private void queueResource(Resource resource) {
         synchronized (lock) {
             if (!resource.isSet(CONNECT | DOWNLOAD))
-                throw new IllegalArgumentException("Invalid resource state (resource: " + resource + ")");
+                throw new IllegalResourceDescriptorException("Invalid resource state (resource: " + resource + ")");
 
             queue.add(resource);
             startThread();
@@ -1030,7 +1030,7 @@
     /**
      * Return the resource matching the specified URL.
      *
-     * @throws IllegalArgumentException if the resource is not being tracked
+     * @throws IllegalResourceDescriptorException if the resource is not being tracked
      */
     private Resource getResource(URL location) {
         synchronized (resources) {
@@ -1040,7 +1040,7 @@
             }
         }
 
-        throw new IllegalArgumentException("Location does not specify a resource being tracked.");
+        throw new IllegalResourceDescriptorException("Location does not specify a resource being tracked.");
     }
 
     /**
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Tue Jul 03 17:00:49 2012 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Mon Jul 09 10:42:24 2012 -0400
@@ -47,6 +47,7 @@
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -73,6 +74,7 @@
 import net.sourceforge.jnlp.SecurityDesc;
 import net.sourceforge.jnlp.Version;
 import net.sourceforge.jnlp.cache.CacheUtil;
+import net.sourceforge.jnlp.cache.IllegalResourceDescriptorException;
 import net.sourceforge.jnlp.cache.ResourceTracker;
 import net.sourceforge.jnlp.cache.UpdatePolicy;
 import net.sourceforge.jnlp.security.SecurityDialogs;
@@ -482,6 +484,39 @@
     }
 
     /**
+     * Check if a described jar file is invalid
+     * @param jar the jar to check
+     * @return true if file exists AND is an invalid jar, false otherwise
+     */
+    private boolean isInvalidJar(JARDesc jar){
+        File cacheFile = tracker.getCacheFile(jar.getLocation());
+        if (cacheFile == null)
+            return false;//File cannot be retrieved, do not claim it is an invalid jar
+        boolean isInvalid = false;
+        try {
+            JarFile jarFile = new JarFile(cacheFile.getAbsolutePath());
+            jarFile.close();
+        } catch (IOException ioe){
+            //Catch a ZipException or any other read failure
+            isInvalid = true;
+        }
+        return isInvalid;
+    }
+
+    /**
+     * Determine how invalid jars should be handled
+     * @return whether to filter invalid jars, or error later on
+     */
+    private boolean shouldFilterInvalidJars(){
+        if (file instanceof PluginBridge){
+            PluginBridge pluginBridge = (PluginBridge)file;
+            /*Ignore on applet, ie !useJNLPHref*/
+            return !pluginBridge.useJNLPHref();
+        }
+        return false;//Error is default behaviour
+    }
+
+    /**
      * Load all of the JARs used in this JNLP file into the
      * ResourceTracker for downloading.
      */
@@ -548,10 +583,26 @@
         if (strict)
             fillInPartJars(initialJars); // add in each initial part's lazy jars
 
+        waitForJars(initialJars); //download the jars first.
+
+        //A ZipException will propagate later on if the jar is invalid and not checked here
+        if (shouldFilterInvalidJars()){
+            //We filter any invalid jars
+            Iterator<JARDesc> iterator = initialJars.iterator();
+            while (iterator.hasNext()){
+                JARDesc jar = iterator.next();
+                if (isInvalidJar(jar)) {
+                    //Remove this jar as an available jar
+                    iterator.remove();
+                    tracker.removeResource(jar.getLocation());
+                    available.remove(jar);
+                }
+            }
+        }
+
         if (JNLPRuntime.isVerifying()) {
 
             JarCertVerifier jcv;
-            waitForJars(initialJars); //download the jars first.
 
             try {
                 jcv = verifyJars(initialJars);
@@ -618,7 +669,16 @@
 
         for (JARDesc jarDesc : file.getResources().getJARs()) {
             try {
-                File cachedFile = tracker.getCacheFile(jarDesc.getLocation());
+
+                File cachedFile;
+
+                try {
+                    cachedFile = tracker.getCacheFile(jarDesc.getLocation());
+                } catch (IllegalResourceDescriptorException irde){
+                    //Caused by ignored resource being removed due to not being valid
+                    System.err.println("JAR " + jarDesc.getLocation() + " is not a valid jar file. Continuing.");
+                    continue;
+                }
 
                 if (cachedFile == null) {
                     System.err.println("JAR " + jarDesc.getLocation() + " not found. Continuing.");