changeset 1289:53500e3de1bc

Newline characters are banned from saving to .appletTrustSettings
author Jiri Vanek <jvanek@redhat.com>
date Wed, 02 Sep 2015 18:24:33 +0200
parents ee5e2cb91774
children fb798629d70a
files ChangeLog netx/net/sourceforge/jnlp/runtime/HtmlBoot.java netx/net/sourceforge/jnlp/runtime/html/AppletExtractor.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/InvalidLineException.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java tests/reproducers/simple/UnicodeLineBreak/resources/UnicodeLineBreak.html tests/reproducers/simple/UnicodeLineBreak/srcs/UnicodeLineBreak.java tests/reproducers/simple/UnicodeLineBreak/testcases/UnicodeLineBreakTests.java
diffstat 10 files changed, 520 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Sep 01 14:52:24 2015 +0200
+++ b/ChangeLog	Wed Sep 02 18:24:33 2015 +0200
@@ -1,3 +1,25 @@
+2015-09-02  Jiri Vanek  <jvanek@redhat.com>
+
+	Newline characters are banned from saving to .appletTrustSettings
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/InvalidLineException.java:
+	New file. Exception to be specially handled if error appear in saved line.
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java:
+	(serializeToReadableAndParseableString) if new-line appear in line,
+	InvalidLineException is thrown
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java:
+	(writeContent) InvalidLineException is expected and logged.
+	* tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java:
+	adapted and quite a lot of tests added.
+	* tests/reproducers/simple/UnicodeLineBreak/resources/UnicodeLineBreak.java:
+	* tests/reproducers/simple/UnicodeLineBreak/srcs/UnicodeLineBreak.java:
+	* tests/reproducers/simple/UnicodeLineBreak/testcases/UnicodeLineBreakTests.java:
+	half automated reproducer of this behavior	
+	* netx/net/sourceforge/jnlp/runtime/HtmlBoot.java: based on existence of -xml,
+	now can turn off tagsoup
+	* netx/net/sourceforge/jnlp/runtime/html/AppletExtractor.java: is passing
+	parsersettings to HtmlBoot
+
+
 2015-09-01  Jiri Vanek  <jvanek@redhat.com>
 
 	Saving of status of dialogs for "whole codebase" now includes also document base
--- a/netx/net/sourceforge/jnlp/runtime/HtmlBoot.java	Tue Sep 01 14:52:24 2015 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/HtmlBoot.java	Wed Sep 02 18:24:33 2015 +0200
@@ -132,7 +132,7 @@
         try {
             OutputController.getLogger().log("Proceeding with html");
             final URL html = Boot.getFileLocation();
-            AppletExtractor axe = new AppletExtractor(html);
+            AppletExtractor axe = new AppletExtractor(html, settings);
             AppletsFilter filtered = new AppletsFilter(axe.findAppletsOnPage(), html, vars.subList(1, vars.size()));
             List<AppletParser> applets = filtered.getApplets();
             // this hack was needed in early phases of the patch.   Now it sees to be not neede. Keeping inside to remove after much more testing
--- a/netx/net/sourceforge/jnlp/runtime/html/AppletExtractor.java	Tue Sep 01 14:52:24 2015 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/html/AppletExtractor.java	Wed Sep 02 18:24:33 2015 +0200
@@ -45,7 +45,9 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.OptionsDefinitions;
 import net.sourceforge.jnlp.Parser;
+import net.sourceforge.jnlp.ParserSettings;
 import net.sourceforge.jnlp.cache.UpdatePolicy;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.util.logging.OutputController;
@@ -68,10 +70,15 @@
         "applet", "APPLET", "Applet",
         "object", "OBJECT", "Object",
         "embed", "EMBED", "Embed"};
+    private final ParserSettings ps;
 
     public AppletExtractor(URL html) {
+        this(html, null);
+    }
+    public AppletExtractor(URL html, ParserSettings ps) {
         JNLPRuntime.saveHistory(html.toExternalForm());
         this.html = html;
+        this.ps = ps;
     }
 
     public URL getHtml() {
@@ -80,9 +87,13 @@
 
     private InputStream cleanStreamIfPossible(InputStream is) {
         try {
-            Class<?> klass = Class.forName(Parser.MALFORMED_PARSER_CLASS);
-            Method m = klass.getMethod("xmlizeInputStream", InputStream.class);
-            return (InputStream) m.invoke(null, is);
+            if (ps != null && ps.isMalformedXmlAllowed()){
+                Class<?> klass = Class.forName(Parser.MALFORMED_PARSER_CLASS);
+                Method m = klass.getMethod("xmlizeInputStream", InputStream.class);
+                return (InputStream) m.invoke(null, is);
+            } else {
+                OutputController.getLogger().log(OutputController.Level.WARNING_DEBUG, "Tagsoup's html2xml cleaning is Disabled. Remove "+OptionsDefinitions.OPTIONS.XML.option+". Parsing will probably fail.");    
+            }
         } catch (Exception ex) {
             OutputController.getLogger().log(OutputController.Level.WARNING_DEBUG, "Tagsoup's html2xml cleaning not loaded. Install tagsoup. Parsing will probably fail.");
             OutputController.getLogger().log(ex);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/InvalidLineException.java	Wed Sep 02 18:24:33 2015 +0200
@@ -0,0 +1,47 @@
+/* 
+ Copyright (C) 2015 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;
+
+
+public class InvalidLineException extends RuntimeException {
+
+    public InvalidLineException(String s) {
+        super(s);
+    }
+    
+}
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Tue Sep 01 14:52:24 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Wed Sep 02 18:24:33 2015 +0200
@@ -93,12 +93,16 @@
         bw.write(this.serializeToReadableAndParseableString());
     }
 
-    private String serializeToReadableAndParseableString() {
-        return appletSecurityActions.toString()
+    private String serializeToReadableAndParseableString() throws InvalidLineException {
+        String s = appletSecurityActions.toString()
                 + " " + ((timeStamp == null) ? "1" : timeStamp.getTime())
                 + " " + ((documentBase == null) ? "" : documentBase.getRegEx())
                 + " " + ((codeBase == null) ? "" : codeBase.getRegEx())
                 + " " + createArchivesString(archives);
+        if (s.contains("\n") || s.contains("\r") || s.contains("\f")){
+            throw new InvalidLineException("Cant write line with \\n, \\r or \\f");
+        }
+        return s;
     }
 
     public Date getTimeStamp() {
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Tue Sep 01 14:52:24 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Wed Sep 02 18:24:33 2015 +0200
@@ -41,12 +41,14 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import net.sourceforge.jnlp.security.appletextendedsecurity.InvalidLineException;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionStorage;
 import net.sourceforge.jnlp.security.dialogs.remember.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.dialogs.remember.RememberableDialog;
 import net.sourceforge.jnlp.util.lockingfile.LockingReaderWriter;
 import net.sourceforge.jnlp.util.lockingfile.StorageIoException;
+import net.sourceforge.jnlp.util.logging.OutputController;
 
 public class UnsignedAppletActionStorageImpl extends LockingReaderWriter implements UnsignedAppletActionStorage {
 
@@ -73,7 +75,7 @@
     @Override
     protected void readContents() throws IOException {
         if (items == null) {
-            items = new ArrayList<UnsignedAppletActionEntry>();
+            items = new ArrayList<>();
         } else {
             items.clear();
         }
@@ -90,8 +92,12 @@
     @Override
     public void writeContent(BufferedWriter bw) throws IOException {
         for (UnsignedAppletActionEntry item : items) {
-            item.write(bw);
-            bw.newLine();
+            try{
+                item.write(bw);
+                bw.newLine();
+            }catch (InvalidLineException ex){
+                OutputController.getLogger().log(ex);
+            }
         }
     }
 
--- a/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java	Tue Sep 01 14:52:24 2015 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmationTest.java	Wed Sep 02 18:24:33 2015 +0200
@@ -36,6 +36,8 @@
 package net.sourceforge.jnlp.security.appletextendedsecurity;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
@@ -43,15 +45,19 @@
 import static org.junit.Assert.assertEquals;
 
 import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
 import net.sourceforge.jnlp.InformationDesc;
-import net.sourceforge.jnlp.config.InfrastructureFileDescriptor;
+import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.browsertesting.browsers.firefox.FirefoxProfilesOperator;
 import net.sourceforge.jnlp.config.PathsAndFiles;
 import net.sourceforge.jnlp.mock.DummyJNLPFileWithJar;
+import net.sourceforge.jnlp.security.appletextendedsecurity.impl.UnsignedAppletActionStorageImpl;
 import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.UnsignedAppletTrustWarningPanel;
 import net.sourceforge.jnlp.security.dialogs.remember.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.dialogs.remember.SavedRememberAction;
 import net.sourceforge.jnlp.util.FileUtils;
-import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 
@@ -64,12 +70,11 @@
     private static final String url42 = "resource.jar";
     private static URL url;
     private static URL url4;
-    private static InfrastructureFileDescriptor APPLET_TRUST_SETTINGS_USER_BACKUP;
 
     private static class DummyJnlpWithTitleAndUrls extends DummyJNLPFileWithJar {
 
         public DummyJnlpWithTitleAndUrls(URL u) throws MalformedURLException {
-            super(null, u);
+            super(url, u);
         }
 
         @Override
@@ -101,49 +106,30 @@
         url=new URL(surl1);
         url4=new URL(url41+url42);
     }
-    
-    
+   
+   private static File backup;
+
     @BeforeClass
-    public static void backupAppTrsSets() {
-        APPLET_TRUST_SETTINGS_USER_BACKUP = PathsAndFiles.APPLET_TRUST_SETTINGS_USER;
-    }
-    
-    @After
-    public  void restoreAppTrsSets() throws Exception {
-        fakeAppTrsSets(APPLET_TRUST_SETTINGS_USER_BACKUP);
+    public static void backupAppTrust() throws IOException{
+        backup = File.createTempFile("appletExtendedSecurity", "itwUnittest");
+        backup.deleteOnExit();
+        FirefoxProfilesOperator.copyFile(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile(), backup);
     }
     
-    private static void fakeAppTrsSets(final File f) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
-        fakeAppTrsSets(new InfrastructureFileDescriptor() {
-
-            @Override
-            public String getFullPath() {
-                return f.getAbsolutePath();
-            }
-
-        });
+    @AfterClass
+    public static void restoreAppTrust() throws IOException{
+        FirefoxProfilesOperator.copyFile(backup, PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
     }
-    private static void fakeAppTrsSets(InfrastructureFileDescriptor fake) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
-        Field field = PathsAndFiles.class.getDeclaredField("APPLET_TRUST_SETTINGS_USER");
-        field.setAccessible(true);
-        Field modifiersField = Field.class.getDeclaredField("modifiers");
-        modifiersField.setAccessible(true);
-        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
-        field.set(null, fake);
-    }
-
 
     @Test
     public void updateAppletActionTest1() throws Exception {
-        File f = File.createTempFile("appletExtendedSecurity", "itwUnittest");
-        f.deleteOnExit();
-        fakeAppTrsSets(f);
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
         UnsignedAppletTrustConfirmation.updateAppletAction(
                 new DummyJnlpWithTitleAndUrls(url4),
                 new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
                 Boolean.FALSE,
                 UnsignedAppletTrustWarningPanel.class);
-        String s = FileUtils.loadFileAsString(f);
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
         Assert.assertTrue(s.contains("UnsignedAppletTrustWarningPanel:A{YES}"));
         Assert.assertTrue(s.contains(url41+url42));
         Assert.assertTrue(s.contains(surl1));
@@ -152,7 +138,7 @@
                 new SavedRememberAction(ExecuteAppletAction.NEVER, "NO"),
                 Boolean.TRUE,
                 UnsignedAppletTrustWarningPanel.class);
-        s = FileUtils.loadFileAsString(f);
+        s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
         Assert.assertTrue(s.contains("UnsignedAppletTrustWarningPanel:N{NO}"));
         Assert.assertFalse(s.contains(url41+url42));
         Assert.assertTrue(s.contains(surl1));        
@@ -207,4 +193,172 @@
         assertEquals(sample, result);
         
     }
+    
+    
+    private static URL urlX1;
+    private static URL urlX2;
+    private static URL urlX3;
+    
+    private static URL urlY1;
+    private static URL urlY2;
+    private static URL urlY3;
+    private static URL urlY4;
+    private static URL urlY5;
+    private static URL urlY6;
+    private static URL urlY7;
+    private static URL urlY8;
+    
+    @BeforeClass
+    public static void initUrlsX123() throws MalformedURLException, IOException {
+        urlX1 = new URL("http://&#10;does&#32;not&#32;metter&#32;is&#32;ok");
+        urlX2 = new URL("http://\ndoes not metter is harmfull");
+        Properties p = new Properties();
+        p.load(new StringReader("key=http:\\u002F\\u002F\\u000Adoes\\u0020not\\u0020metter\\u0020is\\u0020harmfull"));
+        urlX3=new URL(p.getProperty("key"));
+    }
+
+    @BeforeClass
+    public static void initUrlsY12345678() throws MalformedURLException, IOException {
+        urlY1 = new URL("http://som\\EeUrl.cz/aa");
+        urlY2 = new URL("http://some\\QUrl.cz/aa");
+        urlY3 = new URL("http://so\\QmeU\\Erl.cz/aa");
+        urlY4 = new URL("http://so\\EmeU\\Qrl.cz/aa");
+
+        urlY5 = new URL("http://someUrl.cz/aa\\Ebb/cc");
+        urlY6 = new URL("http://someUrl.cz/aa\\Qbb/cc");
+        urlY7 = new URL("http://someUrl.cz/aa\\Qbb/cc/dd\\Eee");
+        urlY8 = new URL("http://someUrl.cz/aa\\Ebb/cc/dd\\Qee");
+    }
+
+    @Test
+    public void updateAppletActionTestYQN1234saveAndLoadFine() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY1),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY2),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY3),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY4),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        AppletStartupSecuritySettings securitySettings = AppletStartupSecuritySettings.getInstance();
+        UnsignedAppletActionStorageImpl userActionStorage = (UnsignedAppletActionStorageImpl) securitySettings.getUnsignedAppletActionCustomStorage();
+        List<UnsignedAppletActionEntry> ll = userActionStorage.getMatchingItems(null, null, null);
+        Assert.assertEquals(4, ll.size());
+    }
+
+    @Test
+    public void updateAppletActionTestYQN5678saveAndLoadFine() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY5),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY6),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY7),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrlsWithOverwrite(urlY8),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        AppletStartupSecuritySettings securitySettings = AppletStartupSecuritySettings.getInstance();
+        UnsignedAppletActionStorageImpl userActionStorage = (UnsignedAppletActionStorageImpl) securitySettings.getUnsignedAppletActionCustomStorage();
+        List<UnsignedAppletActionEntry> ll = userActionStorage.getMatchingItems(null, null, null);
+        Assert.assertEquals(4, ll.size());
+    }
+    
+    @Test
+    public void updateAppletActionTestX3() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        try{
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrls(urlX3),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        //may throw  RuntimeExeption which is correct, however, wee need to check result
+        } catch (Exception ex){
+            ServerAccess.logException(ex);
+        }
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        Assert.assertFalse(s.contains("harmfull"));
+    }
+    
+    @Test
+    public void updateAppletActionTestX2() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        try{
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrls(urlX2),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        //may throw  RuntimeExeption which is correct, however, wee need to check result
+        } catch (Exception ex){
+            ServerAccess.logException(ex);
+        }
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        Assert.assertFalse(s.contains("harmfull"));
+    }
+    
+     @Test
+    public void updateAppletActionTestX1() throws Exception {
+        //this case is correct, if html ecnoded url is passed as URL from javaws, it is kept intact
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        Exception eex = null;
+        try{
+        UnsignedAppletTrustConfirmation.updateAppletAction(
+                new DummyJnlpWithTitleAndUrls(urlX1),
+                new SavedRememberAction(ExecuteAppletAction.ALWAYS, "YES"),
+                Boolean.FALSE,
+                UnsignedAppletTrustWarningPanel.class);
+        //may throw  RuntimeExeption which is correct, however, wee need to check result
+        } catch (Exception ex){
+            eex = ex;
+            ServerAccess.logException(ex);
+        }
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        Assert.assertNull(eex);
+        Assert.assertTrue(s.contains("http://&#10;does&#32;not&#32;metter&#32;is&#32;ok"));
+    }
+
+    private static class DummyJnlpWithTitleAndUrlsWithOverwrite extends DummyJnlpWithTitleAndUrls {
+        private final URL u;
+
+        public DummyJnlpWithTitleAndUrlsWithOverwrite(URL u) throws MalformedURLException {
+            super(u);
+            this.u  = u;
+        }
+
+        @Override
+        public URL getCodeBase() {
+            return u;
+        }
+
+            @Override
+            public URL getSourceLocation() {
+                return u;
+            }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/simple/UnicodeLineBreak/resources/UnicodeLineBreak.html	Wed Sep 02 18:24:33 2015 +0200
@@ -0,0 +1,44 @@
+<!--
+
+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; either version 2, or (at your option)
+any later version.
+
+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.
+
+ -->
+<html><head></head><body bgcolor="blue">
+        <!-- Note, any malicious record may be behind &#10; see assertFalse in testcase-->
+<p><applet id="UnicodeLineBreak1" code="UnicodeLineBreak.class" archive="UnicodeLineBreak.jar, http://&#10;A&#32;1432197956873&#32;\Qhttp:&#47;&#47;evil-site&#47;evil.page&#47;\E&#32;\Qhttp:&#47;&#47;evil-site&#47;\E&#32;malware.jar" codebase="." width="100" height="100">
+</applet></p>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/simple/UnicodeLineBreak/srcs/UnicodeLineBreak.java	Wed Sep 02 18:24:33 2015 +0200
@@ -0,0 +1,47 @@
+
+import java.applet.Applet;
+
+/* AppletTest.java
+Copyright (C) 2011 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.
+ */
+public class UnicodeLineBreak extends Applet {
+
+    @Override
+    public void init() {
+         System.out.println("*** APPLET FINISHED ***");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/simple/UnicodeLineBreak/testcases/UnicodeLineBreakTests.java	Wed Sep 02 18:24:33 2015 +0200
@@ -0,0 +1,140 @@
+/* AppletTestTests.java
+Copyright (C) 2011 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import net.sourceforge.jnlp.OptionsDefinitions;
+import static org.junit.Assert.assertTrue;
+
+import net.sourceforge.jnlp.ProcessResult;
+import net.sourceforge.jnlp.ProcessWrapper;
+import net.sourceforge.jnlp.ServerAccess.AutoClose;
+import net.sourceforge.jnlp.browsertesting.BrowserTest;
+import net.sourceforge.jnlp.browsertesting.Browsers;
+import net.sourceforge.jnlp.closinglisteners.AutoOkClosingListener;
+import net.sourceforge.jnlp.annotations.NeedsDisplay;
+import net.sourceforge.jnlp.annotations.TestInBrowsers;
+import net.sourceforge.jnlp.browsertesting.browsers.firefox.FirefoxProfilesOperator;
+import net.sourceforge.jnlp.config.DeploymentConfiguration;
+import net.sourceforge.jnlp.config.PathsAndFiles;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel;
+import net.sourceforge.jnlp.tools.DeploymentPropertiesModifier;
+import net.sourceforge.jnlp.util.FileUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+
+import org.junit.Test;
+
+public class UnicodeLineBreakTests extends BrowserTest {
+    private static DeploymentPropertiesModifier dp;
+    private static File backup;
+
+
+    @BeforeClass
+    public static void setSecurity() throws IOException{
+        dp = new DeploymentPropertiesModifier();
+        dp.setProperties(DeploymentConfiguration.KEY_SECURITY_LEVEL, AppletSecurityLevel.ASK_UNSIGNED.name());
+    }
+    
+    @BeforeClass
+    public static void backupAppTrust() throws IOException{
+        backup = File.createTempFile("unicodeNewLIne", "itwReproducers");
+        backup.deleteOnExit();
+        FirefoxProfilesOperator.copyFile(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile(), backup);
+    }
+    
+    @AfterClass
+    public static void restoreAppTrust() throws IOException{
+        FirefoxProfilesOperator.copyFile(backup, PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+    }
+    
+    
+     @AfterClass
+    public static void resetSecurity() throws IOException{
+        dp.restoreProperties();
+        
+    }
+    //headless dialogues now works only for javaws. press ok, otherwise first assert  fails
+    //@Test
+    @TestInBrowsers(testIn = { Browsers.all })
+    @NeedsDisplay
+    public void unicodeLineBreakTest() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        ProcessResult pr = server.executeBrowser("/UnicodeLineBreak.html", AutoClose.CLOSE_ON_CORRECT_END);
+        assertTrue(pr.stdout.contains(AutoOkClosingListener.MAGICAL_OK_CLOSING_STRING));
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        String[] ss = s.split("\n");
+        for (String string : ss) {
+            Assert.assertFalse(string.contains("\\Qhttp://evil-site/evil.page/\\E \\Qhttp://evil-site/\\E malware.jar"));
+        }
+    }
+    
+    //javaws -html is imune to this trick when tagsoup is used
+    
+    @Test
+    @NeedsDisplay
+    public void unicodeLineBreakTestJavaWsHtmlTagsupProbablyOn() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+        //tagsoup remove the new line. So here we must really test the startWith, which may be fragile
+        ProcessWrapper pw =  new ProcessWrapper(server.getJavawsLocation(), Arrays.asList(new String[]{OptionsDefinitions.OPTIONS.HEADLESS.option,OptionsDefinitions.OPTIONS.HTML.option}), server.getUrl("/UnicodeLineBreak.html"), new AutoOkClosingListener(), null, null);
+        pw.setWriter("YES\n");
+        ProcessResult pr = pw.execute();
+        assertTrue(pr.stdout.contains(AutoOkClosingListener.MAGICAL_OK_CLOSING_STRING));
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        String[] ss = s.split("\n");
+        for (String string : ss) {
+            Assert.assertFalse(string.startsWith("A 1432197956873 \\Qhttp://evil-site/evil.page/\\E \\Qhttp://evil-site/\\E malware.jar"));
+        }
+    }
+    
+    @Test
+    @NeedsDisplay
+    public void unicodeLineBreakTestJavaWsHtmlTagsupForcedOff() throws Exception {
+        PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile().delete(); //clean file to examine later
+         ProcessWrapper pw =  new ProcessWrapper(server.getJavawsLocation(), Arrays.asList(new String[]{OptionsDefinitions.OPTIONS.XML.option, OptionsDefinitions.OPTIONS.HEADLESS.option, OptionsDefinitions.OPTIONS.HTML.option}), server.getUrl("/UnicodeLineBreak.html"), new AutoOkClosingListener(), null, null);
+        pw.setWriter("YES\n");
+        ProcessResult pr = pw.execute();
+        assertTrue(pr.stdout.contains(AutoOkClosingListener.MAGICAL_OK_CLOSING_STRING));
+        String s = FileUtils.loadFileAsString(PathsAndFiles.APPLET_TRUST_SETTINGS_USER.getFile());
+        String[] ss = s.split("\n");
+        for (String string : ss) {
+            Assert.assertFalse(string.contains("\\Qhttp://evil-site/evil.page/\\E \\Qhttp://evil-site/\\E malware.jar"));
+        }
+    }
+}