changeset 1252:f3a35ac8f513

All UrlRegEx-es got unified and correct quoting
author Jiri Vanek <jvanek@redhat.com>
date Mon, 07 Sep 2015 20:11:55 +0200
parents f07fcd2a6a5e
children eca93c9195e1
files ChangeLog netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegExTest.java
diffstat 9 files changed, 310 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Sep 07 19:55:10 2015 +0200
+++ b/ChangeLog	Mon Sep 07 20:11:55 2015 +0200
@@ -1,3 +1,24 @@
+2015-09-02  Jiri Vanek  <jvanek@redhat.com>
+
+	All UrlRegEx-es got unified and correct quoting
+	* netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java:
+	(addRow) now uses factory methods of quoteAndStar form UrlRegEx
+	* netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java:
+	same, but of exact. Removed redundant space in APPEXTSECguiPanelTableInvalid key
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java:
+	same of exact.
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java:
+	same
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java:
+	same
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java:
+	same
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java:
+	constructor made private,  field final. Creation allowed over factory methods of
+	quote. quoteAndStar, exact. Added and iprved mehtods for visualisation
+	* tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegExTest.java:
+	new test file with tests to new methods in UrlRegex
+
 2015-09-02  Jiri Vanek  <jvanek@redhat.com>
 
 	Newline characters are banned from saving to .appletTrustSettings
--- a/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Mon Sep 07 20:11:55 2015 +0200
@@ -148,12 +148,12 @@
 
     public void addRow() {
         int i = getRowCount()-1;
-        String s = "\\Qhttp://localhost:80/\\E.*";
+        String s = "http://localhost:80/";
         back.add(new UnsignedAppletActionEntry(
                 AppletSecurityActions.createDefault(),
                 new Date(),
-                new UrlRegEx(s),
-                new UrlRegEx(s),
+                UrlRegEx.quoteAndStar(s),
+                UrlRegEx.quoteAndStar(s),
                 null));
         fireTableRowsInserted(i+1, i+1);
     }
--- a/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java	Mon Sep 07 20:11:55 2015 +0200
@@ -628,7 +628,7 @@
             JOptionPane.showMessageDialog(this, Translator.R("APPEXTSECguiPanelTableValid"));
         } catch (Exception ex) {
             OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ex);
-            JOptionPane.showMessageDialog(this, Translator.R("APPEXTSECguiPanelTableInvalid ", ex.toString()));
+            JOptionPane.showMessageDialog(this, Translator.R("APPEXTSECguiPanelTableInvalid", ex.toString()));
         } finally {
             f.delete();
         }
@@ -823,7 +823,7 @@
 
         private MyTextField(UrlRegEx urlRegEx) {
             if (urlRegEx == null) {
-                keeper = new UrlRegEx("");
+                keeper = UrlRegEx.exact("");
             } else {
                 this.keeper = urlRegEx;
             }
@@ -842,7 +842,7 @@
 
         private UrlRegexCellRenderer(UrlRegEx urlRegEx) {
             if (urlRegEx == null) {
-                keeper = new UrlRegEx("");
+                keeper =  UrlRegEx.exact("");
             } else {
                 this.keeper = urlRegEx;
             }
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Mon Sep 07 20:11:55 2015 +0200
@@ -61,11 +61,11 @@
         UnsignedAppletActionEntry nw = new UnsignedAppletActionEntry(
                 AppletSecurityActions.fromString(split[0]),
                 new Date(new Long(split[1])),
-                new UrlRegEx(split[2]),
+                UrlRegEx.exact(split[2]),
                 null,
                 null);
         if (split.length > 3) {
-            nw.setCodeBase(new UrlRegEx(split[3]));
+            nw.setCodeBase(UrlRegEx.exact(split[3]));
         }
         if (split.length > 4) {
             nw.setArchives(createArchivesList(s.substring(s.lastIndexOf(split[3]) + split[3].length()).trim()));
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Mon Sep 07 20:11:55 2015 +0200
@@ -139,12 +139,12 @@
             URL documentbase = UrlUtils.normalizeUrlAndStripParams(file.getSourceLocation(), true /* encode local files */);
 
             /* Else, create a new entry */
-            UrlRegEx codebaseRegex = new UrlRegEx("\\Q" + codebase + "\\E");
-            UrlRegEx documentbaseRegex = new UrlRegEx("\\Q" + stripFile(documentbase)+ "\\E.*"); // Match any from codebase and sourceFile "base"
+            UrlRegEx codebaseRegex = UrlRegEx.quote(codebase.toExternalForm());
+            UrlRegEx documentbaseRegex = UrlRegEx.quoteAndStar(stripFile(documentbase)); // Match any from codebase and sourceFile "base"
             List<String> archiveMatches = null; // Match any from codebase
 
             if (!rememberForCodeBase) { 
-                documentbaseRegex = new UrlRegEx("\\Q" + documentbase + "\\E"); // Match only this applet
+                documentbaseRegex = UrlRegEx.quote(documentbase.toExternalForm()); // Match only this applet
                 archiveMatches = toRelativePaths(getJars(file), file.getCodeBase().toString()); // Match only this applet
             }
             
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java	Mon Sep 07 20:11:55 2015 +0200
@@ -35,11 +35,29 @@
  */
 package net.sourceforge.jnlp.security.appletextendedsecurity;
 
+import java.util.regex.Pattern;
+
 public class UrlRegEx {
 
-    String regEx;
+    private static String quoteString(String s) {
+        return Pattern.quote(s);
+    }
+
+    private final String regEx;
 
-    public UrlRegEx(String s) {
+    public static UrlRegEx quote(String s) {
+        return new UrlRegEx(quoteString(s));
+    }
+    
+    public static UrlRegEx quoteAndStar(String s) {
+        return new UrlRegEx(quoteString(s)+".*");
+    }
+    
+    public static UrlRegEx exact(String s) {
+        return new UrlRegEx(s);
+    }
+    
+    private UrlRegEx(String s) {
         regEx = s;
     }
 
@@ -52,11 +70,60 @@
         return regEx;
     }
 
+    /**
+     * Just cosmetic method to show nicer tables, as \Qsomething\Emaybe is most
+     * common record when cell is edited, the regex is shown fully
+     *
+     * @return unquted pattern or original string
+     */
     public String getFilteredRegEx() {
-        return regEx.replaceAll("\\\\Q", "").replaceAll("\\\\E", "");
+        try {
+            return simpleUnquote(regEx);
+        } catch (Exception ex) {
+            return regEx;
+        }
     }
 
-    public void setRegEx(String regEx) {
-        this.regEx = regEx;
+    //needs testing
+    static String replaceLast(String where, String what, String by) {
+        if (!where.contains(what)) {
+            return where;
+        }
+        StringBuilder b = new StringBuilder(where);
+        b.replace(where.lastIndexOf(what), where.lastIndexOf(what)+what.length(), by);
+        return b.toString();
+    }
+    
+     //needs testing
+    static String simpleUnquote(String s) {
+        //escaped run needs at least \E\Q, but only single char actually hurts
+        if (s.length()<=1){
+            return s;
+        }
+        boolean in = false;
+        for(int i = 1 ; i < s.length() ; i++){
+            if ( i == 0) {
+                continue;
+            }
+            if (!in && s.charAt(i) == 'Q' && s.charAt(i-1) ==  '\\'){
+                in = true;
+                String s1=s.substring(0, i - 1);
+                String s2=s.substring(i + 1);
+                s= s1+s2;
+                i = i - 2;
+                continue;
+            }
+            if (in && s.charAt(i) == 'E' && s.charAt(i-1) ==  '\\'){
+                String s1=s.substring(0, i - 1);
+                String s2=s.substring(i + 1);
+                s= s1+s2;
+                i = i - 2;
+                in = false;
+                continue;
+            }
+        }
+        //all text\Etext were replaced  \Qtext\E\\E\Qtext\E
+        //after above text\\Etext  should remain
+        return s.replace("\\\\E", "\\E");
     }
 }
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java	Mon Sep 07 20:11:55 2015 +0200
@@ -170,10 +170,10 @@
                         source.setTimeStamp((Date) aValue);
                     }
                     if (columnIndex == 3) {
-                        source.setDocumentBase(new UrlRegEx((String) aValue));
+                        source.setDocumentBase(UrlRegEx.exact((String) aValue));
                     }
                     if (columnIndex == 4) {
-                        source.setCodeBase(new UrlRegEx((String) aValue));
+                        source.setCodeBase(UrlRegEx.exact((String) aValue));
                     }
                     if (columnIndex == 5) {
                         source.setArchives(UnsignedAppletActionEntry.createArchivesList((String) aValue));
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Mon Sep 07 19:55:10 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Mon Sep 07 20:11:55 2015 +0200
@@ -41,6 +41,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.PatternSyntaxException;
 import net.sourceforge.jnlp.security.appletextendedsecurity.InvalidLineException;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
@@ -182,21 +183,26 @@
     }
 
     private boolean isMatching(UnsignedAppletActionEntry unsignedAppletActionEntry, String documentBase, String codeBase, List<String> archives) {
-        boolean result = true;
-        if (documentBase != null && !documentBase.trim().isEmpty()) {
-            result = result && documentBase.matches(unsignedAppletActionEntry.getDocumentBase().getRegEx());
-        }
-        if (codeBase != null && !codeBase.trim().isEmpty()) {
-            result = result && codeBase.matches(unsignedAppletActionEntry.getCodeBase().getRegEx());
+        try {
+            boolean result = true;
+            if (documentBase != null && !documentBase.trim().isEmpty()) {
+                result = result && documentBase.matches(unsignedAppletActionEntry.getDocumentBase().getRegEx());
+            }
+            if (codeBase != null && !codeBase.trim().isEmpty()) {
+                result = result && codeBase.matches(unsignedAppletActionEntry.getCodeBase().getRegEx());
+            }
+            if (archives != null) {
+                List<String> saved = unsignedAppletActionEntry.getArchives();
+                if (saved == null || saved.isEmpty()) {
+                    return result;
+                }
+                result = result && compareArchives(archives, saved);
+            }
+            return result;
+        } catch (PatternSyntaxException ex) {
+            OutputController.getLogger().log(OutputController.Level.WARNING_ALL, ex);
+            return false;
         }
-        if (archives != null) {
-            List<String> saved = unsignedAppletActionEntry.getArchives();
-            if (saved == null || saved.isEmpty()) {
-                return result;
-            }
-            result = result && compareArchives(archives, saved);
-        }
-        return result;
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegExTest.java	Mon Sep 07 20:11:55 2015 +0200
@@ -0,0 +1,184 @@
+/*   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;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UrlRegExTest {
+
+    @Test
+    public void testSimpleUnquote2() throws Exception {
+        Assert.assertEquals("aabbccddee", UrlRegEx.simpleUnquote("aa\\Qbb\\Ecc\\Qdd\\Eee"));
+        Assert.assertEquals("aabbccddee", UrlRegEx.simpleUnquote("aa\\Qbb\\Ecc\\Qdd\\Eee"));
+        Assert.assertEquals("a\\Ea\\Ee\\Ee", UrlRegEx.simpleUnquote("a\\Ea\\Q\\E\\E\\Q\\Ee\\Ee"));
+        Assert.assertEquals("http://url.cz/", UrlRegEx.simpleUnquote("\\Qhttp://url.cz/\\E"));
+        Assert.assertEquals("http://url.cz/.*", UrlRegEx.simpleUnquote("\\Qhttp://url.cz/\\E.*"));
+        Assert.assertEquals("http://ur\\El.cz/.*", UrlRegEx.simpleUnquote("\\Qhttp://ur\\E\\E\\Ql.cz/\\E.*"));
+    }
+    
+    @Test
+    public void testSimpleUnquote1() throws Exception {
+        Assert.assertEquals("\\Q", UrlRegEx.simpleUnquote("\\Q\\Q\\E"));
+        Assert.assertEquals("a\\Q", UrlRegEx.simpleUnquote("a\\Q\\Q\\E"));
+        Assert.assertEquals("\\Qb", UrlRegEx.simpleUnquote("\\Q\\Q\\Eb"));
+        Assert.assertEquals("a\\Qb", UrlRegEx.simpleUnquote("a\\Q\\Q\\Eb"));
+        Assert.assertEquals("abc", UrlRegEx.simpleUnquote("a\\Qb\\Ec"));
+        Assert.assertEquals("aabbcc", UrlRegEx.simpleUnquote("aa\\Qbb\\Ecc"));
+        Assert.assertEquals("aabb", UrlRegEx.simpleUnquote("aa\\Qbb\\E"));
+        Assert.assertEquals("bbcc", UrlRegEx.simpleUnquote("\\Qbb\\Ecc"));
+        Assert.assertEquals("aacc", UrlRegEx.simpleUnquote("aa\\Q\\Ecc"));
+        Assert.assertEquals("a", UrlRegEx.simpleUnquote("\\Qa\\E"));
+        Assert.assertEquals("ab", UrlRegEx.simpleUnquote("\\Qab\\E"));
+        Assert.assertEquals("", UrlRegEx.simpleUnquote("\\Q\\E"));
+        Assert.assertEquals("", UrlRegEx.simpleUnquote(""));
+        Assert.assertEquals("a", UrlRegEx.simpleUnquote("a"));
+        Assert.assertEquals("ab", UrlRegEx.simpleUnquote("ab"));
+        Assert.assertEquals("abc", UrlRegEx.simpleUnquote("abc"));
+        Assert.assertEquals("Q", UrlRegEx.simpleUnquote("Q"));
+        Assert.assertEquals("QE", UrlRegEx.simpleUnquote("QE"));
+        Assert.assertEquals("Q\\E", UrlRegEx.simpleUnquote("Q\\E"));
+        Assert.assertEquals("\\E", UrlRegEx.simpleUnquote("\\E"));
+        Assert.assertEquals("\\E\\E\\E", UrlRegEx.simpleUnquote("\\E\\E\\E"));
+    }
+
+    @Test
+    public void testReplaceAll1() throws Exception {
+        Assert.assertEquals("abcd", UrlRegEx.replaceLast("abcd", "X", "Y"));
+        Assert.assertEquals("abcD", UrlRegEx.replaceLast("abcd", "d", "D"));
+        Assert.assertEquals("abcDef", UrlRegEx.replaceLast("abcdef", "d", "D"));
+        Assert.assertEquals("abcdD", UrlRegEx.replaceLast("abcdd", "d", "D"));
+        Assert.assertEquals("Abcd", UrlRegEx.replaceLast("abcd", "a", "A"));
+        Assert.assertEquals("aAbcd", UrlRegEx.replaceLast("aabcd", "a", "A"));
+    }
+
+    @Test
+    public void testReplaceAll2() throws Exception {
+        Assert.assertEquals("abcd", UrlRegEx.replaceLast("abcd", "abcde", ""));
+        Assert.assertEquals("abc", UrlRegEx.replaceLast("abcd", "d", ""));
+        Assert.assertEquals("abcef", UrlRegEx.replaceLast("abcdef", "d", ""));
+        Assert.assertEquals("bcdef", UrlRegEx.replaceLast("abcdef", "a", ""));
+        Assert.assertEquals("abcdef", UrlRegEx.replaceLast("aabcdef", "a", ""));
+        Assert.assertEquals("ab", UrlRegEx.replaceLast("abcd", "cd", ""));
+        Assert.assertEquals("abf", UrlRegEx.replaceLast("abcdef", "cde", ""));
+        Assert.assertEquals("cdef", UrlRegEx.replaceLast("abcdef", "ab", ""));
+        Assert.assertEquals("acdef", UrlRegEx.replaceLast("aabcdef", "ab", ""));
+        Assert.assertEquals("", UrlRegEx.replaceLast("abc", "abc", ""));
+    }
+
+    @Test
+    public void testReplaceAll3() throws Exception {
+        Assert.assertEquals("abcd", UrlRegEx.replaceLast("abcd", "xyz", "ABCDE"));
+        Assert.assertEquals("abcDD", UrlRegEx.replaceLast("abcd", "d", "DD"));
+        Assert.assertEquals("abcDDDef", UrlRegEx.replaceLast("abcdef", "d", "DDD"));
+        Assert.assertEquals("AAbcdef", UrlRegEx.replaceLast("abcdef", "a", "AA"));
+        Assert.assertEquals("aAAAbcdef", UrlRegEx.replaceLast("aabcdef", "a", "AAA"));
+        Assert.assertEquals("abXCDY", UrlRegEx.replaceLast("abcd", "cd", "XCDY"));
+        Assert.assertEquals("abXCDEYZf", UrlRegEx.replaceLast("abcdef", "cde", "XCDEYZ"));
+        Assert.assertEquals("XABYcdef", UrlRegEx.replaceLast("abcdef", "ab", "XABY"));
+        Assert.assertEquals("aABCDcdef", UrlRegEx.replaceLast("aabcdef", "ab", "ABCD"));
+        Assert.assertEquals("ABC", UrlRegEx.replaceLast("abc", "abc", "ABC"));
+        Assert.assertEquals("ABCE", UrlRegEx.replaceLast("abc", "abc", "ABCE"));
+    }
+
+    @Test
+    public void testExact() throws Exception {
+        String s1 = "string";
+        String s2 = "reg.*ex";
+        String s3 = "reg\\Eex";
+        String s4 = "reg\\.\\*ex";
+        UrlRegEx a1 = UrlRegEx.exact(s1);
+        UrlRegEx a2 = UrlRegEx.exact(s2);
+        UrlRegEx a3 = UrlRegEx.exact(s3);
+        UrlRegEx a4 = UrlRegEx.exact(s4);
+        Assert.assertEquals(s1, a1.getRegEx());
+        Assert.assertEquals(s2, a2.getRegEx());
+        Assert.assertEquals(s3, a3.getRegEx());
+        Assert.assertEquals(s4, a4.getRegEx());
+        Assert.assertTrue("regXXXex".matches(a2.getRegEx()));
+        Assert.assertFalse("regXXXex".matches(a4.getRegEx()));
+
+        Assert.assertEquals(s1, a1.getFilteredRegEx());
+        Assert.assertEquals(s2, a2.getFilteredRegEx());
+        Assert.assertEquals(s3, a3.getFilteredRegEx());
+        Assert.assertEquals(s4, a4.getFilteredRegEx());
+    }
+
+    @Test
+    public void testQuote1() throws Exception {
+        String s1 = "string";
+        String s2 = "reg.*ex";
+        String s3 = "reg\\.\\*ex";
+        UrlRegEx a1 = UrlRegEx.quote(s1);
+        UrlRegEx a2 = UrlRegEx.quote(s2);
+        UrlRegEx a3 = UrlRegEx.quote(s3);
+        Assert.assertEquals("\\Q" + s1 + "\\E", a1.getRegEx());
+        Assert.assertEquals("\\Q" + s2 + "\\E", a2.getRegEx());
+        Assert.assertEquals("\\Q" + s3 + "\\E", a3.getRegEx());
+        Assert.assertTrue("string".matches(a1.getRegEx()));
+        Assert.assertFalse("regXXXex".matches(a2.getRegEx()));
+        Assert.assertTrue("reg.*ex".matches(a2.getRegEx()));
+        Assert.assertFalse("regXXXex".matches(a3.getRegEx()));
+        Assert.assertFalse("reg.*ex".matches(a3.getRegEx()));
+        Assert.assertTrue("reg\\.\\*ex".matches(a3.getRegEx()));
+        
+        Assert.assertEquals(s1, a1.getFilteredRegEx());
+        Assert.assertEquals(s2, a2.getFilteredRegEx());
+        Assert.assertEquals(s3, a3.getFilteredRegEx());
+
+    }
+
+    @Test
+    public void testQuote2() throws Exception {
+        String s1 = "stri\\Eng";
+        String s2 = "reg.*ex";
+        String s3 = "reg\\.\\*ex";
+        UrlRegEx a1 = UrlRegEx.quote(s1);
+        UrlRegEx a2 = UrlRegEx.quote(s2);
+        UrlRegEx a3 = UrlRegEx.quote(s3);
+        Assert.assertNotEquals("\\Qstri\\Eng\\E", a1.getRegEx());
+        Assert.assertEquals("\\Q" + s2 + "\\E", a2.getRegEx());
+        Assert.assertEquals("\\Q" + s3 + "\\E", a3.getRegEx());
+        Assert.assertFalse("regXXXex".matches(a2.getRegEx()));
+        Assert.assertTrue("reg.*ex".matches(a2.getRegEx()));
+        Assert.assertTrue("stri\\Eng".matches(a1.getRegEx()));
+        
+        Assert.assertEquals(s1, a1.getFilteredRegEx());
+        Assert.assertEquals(s2, a2.getFilteredRegEx());
+        Assert.assertEquals(s3, a3.getFilteredRegEx());
+
+    }
+}