changeset 1393:f34f9ca3c3ef

Reproduced issue PR3351 * tests/reproducers/signed/Kemtrakpro/resources/Kemtrak_javaws.jnlp: jnlp file to test also javaws (next to applet) behavior * tests/reproducers/signed/Kemtrakpro/srcs/Kemtrak.java: added code to reproduce issue * tests/reproducers/signed/Kemtrakpro/testcases/KemtrakTests.java: added testcases for applet to close jar and try to load class again. added same testcases for javaws. Added testcase for plain java run to prove underlying jdk is not guilty * tests/reproducers/signed/jcalendar/srcs/jcalendar.java: small modification to add distinguish call inside.
author Jiri Vanek <jvanek@redhat.com>
date Mon, 10 Apr 2017 18:55:17 +0200
parents 233e93731f1e
children 78812003bcd2 69a8f501e9d2
files ChangeLog tests/reproducers/signed/Kemtrakpro/resources/Kemtrak_javaws.jnlp tests/reproducers/signed/Kemtrakpro/srcs/Kemtrak.java tests/reproducers/signed/Kemtrakpro/testcases/KemtrakTests.java tests/reproducers/signed/jcalendar/srcs/jcalendar.java
diffstat 5 files changed, 240 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Apr 10 14:44:43 2017 +0200
+++ b/ChangeLog	Mon Apr 10 18:55:17 2017 +0200
@@ -1,3 +1,17 @@
+2017-04-10  Jiri Vanek <jvanek@redhat.com>
+
+	Reproduced issue PR3351
+	* tests/reproducers/signed/Kemtrakpro/resources/Kemtrak_javaws.jnlp:
+	jnlp file to test also javaws (next to applet) behavior
+	* tests/reproducers/signed/Kemtrakpro/srcs/Kemtrak.java: added code to
+	reproduce issue
+	* tests/reproducers/signed/Kemtrakpro/testcases/KemtrakTests.java:
+	added testcases for applet to close jar and try to load class again.
+	added same testcases for javaws. Added testcase for plain java run to
+	prove underlying jdk is not guilty
+	* tests/reproducers/signed/jcalendar/srcs/jcalendar.java: small modification 
+	to add distinguish call inside.
+
 2017-04-10  Jiri Vanek <jvanek@redhat.com>
 
 	better handling of WEmbeddedFrame/XEmbeddedFrame
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/Kemtrakpro/resources/Kemtrak_javaws.jnlp	Mon Apr 10 18:55:17 2017 +0200
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<jnlp spec="7.0+" href="Kemtrak_javaws.jnlp" version="1.302.1.29">
+<!-- spec above has to be "7.0+" otherwise the caching-updating does not work -->
+    <information>
+        <title>Kemtrak 007</title>
+        <vendor>Kemtrak AB</vendor>
+		<shortcut install="false">
+			<!-- needed here to prevent shortcut-->
+		</shortcut>
+    </information>
+	
+	<update check="always" policy="always" />
+
+	<security>
+		<all-permissions/>
+	</security>
+	<resources>
+		<property name="jnlp.versionEnabled" value="true"/>
+		<java version="1.7.0.45"/>
+		<java version="1.7.0.51"/>
+		<java version="1.7.0.55"/>
+		<java version="1.7.0.60"/>
+		<java version="1.7.0.65"/>
+		<java version="1.7.0.67"/>
+		<java version="1.7.0.71"/>
+		<java version="1.7.0.72"/>
+		<java version="1.7.0.75"/>
+		<java version="1.7.0.76"/>
+		<java version="1.7.0.79"/>
+		<java version="1.7.0.80"/>
+		<java version="1.7.0.85"/>
+		<java version="1.7.0.91"/>
+		<java version="1.7.0.95"/>
+		<java version="1.7.0.97"/>
+		<java version="1.7.0.99"/>
+		<java version="1.7.0.101"/>
+		<java version="1.7.0.111"/>
+		<java version="1.7.0.121"/>
+		<java version="1.7.0.131"/>
+		<java version="1.8+"/>
+		<jar href="Kemtrakpro.jar" version="1.302.1.29" main="true" />
+		<jar href="jcalendar.jar" version="1.302.1.29"/>
+	</resources>
+    <application-desc main-class="Kemtrak">
+    </application-desc>
+<!-- can add txt here to change file size to force cache update - txt 790412 abcdefg -->
+</jnlp>    
--- a/tests/reproducers/signed/Kemtrakpro/srcs/Kemtrak.java	Mon Apr 10 14:44:43 2017 +0200
+++ b/tests/reproducers/signed/Kemtrakpro/srcs/Kemtrak.java	Mon Apr 10 18:55:17 2017 +0200
@@ -36,7 +36,12 @@
  */
 
 import java.applet.Applet;
+import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.*;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
 
 public class Kemtrak extends Applet {
 
@@ -56,28 +61,65 @@
     }
     private Killer killer;
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws  IOException {
         System.out.println("Kemtrak2");
-        jcalendar();
+        if (args.length == 2 && args[0].equals("closeJar")) {
+            String cbase = args[1];
+            System.out.println("Closing Jar!");
+            URL localURL = new java.net.URL("jar", "", cbase + "jcalendar.jar!/");
+            JarURLConnection localObject3 = (java.net.JarURLConnection) localURL.openConnection();
+            java.util.jar.JarFile localJarFile = ((java.net.JarURLConnection) localObject3).getJarFile();
+            String str9 = localJarFile.getName();
+            int i3 = localJarFile.size();
+            localJarFile.close();
+            System.out.println("jcalendar " + localURL + "   " + str9 + ", entrie: " + i3);
+            //if one call inisde  jcalendar.jar (jcalendar1() and/or jcalendar2) *BEFORE* closing, issue is NOT hit
+            jcalendar2();
+        } else {
+            jcalendar1();
+        }
+        System.out.println("kemtrak finished");
     }
 
     @Override
     public void init() {
-        System.out.println("Kemtrak1");
-        Kemtrak.main(null);
-        killer = new Killer();
-        killer.start();
+        try {
+            System.out.println("Kemtrak1");
+            String cj = this.getParameter("closeJar");
+            if ("closeJar".equals(cj)) {
+                Kemtrak.main(new String[]{"closeJar", getCodeBase().toExternalForm()});
+            } else {
+                Kemtrak.main(new String[0]);
+            }
+        } catch (IOException u) {
+            throw new RuntimeException(u);
+        } finally {
+            killer = new Killer();
+            killer.start();
+        }
     }
+    
+    
+    //we use reflection only to avoid jcalendar.jar on classpath
 
- public static void jcalendar() {
+    public static void jcalendar1() {
         try {
             Class<?> signedAppletClass = Class.forName("jcalendar");
-            Method m = signedAppletClass.getMethod("main", String[].class);
-            m.invoke(null, (Object)null);
+            Method m = signedAppletClass.getMethod("main1", String[].class);
+            m.invoke(null, (Object) null);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
 
+    public static void jcalendar2() {
+        try {
+            Class<?> signedAppletClass = Class.forName("jcalendar");
+            Method m = signedAppletClass.getMethod("main2", String[].class);
+            m.invoke(null, (Object) null);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
 }
--- a/tests/reproducers/signed/Kemtrakpro/testcases/KemtrakTests.java	Mon Apr 10 14:44:43 2017 +0200
+++ b/tests/reproducers/signed/Kemtrakpro/testcases/KemtrakTests.java	Mon Apr 10 18:55:17 2017 +0200
@@ -35,21 +35,27 @@
 exception statement from your version.
  */
 
+import java.io.File;
+import java.io.IOException;
 import java.util.AbstractMap;
 import java.util.Arrays;
+import net.sourceforge.jnlp.OptionsDefinitions;
 import net.sourceforge.jnlp.browsertesting.BrowserTest;
 
 import net.sourceforge.jnlp.ProcessResult;
 import net.sourceforge.jnlp.ProcessWrapper;
 import net.sourceforge.jnlp.ServerAccess;
 import net.sourceforge.jnlp.annotations.Bug;
+import net.sourceforge.jnlp.annotations.KnownToFail;
 import net.sourceforge.jnlp.closinglisteners.StringBasedClosingListener;
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.ManifestAttributesChecker;
 import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel;
 import net.sourceforge.jnlp.tools.DeploymentPropertiesModifier;
+import net.sourceforge.jnlp.util.FileUtils;
 
 import org.junit.Assert;
+import org.junit.BeforeClass;
 
 import org.junit.Test;
 
@@ -61,6 +67,37 @@
 public class KemtrakTests extends BrowserTest {
 
     private static final ServerAccess SERVER = new ServerAccess();
+    private static final String JNLP_APPLET_ORIG = "Kemtrak.jnlp";
+    private static final String JNLP_APP_ORIG = "Kemtrak_javaws.jnlp";
+
+    private static final String JNLP_APPLET_CODEBASED = "Kemtrak_cb.jnlp";
+    private static final String JNLP_APP_CODEBASED = "Kemtrak_javaws_cb.jnlp";
+
+    @BeforeClass
+    public static void prepareCodebasedFiles() throws IOException {
+        /**
+         * Kemtrak added the codebase="." during fixing the pr3350 then pr3351
+         * rised
+         */
+        File dir = SERVER.getDir();
+        File jnlp1 = new File(dir, JNLP_APPLET_ORIG);
+        File jnlp2 = new File(dir, JNLP_APP_ORIG);
+        
+        File jnlp12 = new File(dir, JNLP_APPLET_CODEBASED);
+        File jnlp22 = new File(dir, JNLP_APP_CODEBASED);
+        String file1 = FileUtils.loadFileAsString(jnlp1);
+        String file2 = FileUtils.loadFileAsString(jnlp2);
+        file1=addCodebase(file1);
+        file2=addCodebase(file2);
+        file1 = file1.replaceAll(JNLP_APPLET_ORIG, JNLP_APPLET_CODEBASED);
+        file2 = file2.replaceAll(JNLP_APP_ORIG, JNLP_APP_CODEBASED);
+        FileUtils.saveFile(file1, jnlp12);
+        FileUtils.saveFile(file2, jnlp22);
+    }
+    
+    private static String addCodebase(String s){
+        return s.replaceFirst("version=\"1.302.1.29\"", "version=\"1.302.1.29\" codebase=\".\"");
+    }
 
     @Bug(id = "PR3350")
     @Test
@@ -75,16 +112,88 @@
                                 AppletSecurityLevel.ASK_UNSIGNED.name()));
         try {
             dm.setProperties();
-            ProcessWrapper pw = new ProcessWrapper(SERVER.getJavawsLocation(),Arrays.asList(new String[]{ServerAccess.HEADLES_OPTION}), SERVER.getUrl("Kemtrak.jnlp"));
+            ProcessWrapper pw = new ProcessWrapper(SERVER.getJavawsLocation(), Arrays.asList(new String[]{ServerAccess.HEADLES_OPTION}), SERVER.getUrl(JNLP_APPLET_ORIG));
             pw.setWriter("YES\nYES\n");
-            pw.addStdOutListener(new StringBasedClosingListener("jcalendar2"));
+            pw.addStdOutListener(new StringBasedClosingListener("kemtrak finished"));
             ProcessResult pr = pw.execute();
             Assert.assertTrue("Stdout should contain Kemtrak1 but did not", pr.stdout.contains("Kemtrak1"));
             Assert.assertTrue("Stdout should contain Kemtrak2 but did not", pr.stdout.contains("Kemtrak2"));
-            Assert.assertTrue("Stdout should contain jcalendar2 but did not", pr.stdout.contains("jcalendar2"));
+            Assert.assertTrue("Stdout should contain jcalendar1 but did not", pr.stdout.contains("jcalendar1"));
         } finally {
             dm.restoreProperties();
         }
     }
 
+    @Bug(id = "PR3351")
+    @KnownToFail
+    @Test
+    public void KemtrakTest2() throws Exception {
+        ProcessWrapper pw = new ProcessWrapper(SERVER.getJavawsLocation(), Arrays.asList(new String[]{
+            ServerAccess.HEADLES_OPTION, OptionsDefinitions.OPTIONS.PARAM.option, "closeJar=closeJar", OptionsDefinitions.OPTIONS.JNLP.option}), SERVER.getUrl(JNLP_APPLET_CODEBASED));
+        pw.setWriter("YES\nYES\n");
+        pw.addStdOutListener(new StringBasedClosingListener("kemtrak finished"));
+        ProcessResult pr = pw.execute();
+        Assert.assertTrue("Stdout should contain Kemtrak1 but did not", pr.stdout.contains("Kemtrak1"));
+        Assert.assertTrue("Stdout should contain Kemtrak2 but did not", pr.stdout.contains("Kemtrak2"));
+        Assert.assertTrue("Stdout should contain jcalendar2 but did not", pr.stdout.contains("jcalendar2"));
+    }
+
+    @Test
+    public void KemtrakTest_javaws1() throws Exception {
+        DeploymentPropertiesModifier.MultipleDeploymentPropertiesModifier dm
+                = new DeploymentPropertiesModifier.MultipleDeploymentPropertiesModifier(
+                        new AbstractMap.SimpleEntry<>(
+                                DeploymentConfiguration.KEY_ENABLE_MANIFEST_ATTRIBUTES_CHECK,
+                                ManifestAttributesChecker.MANIFEST_ATTRIBUTES_CHECK.ALL.name()),
+                        new AbstractMap.SimpleEntry<>(
+                                DeploymentConfiguration.KEY_SECURITY_LEVEL,
+                                AppletSecurityLevel.ASK_UNSIGNED.name()));
+        try {
+            dm.setProperties();
+            ProcessWrapper pw = new ProcessWrapper(SERVER.getJavawsLocation(), Arrays.asList(new String[]{ServerAccess.HEADLES_OPTION}), SERVER.getUrl(JNLP_APP_ORIG));
+            pw.setWriter("YES\nYES\n");
+            pw.addStdOutListener(new StringBasedClosingListener("kemtrak finished"));
+            ProcessResult pr = pw.execute();
+            Assert.assertFalse("Stdout must nor contain Kemtrak1 but did not", pr.stdout.contains("Kemtrak1"));
+            Assert.assertTrue("Stdout should contain Kemtrak2 but did not", pr.stdout.contains("Kemtrak2"));
+            Assert.assertTrue("Stdout should contain jcalendar1 but did not", pr.stdout.contains("jcalendar1"));
+        } finally {
+            dm.restoreProperties();
+        }
+    }
+
+    @Bug(id = "PR3351")
+    @KnownToFail
+    @Test
+    public void KemtrakTest_javaws2() throws Exception {
+        ProcessWrapper pw = new ProcessWrapper(SERVER.getJavawsLocation(), Arrays.asList(new String[]{
+            ServerAccess.HEADLES_OPTION, OptionsDefinitions.OPTIONS.ARG.option, "closeJar", SERVER.getUrl().toExternalForm()+"/", OptionsDefinitions.OPTIONS.JNLP.option}), SERVER.getUrl(JNLP_APP_CODEBASED));
+        pw.setWriter("YES\nYES\n");
+        pw.addStdOutListener(new StringBasedClosingListener("kemtrak finished"));
+        ProcessResult pr = pw.execute();
+        Assert.assertFalse("Stdout must not contain Kemtrak1 but did not", pr.stdout.contains("Kemtrak1"));
+        Assert.assertTrue("Stdout should contain Kemtrak2 but did not", pr.stdout.contains("Kemtrak2"));
+        Assert.assertTrue("Stdout should contain jcalendar2 but did not", pr.stdout.contains("jcalendar2"));
+    }
+    
+    
+    @Test
+    /**
+     * We can see that issue is not reproducible outside  itw
+     */
+    public void KemtrakTest_java() throws Exception {
+        ProcessWrapper pw = new ProcessWrapper(System.getProperty("java.home")+"/bin/java", Arrays.asList(new String[]{
+            "-cp",
+            new File(SERVER.getDir(), "jcalendar.jar").getAbsolutePath()+File.pathSeparator+new File(SERVER.getDir(), "Kemtrakpro.jar").getAbsolutePath(),
+            "Kemtrak",
+             "closeJar",
+            }), SERVER.getDir().toURI().toURL().toExternalForm()+"/");
+        pw.setWriter("YES\nYES\n");
+        pw.addStdOutListener(new StringBasedClosingListener("kemtrak finished"));
+        ProcessResult pr = pw.execute();
+        Assert.assertFalse("Stdout must not contain Kemtrak1 but did not", pr.stdout.contains("Kemtrak1"));
+        Assert.assertTrue("Stdout should contain Kemtrak2 but did not", pr.stdout.contains("Kemtrak2"));
+        Assert.assertTrue("Stdout should contain jcalendar2 but did not", pr.stdout.contains("jcalendar2"));
+    }
+
 }
--- a/tests/reproducers/signed/jcalendar/srcs/jcalendar.java	Mon Apr 10 14:44:43 2017 +0200
+++ b/tests/reproducers/signed/jcalendar/srcs/jcalendar.java	Mon Apr 10 18:55:17 2017 +0200
@@ -36,14 +36,18 @@
  */
 
 import java.applet.Applet;
-import java.lang.reflect.*;
 
 /**
- * This is used by Kemtrak reproducer.
- * Originally the jar was signed2, but I always forget:
- * netx: Initialization Error: Could not initialize applet. (Fatal: Application Error: The JNLP application is not fully signed by a single cert. The JNLP application has its components individually signed, however there must be a common signer to all entries.)
- * netx: Initialization Error: Could not initialize applet. (Fatal: Application Error: The JNLP application is not fully signed by a single cert. The JNLP application has its components individually signed, however there must be a common signer to all entries.)
- * 
+ * This is used by Kemtrak reproducer. Originally the jar was signed2, but I
+ * always forget: netx: Initialization Error: Could not initialize applet.
+ * (Fatal: Application Error: The JNLP application is not fully signed by a
+ * single cert. The JNLP application has its components individually signed,
+ * however there must be a common signer to all entries.) netx: Initialization
+ * Error: Could not initialize applet. (Fatal: Application Error: The JNLP
+ * application is not fully signed by a single cert. The JNLP application has
+ * its components individually signed, however there must be a common signer to
+ * all entries.)
+ *
  * @author jvanek
  */
 public class jcalendar extends Applet {
@@ -64,17 +68,19 @@
     }
     private Killer killer;
 
-    public static void main(String[] args) {
+    public static void main1(String[] args) {
+        System.out.println("jcalendar1");
+    }
+
+    public static void main2(String[] args) {
         System.out.println("jcalendar2");
     }
 
     @Override
     public void init() {
-        System.out.println("jcalendar1");
+        System.out.println("jcalendar0");
         killer = new Killer();
         killer.start();
     }
 
-
-
 }