ASF Bugzilla – Attachment 32382 Details for
Bug 57420
Wrong class names generated since URL_ENCODER in DirContextURLConnection is not thread safe
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Make UEncoder a local variable and introduce a default safe charset enum
0001-Add-UEncoder-a-constructor-for-its-safeChars.-Use-a-.patch (text/plain), 8.83 KB, created by
Felix Schumacher
on 2015-01-20 21:00:14 UTC
(
hide
)
Description:
Make UEncoder a local variable and introduce a default safe charset enum
Filename:
MIME Type:
Creator:
Felix Schumacher
Created:
2015-01-20 21:00:14 UTC
Size:
8.83 KB
patch
obsolete
>From 45739bd26b1fa2b6e005eb6d09f92207a5a13be8 Mon Sep 17 00:00:00 2001 >From: Felix Schumacher <felix.schumacher@internetallee.de> >Date: Tue, 20 Jan 2015 21:17:41 +0100 >Subject: [PATCH] Add UEncoder a constructor for its safeChars. Use a method > variable for the UEncoder in DirContextURLConnection, as UEncoder is not > thread safe. Use a immutable safeChars field for Response instances. > >--- > java/org/apache/catalina/connector/Response.java | 4 +- > .../naming/resources/DirContextURLConnection.java | 9 +- > java/org/apache/tomcat/util/buf/UEncoder.java | 104 ++++++++++++++------- > test/org/apache/tomcat/util/buf/TestUEncoder.java | 26 ++++++ > 4 files changed, 102 insertions(+), 41 deletions(-) > >diff --git a/java/org/apache/catalina/connector/Response.java b/java/org/apache/catalina/connector/Response.java >index 65998bc..ad22618 100644 >--- a/java/org/apache/catalina/connector/Response.java >+++ b/java/org/apache/catalina/connector/Response.java >@@ -51,6 +51,7 @@ import org.apache.catalina.util.RequestUtil; > import org.apache.catalina.util.SessionConfig; > import org.apache.tomcat.util.buf.CharChunk; > import org.apache.tomcat.util.buf.UEncoder; >+import org.apache.tomcat.util.buf.UEncoder.SafeCharsSet; > import org.apache.tomcat.util.http.FastHttpDateFormat; > import org.apache.tomcat.util.http.MimeHeaders; > import org.apache.tomcat.util.http.ServerCookie; >@@ -91,7 +92,6 @@ public class Response > } > > public Response() { >- urlEncoder.addSafeCharacter('/'); > } > > >@@ -282,7 +282,7 @@ public class Response > /** > * URL encoder. > */ >- protected UEncoder urlEncoder = new UEncoder(); >+ protected UEncoder urlEncoder = new UEncoder(SafeCharsSet.WITH_SLASH); > > > /** >diff --git a/java/org/apache/naming/resources/DirContextURLConnection.java b/java/org/apache/naming/resources/DirContextURLConnection.java >index 8133c3d..57cccb6 100644 >--- a/java/org/apache/naming/resources/DirContextURLConnection.java >+++ b/java/org/apache/naming/resources/DirContextURLConnection.java >@@ -42,6 +42,7 @@ import javax.naming.directory.DirContext; > import org.apache.naming.JndiPermission; > import org.apache.tomcat.util.buf.UDecoder; > import org.apache.tomcat.util.buf.UEncoder; >+import org.apache.tomcat.util.buf.UEncoder.SafeCharsSet; > import org.apache.tomcat.util.http.FastHttpDateFormat; > > /** >@@ -57,11 +58,6 @@ import org.apache.tomcat.util.http.FastHttpDateFormat; > public class DirContextURLConnection extends URLConnection { > > private static final UDecoder URL_DECODER = new UDecoder(); >- private static final UEncoder URL_ENCODER = new UEncoder(); >- >- static{ >- URL_ENCODER.addSafeCharacter('/'); >- } > > // ----------------------------------------------------------- Constructors > >@@ -436,11 +432,12 @@ public class DirContextURLConnection extends URLConnection { > try { > NamingEnumeration<NameClassPair> enumeration = > collection.list("/"); >+ UEncoder urlEncoder = new UEncoder(SafeCharsSet.WITH_SLASH); > while (enumeration.hasMoreElements()) { > NameClassPair ncp = enumeration.nextElement(); > String s = ncp.getName(); > result.addElement( >- URL_ENCODER.encodeURL(s, 0, s.length()).toString()); >+ urlEncoder.encodeURL(s, 0, s.length()).toString()); > } > } catch (NamingException e) { > // Unexpected exception >diff --git a/java/org/apache/tomcat/util/buf/UEncoder.java b/java/org/apache/tomcat/util/buf/UEncoder.java >index 8c700dd..2591a89 100644 >--- a/java/org/apache/tomcat/util/buf/UEncoder.java >+++ b/java/org/apache/tomcat/util/buf/UEncoder.java >@@ -31,6 +31,22 @@ import java.util.BitSet; > */ > public final class UEncoder { > >+ public enum SafeCharsSet { >+ WITH_SLASH("/"), DEFAULT(""); >+ private final BitSet safeChars; >+ >+ private BitSet getSafeChars() { >+ return this.safeChars; >+ } >+ >+ private SafeCharsSet(String additionalSafeChars) { >+ safeChars = initialSafeChars(); >+ for (char c : additionalSafeChars.toCharArray()) { >+ safeChars.set(c); >+ } >+ } >+ } >+ > // Not static - the set may differ ( it's better than adding > // an extra check for "/", "+", etc > private BitSet safeChars=null; >@@ -38,11 +54,28 @@ public final class UEncoder { > private ByteChunk bb=null; > private CharChunk cb=null; > private CharChunk output=null; >+ private final boolean readOnlySafeChars; > > private String encoding="UTF8"; > > public UEncoder() { >- initSafeChars(); >+ this.safeChars = initialSafeChars(); >+ readOnlySafeChars = false; >+ } >+ >+ /** >+ * Create a UEncoder with an unmodifiable safe character set. >+ * <p> >+ * Calls to {@link UEncoder#addSafeCharacter(char) addSafeCharacter(char)} >+ * on instances created by this constructor will throw an >+ * {@link IllegalStateException}. >+ * >+ * @param safeCharsSet >+ * safe characters for this encoder >+ */ >+ public UEncoder(SafeCharsSet safeCharsSet) { >+ this.safeChars = safeCharsSet.getSafeChars(); >+ readOnlySafeChars = true; > } > > /** >@@ -54,6 +87,9 @@ public final class UEncoder { > } > > public void addSafeCharacter( char c ) { >+ if (readOnlySafeChars) { >+ throw new IllegalStateException("UEncoders safeChararacters are read only"); >+ } > safeChars.set( c ); > } > >@@ -120,36 +156,38 @@ public final class UEncoder { > out.append(ch); > } > } >- >- // -------------------- Internal implementation -------------------- >- >- private void initSafeChars() { >- safeChars=new BitSet(128); >- int i; >- for (i = 'a'; i <= 'z'; i++) { >- safeChars.set(i); >- } >- for (i = 'A'; i <= 'Z'; i++) { >- safeChars.set(i); >- } >- for (i = '0'; i <= '9'; i++) { >- safeChars.set(i); >- } >- //safe >- safeChars.set('$'); >- safeChars.set('-'); >- safeChars.set('_'); >- safeChars.set('.'); >- >- // Dangerous: someone may treat this as " " >- // RFC1738 does allow it, it's not reserved >- // safeChars.set('+'); >- //extra >- safeChars.set('!'); >- safeChars.set('*'); >- safeChars.set('\''); >- safeChars.set('('); >- safeChars.set(')'); >- safeChars.set(','); >- } >+ >+ // -------------------- Internal implementation -------------------- >+ >+ private static BitSet initialSafeChars() { >+ BitSet initialSafeChars = new BitSet(128); >+ int i; >+ for (i = 'a'; i <= 'z'; i++) { >+ initialSafeChars.set(i); >+ } >+ for (i = 'A'; i <= 'Z'; i++) { >+ initialSafeChars.set(i); >+ } >+ for (i = '0'; i <= '9'; i++) { >+ initialSafeChars.set(i); >+ } >+ // safe >+ initialSafeChars.set('$'); >+ initialSafeChars.set('-'); >+ initialSafeChars.set('_'); >+ initialSafeChars.set('.'); >+ >+ // Dangerous: someone may treat this as " " >+ // RFC1738 does allow it, it's not reserved >+ // safeChars.set('+'); >+ // extra >+ initialSafeChars.set('!'); >+ initialSafeChars.set('*'); >+ initialSafeChars.set('\''); >+ initialSafeChars.set('('); >+ initialSafeChars.set(')'); >+ initialSafeChars.set(','); >+ return initialSafeChars; >+ } >+ > } >diff --git a/test/org/apache/tomcat/util/buf/TestUEncoder.java b/test/org/apache/tomcat/util/buf/TestUEncoder.java >index d77a7fc..7287294 100644 >--- a/test/org/apache/tomcat/util/buf/TestUEncoder.java >+++ b/test/org/apache/tomcat/util/buf/TestUEncoder.java >@@ -20,6 +20,9 @@ package org.apache.tomcat.util.buf; > import java.io.IOException; > > import static org.junit.Assert.assertTrue; >+import static org.junit.Assert.fail; >+ >+import org.apache.tomcat.util.buf.UEncoder.SafeCharsSet; > import org.junit.Test; > > /** >@@ -45,4 +48,27 @@ public class TestUEncoder { > assertTrue(urlEncoder.encodeURL(s, 0, s.length()) > .equals("%f0%90%90%81")); > } >+ >+ @Test >+ public void testEncodeURLWithSlashInit() throws IOException { >+ UEncoder urlEncoder = new UEncoder(SafeCharsSet.WITH_SLASH); >+ >+ String s = "a+b/c/d+e.class"; >+ assertTrue(urlEncoder.encodeURL(s, 0, s.length()).equals( >+ "a%2bb/c/d%2be.class")); >+ assertTrue(urlEncoder.encodeURL(s, 2, s.length() - 2).equals( >+ "b/c/d%2be.cla")); >+ >+ try { >+ urlEncoder.addSafeCharacter('+'); >+ fail(); >+ } catch (IllegalStateException e) { >+ // OK >+ } >+ >+ s = new String(new char[] { 0xD801, 0xDC01 }); >+ assertTrue(urlEncoder.encodeURL(s, 0, s.length()) >+ .equals("%f0%90%90%81")); >+ } >+ > } >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 57420
:
32378
| 32382