changeset 992:a1a59525e85e

Internal implementation of ExecuteAppletAction now support multiple items
author Jiri Vanek <jvanek@redhat.com>
date Fri, 09 May 2014 14:58:37 +0200
parents de898c0d6d5f
children 6b3a610aff7d
files ChangeLog netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteAppletAction.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActionsTest.java tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java
diffstat 10 files changed, 491 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon May 05 17:11:45 2014 +0200
+++ b/ChangeLog	Fri May 09 14:58:37 2014 +0200
@@ -1,3 +1,27 @@
+2014-05-09  Jiri Vanek  <jvanek@redhat.com>
+
+	Internal implementation of ExecuteAppletAction now support multiple items
+	* netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java: 
+	Returning AppletSecurityActions instead of ExecuteAppletAction class
+	* netx/net/sourceforge/jnlp/resources/Messages.properties: added
+	APPEXTSECunsetAppletAction key.
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java: 
+	New file, to handle multiple actions hidden in one record.
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteAppletAction.java: Added
+	UNSET option, handled in (fromString) and (fromChar) and (toChar) and (toExpalnation)
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java: 
+	instead of ExecuteAppletAction type in fromString and constructor, using
+	AppletSecurityActions
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java: 
+	behaviour wrapped by  AppletSecurityActions.fromAction(behaviour)
+	* tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActionsTest.java: 
+	New test for new file
+	* tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java: 
+	added license header
+	* tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java: 
+	Test adapted to new features, and to preserving old behavior.
+
+
 2014-05-05  Jiri Vanek  <jvanek@redhat.com>
 
 	Links in AppTrustWarningPanel are now clickable.
--- a/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Mon May 05 17:11:45 2014 +0200
+++ b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Fri May 09 14:58:37 2014 +0200
@@ -39,6 +39,7 @@
 import javax.swing.event.TableModelEvent;
 import javax.swing.table.AbstractTableModel;
 import net.sourceforge.jnlp.runtime.Translator;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UrlRegEx;
@@ -75,7 +76,7 @@
     @Override
     public Class<?> getColumnClass(int columnIndex) {
         if (columnIndex == 0) {
-            return ExecuteAppletAction.class;
+            return AppletSecurityActions.class;
         }
         if (columnIndex == 1) {
             return Date.class;
@@ -145,7 +146,7 @@
         int i = getRowCount()-1;
         String s = "\\Qhttp://localhost:80/\\E.*";
         back.add(new UnsignedAppletActionEntry(
-                ExecuteAppletAction.NEVER,
+                AppletSecurityActions.fromAction(ExecuteAppletAction.NEVER),
                 new Date(),
                 new UrlRegEx(s),
                 new UrlRegEx(s),
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Mon May 05 17:11:45 2014 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Fri May 09 14:58:37 2014 +0200
@@ -818,6 +818,7 @@
 APPEXTSECunsignedAppletActionYes=This applet was visited and allowed
 APPEXTSecunsignedAppletActionSandbox=This applet was visited and allowed to run with restricted privileges
 APPEXTSECunsignedAppletActionNo=This applet was visited and denied
+APPEXTSECunsetAppletAction=This applet has not yet asked for this action
 APPEXTSECControlPanelExtendedAppletSecurityTitle=Extended applet security
 APPEXTSECguiTableModelTableColumnAction=Action
 APPEXTSECguiTableModelTableColumnDateOfAction=Date of action
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java	Fri May 09 14:58:37 2014 +0200
@@ -0,0 +1,116 @@
+/*   Copyright (C) 2014 Red Hat, Inc.
+
+ This file is part of IcedTea.
+
+ IcedTea is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, version 2.
+
+ IcedTea is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with IcedTea; see the file COPYING.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library.  Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module.  An independent module is a module which is not derived from
+ or based on this library.  If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so.  If you do not wish to do so, delete this
+ exception statement from your version.
+ */
+package net.sourceforge.jnlp.security.appletextendedsecurity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AppletSecurityActions {
+    private final List<ExecuteAppletAction> actions = new ArrayList<>();
+
+    
+    /*
+     * backward compatibility method for base, UnsignedAppletTrustConfirmation usage
+     * FIXME - remove
+     */
+    public static AppletSecurityActions fromAction(ExecuteAppletAction s) {
+        if (s == null){
+            s = ExecuteAppletAction.UNSET;
+        }
+        return fromString(s.toChar());
+    }
+    
+    static AppletSecurityActions fromString(String s) {
+        if (s == null) {
+            s = "";
+        }
+        s = s.trim(); //to not return on leading space, may be dangerous, 
+        //but the s shouldbe already trimmed before bubbling here.
+        //does " A"  means UNSET(1)+ALWAYS(2)  or ALWAYS(1)+UNSET(2)
+        //or UNSET(1)+UNSET(2)?
+        AppletSecurityActions asas = new AppletSecurityActions();
+        for (char x : s.toCharArray()){
+            if (Character.isWhitespace(x)){
+                break;
+            }
+            asas.actions.add(ExecuteAppletAction.fromChar(x));
+        }
+        return asas;
+    }
+
+    public ExecuteAppletAction getAction(int i) {
+        if (i>= actions.size()){
+            return ExecuteAppletAction.UNSET;
+        }
+        return actions.get(i);
+    }
+    
+    void setAction(int i, ExecuteAppletAction a) {
+        while (actions.size() <= i){
+            actions.add(ExecuteAppletAction.UNSET);
+        }
+        actions.set(i,a);
+    }
+    
+    
+    public ExecuteAppletAction getUnsignedAppletAction() {
+        return getAction(0);
+    }
+    
+    public void setUnsignedAppletAction(ExecuteAppletAction a) {
+        actions.set(0,a);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        for (ExecuteAppletAction executeAppletAction : actions) {
+            sb.append(executeAppletAction.toChar());
+        }
+        return sb.toString();
+    }
+
+    
+    /**
+     * stub for testing 
+     * @return 
+     */
+    List<ExecuteAppletAction> getActions() {
+        return actions;
+    }
+    
+    
+}
\ No newline at end of file
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteAppletAction.java	Mon May 05 17:11:45 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteAppletAction.java	Fri May 09 14:58:37 2014 +0200
@@ -39,7 +39,7 @@
 
 public enum ExecuteAppletAction {
 
-    ALWAYS, NEVER, YES, SANDBOX, NO;
+    ALWAYS, NEVER, YES, SANDBOX, NO, UNSET;
 
     public String toChar() {
         switch (this) {
@@ -53,6 +53,8 @@
                 return "s";
             case NO:
                 return "n";
+            case UNSET:
+                return "X";
         }
         throw new RuntimeException("Unknown ExecuteUnsignedApplet");
     }
@@ -69,24 +71,36 @@
                 return Translator.R("APPEXTSECunsignedAppletActionSandbox");
             case NO:
                 return Translator.R("APPEXTSECunsignedAppletActionNo");
+            case UNSET:
+                return Translator.R("APPEXTSECunsetAppletAction");
         }
         throw new RuntimeException("Unknown UnsignedAppletAction");
     }
 
     public static ExecuteAppletAction fromString(String s) {
-        if (s.startsWith("A")) {
-            return ExecuteAppletAction.ALWAYS;
-        } else if (s.startsWith("N")) {
-            return ExecuteAppletAction.NEVER;
-        } else if (s.startsWith("y")) {
-            return ExecuteAppletAction.YES;
-        } else if (s.startsWith("s")) {
-            return ExecuteAppletAction.SANDBOX;
-        } else if (s.startsWith("n")) {
-            return ExecuteAppletAction.NO;
-        } else {
-            throw new RuntimeException("Unknown ExecuteUnsignedApplet for " + s);
+        if (s.length() == 0){
+            throw new RuntimeException("Undefined zero-length ExecuteAppletAction String representatio");    
         }
+        return fromChar(s.charAt(0));
+        
+    }
+    
+    public static ExecuteAppletAction fromChar(char s) {
+        switch (s) {
+            case 'A':
+                return ExecuteAppletAction.ALWAYS;
+            case 'N':
+                return ExecuteAppletAction.NEVER;
+            case 'y':
+                return ExecuteAppletAction.YES;
+            case 's':
+                return ExecuteAppletAction.SANDBOX;
+            case 'n':
+                return ExecuteAppletAction.NO;
+            case 'X':
+                return ExecuteAppletAction.UNSET;
+        }
+        throw new RuntimeException("Unknown ExecuteUnsignedApplet for " + s);
     }
 
     @Override
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Mon May 05 17:11:45 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Fri May 09 14:58:37 2014 +0200
@@ -43,7 +43,7 @@
 
 public class UnsignedAppletActionEntry {
 
-    private ExecuteAppletAction unsignedAppletAction;
+    private final AppletSecurityActions unsignedAppletAction;
     private Date timeStamp;
     private UrlRegEx documentBase;
     private UrlRegEx codeBase;
@@ -52,7 +52,7 @@
     public static UnsignedAppletActionEntry createFromString(String s) {
         String[] split = s.split("\\s+");
         UnsignedAppletActionEntry nw = new UnsignedAppletActionEntry(
-                ExecuteAppletAction.fromString(split[0]),
+                AppletSecurityActions.fromString(split[0]),
                 new Date(new Long(split[1])),
                 new UrlRegEx(split[2]),
                 null,
@@ -66,7 +66,7 @@
         return nw;
     }
 
-    public UnsignedAppletActionEntry(ExecuteAppletAction unsignedAppletAction, Date timeStamp, UrlRegEx documentBase, UrlRegEx codeBase, List<String> archives) {
+    public UnsignedAppletActionEntry(AppletSecurityActions unsignedAppletAction, Date timeStamp, UrlRegEx documentBase, UrlRegEx codeBase, List<String> archives) {
         this.unsignedAppletAction = unsignedAppletAction;
         this.timeStamp = timeStamp;
         this.documentBase = documentBase;
@@ -86,7 +86,7 @@
     }
 
     private String serializeToReadableAndParseableString() {
-        return unsignedAppletAction.toChar()
+        return unsignedAppletAction.toString()
                 + " " + ((timeStamp == null) ? "1" : timeStamp.getTime())
                 + " " + ((documentBase == null) ? "" : documentBase.getRegEx())
                 + " " + ((codeBase == null) ? "" : codeBase.getRegEx())
@@ -110,11 +110,20 @@
     }
 
     public ExecuteAppletAction getUnsignedAppletAction() {
+        return unsignedAppletAction.getUnsignedAppletAction();
+    }
+    
+    /**
+     * should be testing only
+     * 
+     * @return 
+     */
+    public AppletSecurityActions getAppletSecurityActions() {
         return unsignedAppletAction;
     }
 
     public void setUnsignedAppletAction(ExecuteAppletAction unsignedAppletAction) {
-        this.unsignedAppletAction = unsignedAppletAction;
+        this.unsignedAppletAction.setUnsignedAppletAction(unsignedAppletAction);
     }
 
     public UrlRegEx getCodeBase() {
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Mon May 05 17:11:45 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Fri May 09 14:58:37 2014 +0200
@@ -148,7 +148,7 @@
             }
 
             UnsignedAppletActionEntry entry = new UnsignedAppletActionEntry(
-                    behaviour, 
+                    AppletSecurityActions.fromAction(behaviour), 
                     new Date(),
                     documentbaseRegex, 
                     codebaseRegex,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActionsTest.java	Fri May 09 14:58:37 2014 +0200
@@ -0,0 +1,147 @@
+/*   Copyright (C) 2014 Red Hat, Inc.
+
+ This file is part of IcedTea.
+
+ IcedTea is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, version 2.
+
+ IcedTea is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with IcedTea; see the file COPYING.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library.  Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module.  An independent module is a module which is not derived from
+ or based on this library.  If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so.  If you do not wish to do so, delete this
+ exception statement from your version.
+ */
+package net.sourceforge.jnlp.security.appletextendedsecurity;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class AppletSecurityActionsTest {
+
+    @Test
+    public void parseMultipleItemsCorrect() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("ANynsXsnyNA");
+        assertEquals(ExecuteAppletAction.ALWAYS, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.NEVER, a1.getAction(1));
+        assertEquals(ExecuteAppletAction.YES, a1.getAction(2));
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(3));
+        assertEquals(ExecuteAppletAction.SANDBOX, a1.getAction(4));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(5));
+        assertEquals(ExecuteAppletAction.SANDBOX, a1.getAction(6));
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(7));
+        assertEquals(ExecuteAppletAction.YES, a1.getAction(8));
+        assertEquals(ExecuteAppletAction.NEVER, a1.getAction(9));
+        assertEquals(ExecuteAppletAction.ALWAYS, a1.getAction(10));
+        assertEquals(11, a1.getActions().size());
+    }
+
+    @Test
+    public void parseEmpty() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("");
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(10));
+        assertEquals(0, a1.getActions().size());
+    }
+
+    @Test
+    public void parseOkSetAndGetZero() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("");
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(0));
+        assertEquals(0, a1.getActions().size());
+        a1.setAction(0, ExecuteAppletAction.YES);
+        assertEquals(ExecuteAppletAction.YES, a1.getAction(0));
+        assertEquals(1, a1.getActions().size());
+    }
+
+    @Test
+    public void parseOkSetAndGet() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("s");
+        assertEquals(ExecuteAppletAction.SANDBOX, a1.getAction(0));
+        assertEquals(1, a1.getActions().size());
+        a1.setAction(0, ExecuteAppletAction.NO);
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(0));
+        assertEquals(1, a1.getActions().size());
+        a1.setAction(1, ExecuteAppletAction.YES);
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.YES, a1.getAction(1));
+        assertEquals(2, a1.getActions().size());
+        a1.setAction(0, ExecuteAppletAction.NO);
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(0));
+        assertEquals(2, a1.getActions().size());
+        a1.setAction(4, ExecuteAppletAction.NEVER);
+        assertEquals(ExecuteAppletAction.NO, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.YES, a1.getAction(1));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(2));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(3));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(3));
+        assertEquals(ExecuteAppletAction.NEVER, a1.getAction(4));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(5));//default again
+        assertEquals(5, a1.getActions().size());
+
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void parseNotOkGet() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("ANynsXsnyNA");
+        a1.getAction(-1);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void parseNotOkSet() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("ANynsXsnyNA");
+        a1.setAction(-1, ExecuteAppletAction.NO);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void parseMultipleItemsToSomeWrong() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("AQA");
+    }
+
+    @Test
+    public void parseMultipleItemsFillMissing() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("AN");
+        assertEquals(ExecuteAppletAction.ALWAYS, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.NEVER, a1.getAction(1));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(2));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(3));
+        //note, getters do not increase length
+        assertEquals(2, a1.getActions().size());
+    }
+
+    @Test
+    public void parseMultipleItemsSpaceEnd() throws Exception {
+        AppletSecurityActions a1 = AppletSecurityActions.fromString("ANXs AAA");
+        assertEquals(ExecuteAppletAction.ALWAYS, a1.getAction(0));
+        assertEquals(ExecuteAppletAction.NEVER, a1.getAction(1));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(2));
+        assertEquals(ExecuteAppletAction.SANDBOX, a1.getAction(3));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(4));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(5));
+        assertEquals(ExecuteAppletAction.UNSET, a1.getAction(10));
+        assertEquals(4, a1.getActions().size());
+    }
+
+}
--- a/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java	Mon May 05 17:11:45 2014 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java	Fri May 09 14:58:37 2014 +0200
@@ -1,3 +1,40 @@
+/*   Copyright (C) 2014 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+
 package net.sourceforge.jnlp.security.appletextendedsecurity;
 
 import static org.junit.Assert.assertEquals;
--- a/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java	Mon May 05 17:11:45 2014 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java	Fri May 09 14:58:37 2014 +0200
@@ -32,16 +32,16 @@
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version.
- */
-
+*/
 package net.sourceforge.jnlp.security.appletextendedsecurity.impl;
 
-import net.sourceforge.jnlp.security.appletextendedsecurity.impl.UnsignedAppletActionStorageImpl;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
+import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -52,83 +52,172 @@
     private static File f1;
     private static File f2;
     private static File f3;
-    private static File f4;
+    private static File ff1;
+    private static File ff2;
+    private static File ff3;
+    private static File ff4;
 
     @BeforeClass
     public static void preapreTestFiles() throws IOException {
         f1 = File.createTempFile("itwMatching", "testFile1");
         f2 = File.createTempFile("itwMatching", "testFile2");
         f3 = File.createTempFile("itwMatching", "testFile3");
-        f4 = File.createTempFile("itwMatching", "testFile4");
         ServerAccess.saveFile("A 123456 .* .* jar1,jar2", f1);
-        ServerAccess.saveFile("A 123456 .* \\Qbla\\E jar1,jar2", f2);
+        ServerAccess.saveFile("N 123456 .* \\Qbla\\E jar1,jar2", f2);
         ServerAccess.saveFile(""
                 + "A 1 \\Qhttp://jmol.sourceforge.net/demo/atoms/\\E \\Qhttp://jmol.sourceforge.net/jmol/\\E JmolApplet0.jar\n"
-                + "A 1363278653454 \\Qhttp://www.walter-fendt.de/ph14e\\E.* \\Qhttp://www.walter-fendt.de\\E.*\n"
+                + "N 1363278653454 \\Qhttp://www.walter-fendt.de/ph14e\\E.* \\Qhttp://www.walter-fendt.de\\E.*\n"
                 + "n 1363281783104 \\Qhttp://www.walter-fendt.de/ph14e/inclplane.htm\\E \\Qhttp://www.walter-fendt.de/ph14_jar/\\E Ph14English.jar,SchiefeEbene.jar"
                 + "", f3);
+
+        ff1 = File.createTempFile("itwMatching", "testFile1");
+        ff2 = File.createTempFile("itwMatching", "testFile2");
+        ff3 = File.createTempFile("itwMatching", "testFile3");
+        ff4 = File.createTempFile("itwMatching", "testFile3");
+        ServerAccess.saveFile("AXn 123456 .* .* jar1,jar2", ff1);
+        ServerAccess.saveFile("XXXXXy 123456 .* \\Qbla\\E jar1,jar2", ff2);
+        ServerAccess.saveFile("XXXXXY 123456 .* \\Qbla\\E jar1,jar2", ff4);//errornous
+        ServerAccess.saveFile(""
+                + "XA 1 \\Qa\\E \\Qb\\E jar1\n"
+                + "NNA 2 \\Qc\\E \\Qd\\E\n"
+                + "nyXyn 3 \\Qe\\E \\Qf\\E j1,j2"
+                + "", ff3);
+    }
+
+    @AfterClass
+    public static void removeTestFiles() throws IOException {
+        f1.delete();
+        f2.delete();
+        f3.delete();
+        ff1.delete();
+        ff2.delete();
+        ff3.delete();
+        ff4.delete();
+    }
+
+    @Test
+    public void multipleActionsf4JustLoad() {
+        UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(ff4);
+        //pass
     }
 
-     @AfterClass
-    public static void removeTestFiles() throws IOException {
-         f1.delete();
-         f2.delete();
-         f3.delete();
-     }
+    @Test(expected = RuntimeException.class)
+    public void multipleActionsf4() {
+        UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(ff4);
+        //reed whatever
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("a", "b", Arrays.asList(new String[]{"jar1"}));
+    }
+
+    @Test
+    public void multipleActionsf3() {
+        UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(ff3);
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("a", "b", Arrays.asList(new String[]{"jar1"}));
+        UnsignedAppletActionEntry r2 = i1.getMatchingItem("c", "d", Arrays.asList(new String[]{}));
+        UnsignedAppletActionEntry r3 = i1.getMatchingItem("e", "f", Arrays.asList(new String[]{"j1", "j2"}));
+
+        Assert.assertNotNull("r1 should be found", r1);
+        checkValues(r1, ExecuteAppletAction.UNSET, ExecuteAppletAction.ALWAYS);
+
+        Assert.assertNotNull("r2 should be found", r2);
+        checkValues(r2, ExecuteAppletAction.NEVER, ExecuteAppletAction.NEVER, ExecuteAppletAction.ALWAYS);
 
+        Assert.assertNotNull("r3 should be found", r3);
+        checkValues(r3, ExecuteAppletAction.NO, ExecuteAppletAction.YES, ExecuteAppletAction.UNSET, ExecuteAppletAction.YES, ExecuteAppletAction.NO);
+    }
 
-     @Test
+    @Test
+    public void multipleActionsf2() {
+        UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(ff2);
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("whatever", "bla", Arrays.asList(new String[]{"jar1", "jar2"}));
+        Assert.assertNotNull("r1 should be found", r1);
+        checkValues(r1, ExecuteAppletAction.UNSET, ExecuteAppletAction.UNSET, ExecuteAppletAction.UNSET, ExecuteAppletAction.UNSET, ExecuteAppletAction.UNSET, ExecuteAppletAction.YES);
+    }
+
+    @Test
+    public void multipleActionsf1() {
+        UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(ff1);
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar1", "jar2"}));
+        Assert.assertNotNull("r1 should be found", r1);
+        checkValues(r1, ExecuteAppletAction.ALWAYS, ExecuteAppletAction.UNSET, ExecuteAppletAction.NO);
+
+    }
+
+    @Test
     public void wildcards1() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f3);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("http://www.walter-fendt.de/ph14e/inclplane.htm", "http://www.walter-fendt.de/ph14_jar/", Arrays.asList(new String[]{"Ph14English.jar","SchiefeEbene.jar"}));
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("http://www.walter-fendt.de/ph14e/inclplane.htm", "http://www.walter-fendt.de/ph14_jar/", Arrays.asList(new String[]{"Ph14English.jar", "SchiefeEbene.jar"}));
+        Assert.assertNotNull("r1 should be found", r1);
         ServerAccess.logOutputReprint(r1.toString());
-     }
-     @Test
+        checkValues(r1, ExecuteAppletAction.NEVER);
+    }
+
+    @Test
     public void allMatchingDocAndCode() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f1);
         UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar1", "jar2"}));
         Assert.assertNotNull("r1 should be found", r1);
+        checkValues(r1, ExecuteAppletAction.ALWAYS);
         UnsignedAppletActionEntry r3 = i1.getMatchingItem("blah", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}));
-        Assert.assertNotNull("r3 should be found", r1);
-        UnsignedAppletActionEntry r4 = i1.getMatchingItem("blha", "blaBlam",  Arrays.asList(new String[]{"jar2", "wrong_jar"}));
+        checkValues(r3, ExecuteAppletAction.ALWAYS);
+        Assert.assertNotNull("r3 should be found", r3);
+        UnsignedAppletActionEntry r4 = i1.getMatchingItem("blha", "blaBlam", Arrays.asList(new String[]{"jar2", "wrong_jar"}));
         Assert.assertNull("r4 should NOT be found", r4);
-        UnsignedAppletActionEntry r5 = i1.getMatchingItem("blaBla", "blaBlaBla",  Arrays.asList(new String[]{"jar2"}));
+        UnsignedAppletActionEntry r5 = i1.getMatchingItem("blaBla", "blaBlaBla", Arrays.asList(new String[]{"jar2"}));
         Assert.assertNull("r5 should NOT be found", r5);
 
     }
 
-     @Test
+    @Test
     public void allMatchingDocAndStrictCode() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f2);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("whatever", "bla",  Arrays.asList(new String[]{"jar1", "jar2"}));
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("whatever", "bla", Arrays.asList(new String[]{"jar1", "jar2"}));
         Assert.assertNotNull("r1 should be found", r1);
-        UnsignedAppletActionEntry r3 = i1.getMatchingItem("whatever", null,  Arrays.asList(new String[]{"jar2", "jar1"}));
-        Assert.assertNotNull("r3 should be found", r1);
-        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBlam",  Arrays.asList(new String[]{"jar1", "jar2"}));
+        checkValues(r1, ExecuteAppletAction.NEVER);
+        UnsignedAppletActionEntry r3 = i1.getMatchingItem("whatever", null, Arrays.asList(new String[]{"jar2", "jar1"}));
+        Assert.assertNotNull("r3 should be found", r3);
+        checkValues(r3, ExecuteAppletAction.NEVER);
+        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBlam", Arrays.asList(new String[]{"jar1", "jar2"}));
         Assert.assertNull("r2 should NOT be found", r2);
         UnsignedAppletActionEntry r4 = i1.getMatchingItem(null, "blaBlam", null);
         Assert.assertNull("r4 should NOT be found", r4);
 
     }
 
-     @Test
+    @Test
     public void allMatchingDocAndCodeWithNulls() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f1);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla",  null);
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla", null);
         Assert.assertNotNull("r1 should be found", r1);
+        checkValues(r1, ExecuteAppletAction.ALWAYS);
         UnsignedAppletActionEntry r3 = i1.getMatchingItem("bla", "whatever", null);
-        Assert.assertNotNull("r3 should be found", r1);
+        Assert.assertNotNull("r3 should be found", r3);
+        checkValues(r3, ExecuteAppletAction.ALWAYS);
         UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}));
         Assert.assertNotNull("r2 should be found", r2);
-        UnsignedAppletActionEntry r4 = i1.getMatchingItem("bla", "blaBla",  null);
+        checkValues(r2, ExecuteAppletAction.ALWAYS);
+        UnsignedAppletActionEntry r4 = i1.getMatchingItem("bla", "blaBla", null);
         Assert.assertNotNull("r4 should be found", r4);
-        UnsignedAppletActionEntry r5 = i1.getMatchingItem("", "blaBla",  Arrays.asList(new String[]{"jar2", "jar1"}));
+        checkValues(r2, ExecuteAppletAction.ALWAYS);
+        UnsignedAppletActionEntry r5 = i1.getMatchingItem("", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}));
         Assert.assertNotNull("r5 should be found", r5);
-        UnsignedAppletActionEntry r6 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r6 = i1.getMatchingItem(null, null, Arrays.asList(new String[]{"jar2", "jar1"}));
         Assert.assertNotNull("r6 should be found", r6);
-        UnsignedAppletActionEntry r7 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar11"}));
+        UnsignedAppletActionEntry r7 = i1.getMatchingItem(null, null, Arrays.asList(new String[]{"jar2", "jar11"}));
         Assert.assertNull("r7 should NOT be found", r7);
 
+    }
+
+    private void checkValues(UnsignedAppletActionEntry item, ExecuteAppletAction... items) {
+        AppletSecurityActions as = item.getAppletSecurityActions();
+        for (int i = 0; i < items.length; i++) {
+            Assert.assertEquals(items[i], as.getAction(i));
+
+        }
+        for (int i = items.length; i < 1000; i++) {
+            Assert.assertEquals(ExecuteAppletAction.UNSET, as.getAction(i));
+
+        }
 
     }
+
 }