From 3527c6a71b7247edc8ba92352b706679d958efd7 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 19 Jun 2015 16:48:53 +1000 Subject: [PATCH] StringUtil.csvSplit(String) Conflicts: jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java --- .../annotations/AnnotationConfiguration.java | 3 +- .../client/util/DigestAuthentication.java | 3 +- .../org/eclipse/jetty/http/HttpGenerator.java | 2 +- .../jetty/maven/plugin/AbstractJettyMojo.java | 3 +- .../maven/plugin/JettyWebAppContext.java | 3 +- .../jetty/maven/plugin/OverlayConfig.java | 3 +- .../eclipse/jetty/maven/plugin/Starter.java | 13 +- .../jetty/maven/plugin/WarPluginInfo.java | 5 +- .../org/eclipse/jetty/rhttp/gateway/Main.java | 2 +- .../jetty/security/PropertyUserStore.java | 3 +- .../org/eclipse/jetty/server/Response.java | 5 +- .../jetty/servlets/CrossOriginFilter.java | 11 +- .../org/eclipse/jetty/servlets/DoSFilter.java | 3 +- .../org/eclipse/jetty/servlets/PutFilter.java | 3 +- .../eclipse/jetty/servlets/PutFilterTest.java | 5 +- .../org/eclipse/jetty/util/StringUtil.java | 183 +++++++++++++++++- .../eclipse/jetty/util/StringUtilTest.java | 33 ++++ .../jetty/util/ssl/SslContextFactoryTest.java | 6 + .../server/browser/JsrBrowserSocket.java | 4 +- 19 files changed, 262 insertions(+), 31 deletions(-) diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 4f1daa63327..2626112a21f 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -46,6 +46,7 @@ import org.eclipse.jetty.annotations.AnnotationParser.Handler; import org.eclipse.jetty.plus.annotation.ContainerInitializer; import org.eclipse.jetty.util.ConcurrentHashSet; import org.eclipse.jetty.util.MultiException; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; @@ -274,7 +275,7 @@ public class AnnotationConfiguration extends AbstractConfiguration { _ordering = ordering; - String[] tmp = ordering.split(","); + String[] tmp = StringUtil.csvSplit(ordering); for (int i=0; i serverQOPValues = Arrays.asList(serverQOP.split(",")); + List serverQOPValues = StringUtil.csvSplit(null,serverQOP,0,serverQOP.length()); if (serverQOPValues.contains("auth")) clientQOP = "auth"; else if (serverQOPValues.contains("auth-int")) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index 520822637ba..4034eec24eb 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -633,7 +633,7 @@ public class HttpGenerator if (values[0]==null) { - split = field.getValue().split("\\s*,\\s*"); + split = StringUtil.csvSplit(field.getValue()); if (split.length>0) { values=new HttpHeaderValue[split.length]; diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java index 3e373a15d45..203196263c8 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java @@ -47,6 +47,7 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; @@ -804,7 +805,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo } else { - String[] files = this.jettyXml.split(","); + String[] files = StringUtil.csvSplit(this.jettyXml); for ( String file : files ) { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java index 0d56f0559d6..b5d1dee4c0c 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java @@ -39,6 +39,7 @@ import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -252,7 +253,7 @@ public class JettyWebAppContext extends WebAppContext List resources = new ArrayList(); for (String rl:resourceBases) { - String[] rs = rl.split(" *, *"); + String[] rs = StringUtil.csvSplit(rl); for (String r:rs) resources.add(r); } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java index 287ba131cd7..5f638c61cf7 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.eclipse.jetty.util.StringUtil; /** * OverlayConfig @@ -48,7 +49,7 @@ public class OverlayConfig { if (fmt == null) return; - String[] atoms = fmt.split(","); + String[] atoms = StringUtil.csvSplit(fmt); for (int i=0;i= 3) { gid = atoms[0].trim(); @@ -226,7 +227,7 @@ public class Starter str = (String)props.getProperty("base.dirs"); if (str != null && !"".equals(str.trim())) { - ResourceCollection bases = new ResourceCollection(str.split(",")); + ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str)); webApp.setWar(null); webApp.setBaseResource(bases); } @@ -235,7 +236,7 @@ public class Starter str = (String)props.get("base.dirs.orig"); if (str != null && !"".equals(str.trim())) { - ResourceCollection bases = new ResourceCollection(str.split(",")); + ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str)); webApp.setAttribute ("org.eclipse.jetty.resources.originalBases", bases); } @@ -331,7 +332,7 @@ public class Starter if (str != null && !"".equals(str.trim())) { List jars = new ArrayList(); - String[] names = str.split(","); + String[] names = StringUtil.csvSplit(str); for (int j=0; names != null && j < names.length; j++) jars.add(new File(names[j].trim())); webApp.setWebInfLib(jars); @@ -360,7 +361,7 @@ public class Starter if ("--jetty-xml".equals(args[i])) { jettyXmls = new ArrayList(); - String[] names = args[++i].split(","); + String[] names = StringUtil.csvSplit(args[++i]); for (int j=0; names!= null && j < names.length; j++) { jettyXmls.add(new File(names[j].trim())); @@ -489,7 +490,7 @@ public class Starter { if (csv == null || "".equals(csv.trim())) return null; - String[] atoms = csv.split(","); + String[] atoms = StringUtil.csvSplit(csv); List list = new ArrayList(); for (String a:atoms) { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java index f939a220ccb..e8ae0e0672a 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java @@ -28,6 +28,7 @@ import java.util.List; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.eclipse.jetty.util.StringUtil; @@ -105,7 +106,7 @@ public class WarPluginInfo if (node == null) return null; String val = node.getValue(); - _dependentMavenWarIncludes = Arrays.asList(val.split(",")); + _dependentMavenWarIncludes = StringUtil.csvSplit(null,val,0,val.length()); } return _dependentMavenWarIncludes; } @@ -134,7 +135,7 @@ public class WarPluginInfo if (node == null) return null; String val = node.getValue(); - _dependentMavenWarExcludes = Arrays.asList(val.split(",")); + _dependentMavenWarExcludes = StringUtil.csvSplit(null,val,0,val.length()); } return _dependentMavenWarExcludes; } diff --git a/jetty-rhttp/jetty-rhttp-gateway/src/main/java/org/eclipse/jetty/rhttp/gateway/Main.java b/jetty-rhttp/jetty-rhttp-gateway/src/main/java/org/eclipse/jetty/rhttp/gateway/Main.java index cddc8b63dea..b21ce11f55b 100644 --- a/jetty-rhttp/jetty-rhttp-gateway/src/main/java/org/eclipse/jetty/rhttp/gateway/Main.java +++ b/jetty-rhttp/jetty-rhttp-gateway/src/main/java/org/eclipse/jetty/rhttp/gateway/Main.java @@ -113,7 +113,7 @@ public class Main String argValue = matcher.group(2); if (argValue.startsWith("host,")) { - String[] typeAndSuffix = argValue.split(","); + String[] typeAndSuffix = StringUtil.split(argValue); if (typeAndSuffix.length != 2) throw new IllegalArgumentException("Invalid option " + arg + ", must be of the form --" + RETRIEVER_ARG + "=host,suffix"); diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index b4937d3a669..9e7ec5261f5 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -38,6 +38,7 @@ import org.eclipse.jetty.security.MappedLoginService.RolePrincipal; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.Scanner.BulkListener; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -153,7 +154,7 @@ public class PropertyUserStore extends AbstractLifeCycle String[] roleArray = IdentityService.NO_ROLES; if (roles != null && roles.length() > 0) { - roleArray = roles.split(","); + roleArray = StringUtil.csvSplit(roles); } known.add(username); Credential credential = Credential.getCredential(credentials); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 93cc88b181d..cc1e8dcb130 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -1187,10 +1187,9 @@ public class Response implements HttpServletResponse String connection = _channel.getRequest().getHttpFields().getStringField(HttpHeader.CONNECTION); if (connection != null) { - String[] values = connection.split(","); - for (int i = 0; values != null && i < values.length; i++) + for (String value: StringUtil.csvSplit(null,connection,0,connection.length())) { - HttpHeaderValue cb = HttpHeaderValue.CACHE.get(values[0].trim()); + HttpHeaderValue cb = HttpHeaderValue.CACHE.get(value); if (cb != null) { diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java index e1ba9b988cb..a8d668e9afa 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java @@ -35,6 +35,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -136,7 +137,7 @@ public class CrossOriginFilter implements Filter String allowedOriginsConfig = config.getInitParameter(ALLOWED_ORIGINS_PARAM); if (allowedOriginsConfig == null) allowedOriginsConfig = "*"; - String[] allowedOrigins = allowedOriginsConfig.split(","); + String[] allowedOrigins = StringUtil.csvSplit(allowedOriginsConfig); for (String allowedOrigin : allowedOrigins) { allowedOrigin = allowedOrigin.trim(); @@ -159,7 +160,7 @@ public class CrossOriginFilter implements Filter if (allowedMethodsConfig == null) allowedMethods.addAll(DEFAULT_ALLOWED_METHODS); else - allowedMethods.addAll(Arrays.asList(allowedMethodsConfig.split(","))); + allowedMethods.addAll(Arrays.asList(StringUtil.csvSplit(allowedMethodsConfig))); String allowedHeadersConfig = config.getInitParameter(ALLOWED_HEADERS_PARAM); if (allowedHeadersConfig == null) @@ -167,7 +168,7 @@ public class CrossOriginFilter implements Filter else if ("*".equals(allowedHeadersConfig)) anyHeadersAllowed = true; else - allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig.split(","))); + allowedHeaders.addAll(Arrays.asList(StringUtil.csvSplit(allowedHeadersConfig))); String preflightMaxAgeConfig = config.getInitParameter(PREFLIGHT_MAX_AGE_PARAM); if (preflightMaxAgeConfig == null) @@ -189,7 +190,7 @@ public class CrossOriginFilter implements Filter String exposedHeadersConfig = config.getInitParameter(EXPOSED_HEADERS_PARAM); if (exposedHeadersConfig == null) exposedHeadersConfig = ""; - exposedHeaders.addAll(Arrays.asList(exposedHeadersConfig.split(","))); + exposedHeaders.addAll(Arrays.asList(StringUtil.csvSplit(exposedHeadersConfig))); String chainPreflightConfig = config.getInitParameter(OLD_CHAIN_PREFLIGHT_PARAM); if (chainPreflightConfig != null) @@ -400,7 +401,7 @@ public class CrossOriginFilter implements Filter return Collections.emptyList(); List requestedHeaders = new ArrayList(); - String[] headers = accessControlRequestHeaders.split(","); + String[] headers = StringUtil.csvSplit(accessControlRequestHeaders); for (String header : headers) { String h = header.trim(); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index f1e331591af..1e23bfe34f0 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -52,6 +52,7 @@ import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; @@ -1036,7 +1037,7 @@ public class DoSFilter implements Filter public void setWhitelist(String commaSeparatedList) { List result = new ArrayList<>(); - for (String address : commaSeparatedList.split(",")) + for (String address : StringUtil.csvSplit(commaSeparatedList)) addWhitelistAddress(result, address); clearWhitelist(); _whitelist.addAll(result); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java index b31ab318409..24a1b75eded 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java @@ -44,6 +44,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; /** @@ -331,7 +332,7 @@ public class PutFilter implements Filter if ("Allow".equalsIgnoreCase(name)) { Set options = new HashSet(); - options.addAll(Arrays.asList(value.split(" *, *"))); + options.addAll(Arrays.asList(StringUtil.csvSplit(value))); options.addAll(_operations); value=null; for (String o : options) diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java index dbce3610808..d656eaf3bb2 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java @@ -41,6 +41,7 @@ import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletTester; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -266,8 +267,8 @@ public class PutFilterTest assertEquals(HttpServletResponse.SC_OK,response.getStatus()); Set options = new HashSet(); - options.addAll(Arrays.asList(response.get("Allow").split(" *, *"))); - + String allow=response.get("Allow"); + options.addAll(StringUtil.csvSplit(null,allow,0,allow.length())); assertTrue(options.contains("GET")); assertTrue(options.contains("POST")); assertTrue(options.contains("PUT")); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java index e82b8c93870..9c3315f7cc6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java @@ -21,6 +21,8 @@ package org.eclipse.jetty.util; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -721,6 +723,11 @@ public class StringUtil return str.substring(0,maxSize); } + /** + * Parse the string representation of a list using {@link #csvSplit(List,String,int,int)} + * @param s The string to parse, expected to be enclosed as '[...]' + * @return An array of parsed values. + */ public static String[] arrayFromString(String s) { if (s==null) @@ -731,9 +738,183 @@ public class StringUtil if (s.length()==2) return new String[]{}; - return s.substring(1,s.length()-1).split(" *, *"); + return csvSplit(s,1,s.length()-2); } + /** + * Parse a CSV string using {@link #csvSplit(List,String, int, int)} + * @param s The string to parse + * @return An array of parsed values. + */ + public static String[] csvSplit(String s) + { + if (s==null) + return null; + return csvSplit(s,0,s.length()); + } + + /** + * Parse a CSV string using {@link #csvSplit(List,String, int, int)} + * @param s The string to parse + * @param off The offset into the string to start parsing + * @param len The len in characters to parse + * @return An array of parsed values. + */ + public static String[] csvSplit(String s, int off,int len) + { + if (s==null) + return null; + if (off<0 || len<0 || off>s.length()) + throw new IllegalArgumentException(); + + List list = new ArrayList<>(); + csvSplit(list,s,off,len); + return list.toArray(new String[list.size()]); + } + + enum CsvSplitState { PRE_DATA, QUOTE, SLOSH, DATA, WHITE, POST_DATA }; + + /** Split a quoted comma separated string to a list + *

Handle rfc4180-like + * CSV strings, with the exceptions:

    + *
  • quoted values may contain double quotes escaped with back-slash + *
  • Non-quoted values are trimmed of leading trailing white space + *
  • trailing commas are ignored + *
  • double commas result in a empty string value + *
+ * @param list The Collection to split to (or null to get a new list) + * @param s The string to parse + * @param off The offset into the string to start parsing + * @param len The len in characters to parse + * @return list containing the parsed list values + */ + public static List csvSplit(List list,String s, int off,int len) + { + if (list==null) + list=new ArrayList<>(); + CsvSplitState state = CsvSplitState.PRE_DATA; + StringBuilder out = new StringBuilder(); + int last=-1; + while (len>0) + { + char ch = s.charAt(off++); + len--; + + switch(state) + { + case PRE_DATA: + if (Character.isWhitespace(ch)) + continue; + + if ('"'==ch) + { + state=CsvSplitState.QUOTE; + continue; + } + + if (','==ch) + { + list.add(""); + continue; + } + + state=CsvSplitState.DATA; + out.append(ch); + continue; + + case DATA: + if (Character.isWhitespace(ch)) + { + last=out.length(); + out.append(ch); + state=CsvSplitState.WHITE; + continue; + } + + if (','==ch) + { + list.add(out.toString()); + out.setLength(0); + state=CsvSplitState.PRE_DATA; + continue; + } + + out.append(ch); + continue; + + case WHITE: + if (Character.isWhitespace(ch)) + { + out.append(ch); + continue; + } + + if (','==ch) + { + out.setLength(last); + list.add(out.toString()); + out.setLength(0); + state=CsvSplitState.PRE_DATA; + continue; + } + + state=CsvSplitState.DATA; + out.append(ch); + last=-1; + continue; + + case QUOTE: + if ('\\'==ch) + { + state=CsvSplitState.SLOSH; + continue; + } + if ('"'==ch) + { + list.add(out.toString()); + out.setLength(0); + state=CsvSplitState.POST_DATA; + continue; + } + out.append(ch); + continue; + + case SLOSH: + out.append(ch); + state=CsvSplitState.QUOTE; + continue; + + case POST_DATA: + if (','==ch) + { + state=CsvSplitState.PRE_DATA; + continue; + } + continue; + } + } + + switch(state) + { + case PRE_DATA: + case POST_DATA: + break; + + case DATA: + case QUOTE: + case SLOSH: + list.add(out.toString()); + break; + + case WHITE: + out.setLength(last); + list.add(out.toString()); + break; + } + + return list; + } + public static String sanitizeXmlString(String html) { if (html==null) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java index 8c4b05f8ee7..394d1f3fe76 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java @@ -18,12 +18,17 @@ package org.eclipse.jetty.util; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.nio.charset.StandardCharsets; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -241,4 +246,32 @@ public class StringUtilTest assertEquals("Hello <Cruel> World",StringUtil.sanitizeXmlString("Hello World")); assertEquals("Hello ? World",StringUtil.sanitizeXmlString("Hello \u0000 World")); } + + @Test + public void testSplit() + { + assertThat(StringUtil.csvSplit(null),nullValue()); + assertThat(StringUtil.csvSplit(null),nullValue()); + + assertThat(StringUtil.csvSplit(""),emptyArray()); + assertThat(StringUtil.csvSplit(" \t\n"),emptyArray()); + + assertThat(StringUtil.csvSplit("aaa"),arrayContaining("aaa")); + assertThat(StringUtil.csvSplit(" \taaa\n"),arrayContaining("aaa")); + assertThat(StringUtil.csvSplit(" \ta\n"),arrayContaining("a")); + assertThat(StringUtil.csvSplit(" \t\u1234\n"),arrayContaining("\u1234")); + + assertThat(StringUtil.csvSplit("aaa,bbb,ccc"),arrayContaining("aaa","bbb","ccc")); + assertThat(StringUtil.csvSplit("aaa,,ccc"),arrayContaining("aaa","","ccc")); + assertThat(StringUtil.csvSplit(",b b,"),arrayContaining("","b b")); + assertThat(StringUtil.csvSplit(",,bbb,,"),arrayContaining("","","bbb","")); + + assertThat(StringUtil.csvSplit(" aaa, bbb, ccc"),arrayContaining("aaa","bbb","ccc")); + assertThat(StringUtil.csvSplit("aaa,\t,ccc"),arrayContaining("aaa","","ccc")); + assertThat(StringUtil.csvSplit(" , b b , "),arrayContaining("","b b")); + assertThat(StringUtil.csvSplit(" ,\n,bbb, , "),arrayContaining("","","bbb","")); + + assertThat(StringUtil.csvSplit("\"aaa\", \" b,\\\"\",\"\""),arrayContaining("aaa"," b,\"","")); + } + } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java index a59a4b33cdd..e14fa54f9a4 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java @@ -31,11 +31,14 @@ import java.security.KeyStore; import javax.net.ssl.SSLEngine; +import org.eclipse.jetty.toolchain.test.JDK; +import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.resource.Resource; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -208,6 +211,9 @@ public class SslContextFactoryTest @Test public void testSetIncludeCipherSuitesRegex() throws Exception { + // Test does not work on JDK 8+ (RC4 is disabled) + Assume.assumeFalse(JDK.IS_8); + cf.setIncludeCipherSuites(".*RC4.*"); cf.start(); SSLEngine sslEngine = cf.newSSLEngine(); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserSocket.java index ace05d8205c..8540689a72e 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserSocket.java @@ -132,7 +132,7 @@ public class JsrBrowserSocket } case "many": { - String parts[] = val.split(","); + String parts[] = StringUtil.csvSplit(val); int size = Integer.parseInt(parts[0]); int count = Integer.parseInt(parts[1]); @@ -141,7 +141,7 @@ public class JsrBrowserSocket } case "manythreads": { - String parts[] = val.split(","); + String parts[] = StringUtil.csvSplit(val); int threadCount = Integer.parseInt(parts[0]); int size = Integer.parseInt(parts[1]); int count = Integer.parseInt(parts[2]);