diff --git a/build/build-resources/pom.xml b/build/build-resources/pom.xml index 999c9014593..6d40d5513de 100644 --- a/build/build-resources/pom.xml +++ b/build/build-resources/pom.xml @@ -15,7 +15,7 @@ UTF-8 3.1.0 - 3.1.0 + 3.1.2 true true true diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java index 7c28dab2935..8ec1830e69c 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java @@ -18,6 +18,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class CommandLineBuilder { @@ -38,37 +39,90 @@ public class CommandLineBuilder return "java"; } - /** - * Perform an optional quoting of the argument, being intelligent with spaces and quotes as needed. If a subString is set in quotes it won't the subString - * won't be escaped. - * - * @param arg the argument to quote - * @return the quoted and escaped argument - * @deprecated no replacement, quoting is done by {@link #toQuotedString()} now. - */ - @Deprecated - public static String quote(String arg) - { - return "'" + arg + "'"; - } - - private List args; + private final StringBuilder commandLine = new StringBuilder(); + private final List args = new ArrayList<>(); + private final String separator; public CommandLineBuilder() { - args = new ArrayList(); + this(false); } - public CommandLineBuilder(String bin) + public CommandLineBuilder(boolean multiline) { - this(); - args.add(bin); + separator = multiline ? (" \\" + System.lineSeparator() + " ") : " "; } /** - * Add a simple argument to the command line. - *

- * Will quote arguments that have a space in them. + * This method applies single quotes suitable for a POSIX compliant shell if + * necessary. + * + * @param input The string to quote if needed + * @return The quoted string or the original string if quotes are not necessary + */ + public static String shellQuoteIfNeeded(String input) + { + // Single quotes are used because double quotes + // are evaluated differently by some shells. + + if (input == null) + return null; + if (input.length() == 0) + return "''"; + + int i = 0; + boolean needsQuoting = false; + while (!needsQuoting && i < input.length()) + { + char c = input.charAt(i++); + + // needs quoting unless a limited set of known good characters + needsQuoting = !( + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '/' || + c == ':' || + c == '.' || + c == ',' || + c == '+' || + c == '-' || + c == '_' + ); + } + + if (!needsQuoting) + return input; + + StringBuilder builder = new StringBuilder(input.length() * 2); + builder.append("'"); + builder.append(input, 0, --i); + + while (i < input.length()) + { + char c = input.charAt(i++); + if (c == '\'') + { + // There is no escape for a literal single quote, so we must leave the quotes + // and then escape the single quote. We test for the start/end of the string, so + // we can be less ugly in those cases. + if (i == 1) + builder.insert(0, "\\").append("'"); + else if (i == input.length()) + builder.append("'\\"); + else + builder.append("'\\''"); + } + else + builder.append(c); + } + builder.append("'"); + + return builder.toString(); + } + + /** + * Add a simple argument to the command line, quoted if necessary. * * @param arg the simple argument to add */ @@ -76,49 +130,75 @@ public class CommandLineBuilder { if (arg != null) { + if (commandLine.length() > 0) + commandLine.append(separator); args.add(arg); + commandLine.append(shellQuoteIfNeeded(arg)); } } /** - * Similar to {@link #addArg(String)} but concats both name + value with an "=" sign, quoting were needed, and excluding the "=" portion if the value is - * undefined or empty. - * - *

-     *   addEqualsArg("-Dname", "value") = "-Dname=value"
-     *   addEqualsArg("-Djetty.home", "/opt/company inc/jetty (7)/") = "-Djetty.home=/opt/company\ inc/jetty\ (7)/"
-     *   addEqualsArg("-Djenkins.workspace", "/opt/workspaces/jetty jdk7/") = "-Djenkins.workspace=/opt/workspaces/jetty\ jdk7/"
-     *   addEqualsArg("-Dstress", null) = "-Dstress"
-     *   addEqualsArg("-Dstress", "") = "-Dstress"
-     * 
- * + * Add a "name=value" style argument to the command line with + * name and value quoted if necessary. * @param name the name * @param value the value */ - public void addEqualsArg(String name, String value) + public void addArg(String name, String value) { + Objects.requireNonNull(name); + + if (commandLine.length() > 0) + commandLine.append(separator); + if ((value != null) && (value.length() > 0)) { args.add(name + "=" + value); + commandLine.append(shellQuoteIfNeeded(name)).append('=').append(shellQuoteIfNeeded(value)); } else { args.add(name); + commandLine.append(shellQuoteIfNeeded(name)); } } /** - * Add a simple argument to the command line. - *

- * Will NOT quote/escape arguments that have a space in them. - * - * @param arg the simple argument to add + * Adds a "-OPTION" style option to the command line with no quoting, for example `--help`. + * @param option the option */ - public void addRawArg(String arg) + public void addOption(String option) { - if (arg != null) + addOption(option, null, null); + } + + /** + * Adds a "-OPTIONname=value" style option to the command line with + * name and value quoted if necessary, for example "-Dprop=value". + * @param option the option + * @param name the name + * @param value the value + */ + public void addOption(String option, String name, String value) + { + Objects.requireNonNull(option); + + if (commandLine.length() > 0) + commandLine.append(separator); + + if (name == null || name.length() == 0) { - args.add(arg); + commandLine.append(option); + args.add(option); + } + else if ((value != null) && (value.length() > 0)) + { + args.add(option + name + "=" + value); + commandLine.append(option).append(shellQuoteIfNeeded(name)).append('=').append(shellQuoteIfNeeded(value)); + } + else + { + args.add(option + name); + commandLine.append(option).append(shellQuoteIfNeeded(name)); } } @@ -129,20 +209,12 @@ public class CommandLineBuilder @Override public String toString() - { - return toString(" "); - } - - public String toString(String delim) { StringBuilder buf = new StringBuilder(); - for (String arg : args) { if (buf.length() > 0) - { - buf.append(delim); - } + buf.append(' '); buf.append(arg); // we assume escaping has occurred during addArg } @@ -154,23 +226,9 @@ public class CommandLineBuilder * * @return the toString but each arg that has spaces is surrounded by {@code '} (single-quote tick) */ - public String toQuotedString() + public String toCommandLine() { - StringBuilder buf = new StringBuilder(); - - for (String arg : args) - { - if (buf.length() > 0) - buf.append(' '); - boolean needsQuotes = (arg.contains(" ")); - if (needsQuotes) - buf.append("'"); - buf.append(arg); - if (needsQuotes) - buf.append("'"); - } - - return buf.toString(); + return commandLine.toString(); } public void debug() diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index afe0e875af9..4ccc2325ac3 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -436,7 +436,7 @@ public class Main { CommandLineBuilder cmd = args.getMainArgs(args.getDryRunParts()); cmd.debug(); - System.out.println(cmd.toQuotedString()); + System.out.println(cmd.toCommandLine()); } if (args.isStopCommand()) diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 4b6585bfec4..6dcadddb57a 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -13,6 +13,7 @@ package org.eclipse.jetty.start; +import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; @@ -182,6 +183,7 @@ public class StartArgs private boolean listConfig = false; private boolean version = false; private boolean dryRun = false; + private boolean multiLine = false; private final Set dryRunParts = new HashSet<>(); private boolean jpms = false; private boolean createStartD = false; @@ -493,17 +495,6 @@ public class StartArgs return files; } - /** - * Gets the List of JVM arguments detected. - * - * @deprecated use {@link #getJvmArgSources()} instead, as it will return source references with each arg. - */ - @Deprecated - public List getJvmArgs() - { - return new ArrayList<>(jvmArgSources.keySet()); - } - /** * Return ordered Map of JVM arguments to Source (locations) * @@ -519,7 +510,7 @@ public class StartArgs if (parts.isEmpty()) parts = ALL_PARTS; - CommandLineBuilder cmd = new CommandLineBuilder(); + CommandLineBuilder cmd = new CommandLineBuilder(multiLine); // Special Stop/Shutdown properties ensureSystemPropertySet("STOP.PORT"); @@ -527,13 +518,13 @@ public class StartArgs ensureSystemPropertySet("STOP.WAIT"); if (parts.contains("java")) - cmd.addRawArg(CommandLineBuilder.findJavaBin()); + cmd.addArg(CommandLineBuilder.findJavaBin()); if (parts.contains("opts")) { - cmd.addRawArg("-Djava.io.tmpdir=" + System.getProperty("java.io.tmpdir")); - cmd.addRawArg("-Djetty.home=" + baseHome.getHome()); - cmd.addRawArg("-Djetty.base=" + baseHome.getBase()); + cmd.addOption("-D", "java.io.tmpdir", System.getProperty("java.io.tmpdir")); + cmd.addOption("-D", "jetty.home", baseHome.getHome()); + cmd.addOption("-D", "jetty.base", baseHome.getBase()); Props properties = jettyEnvironment.getProperties(); for (String x : getJvmArgSources().keySet()) @@ -545,11 +536,11 @@ public class StartArgs String value = assign.length == 1 ? "" : assign[1]; Prop p = processSystemProperty(key, value, null); - cmd.addRawArg("-D" + p.key + "=" + properties.expand(p.value)); + cmd.addOption("-D", p.key, properties.expand(p.value)); } else { - cmd.addRawArg(properties.expand(x)); + cmd.addArg(properties.expand(x)); } } @@ -557,7 +548,7 @@ public class StartArgs for (String propKey : systemPropertySource.keySet()) { String value = System.getProperty(propKey); - cmd.addEqualsArg("-D" + propKey, value); + cmd.addOption("-D", propKey, value); } } @@ -594,38 +585,38 @@ public class StartArgs if (!files.isEmpty()) { - cmd.addRawArg("--module-path"); + cmd.addOption("--module-path"); String modules = files.stream() .map(Path::toAbsolutePath) .map(Path::toString) .collect(Collectors.joining(FS.pathSeparator())); - cmd.addRawArg(modules); + cmd.addArg(modules); } List dirs = dirsAndFiles.get(true); if (dirs != null && !dirs.isEmpty()) { - cmd.addRawArg("--class-path"); + cmd.addOption("--class-path"); String directories = dirs.stream() .map(Path::toAbsolutePath) .map(Path::toString) .collect(Collectors.joining(FS.pathSeparator())); - cmd.addRawArg(directories); + cmd.addArg(directories); } generateJpmsArgs(cmd); } else { - cmd.addRawArg("--class-path"); - cmd.addRawArg(jettyEnvironment.getClasspath().toString()); + cmd.addOption("--class-path"); + cmd.addArg(jettyEnvironment.getClasspath().toString()); } } if (parts.contains("main")) { if (isJPMS()) - cmd.addRawArg("--module"); - cmd.addRawArg(getMainClassname()); + cmd.addOption("--module"); + cmd.addArg(getMainClassname()); } // do properties and xmls @@ -637,7 +628,8 @@ public class StartArgs // pass properties as args for (Prop p : properties) { - cmd.addRawArg(CommandLineBuilder.quote(p.key) + "=" + CommandLineBuilder.quote(properties.expand(p.value))); + if (!p.key.startsWith("java.version.")) + cmd.addArg(p.key, properties.expand(p.value)); } } else if (properties.size() > 0) @@ -658,17 +650,17 @@ public class StartArgs { properties.store(out, "start.jar properties"); } - cmd.addRawArg(propPath.toAbsolutePath().toString()); + cmd.addArg(propPath.toAbsolutePath().toString()); } for (Path xml : jettyEnvironment.getXmlFiles()) { - cmd.addRawArg(xml.toAbsolutePath().toString()); + cmd.addArg(xml.toAbsolutePath().toString()); } for (Path propertyFile : jettyEnvironment.getPropertyFiles()) { - cmd.addRawArg(propertyFile.toAbsolutePath().toString()); + cmd.addArg(propertyFile.toAbsolutePath().toString()); } } @@ -773,28 +765,28 @@ public class StartArgs { if (!_jmodAdds.isEmpty()) { - cmd.addRawArg("--add-modules"); - cmd.addRawArg(String.join(",", _jmodAdds)); + cmd.addOption("--add-modules"); + cmd.addArg(String.join(",", _jmodAdds)); } for (Map.Entry> entry : _jmodPatch.entrySet()) { - cmd.addRawArg("--patch-module"); - cmd.addRawArg(entry.getKey() + "=" + String.join(FS.pathSeparator(), entry.getValue())); + cmd.addOption("--patch-module"); + cmd.addArg(entry.getKey(), String.join(File.pathSeparator, entry.getValue())); } for (Map.Entry> entry : _jmodOpens.entrySet()) { - cmd.addRawArg("--add-opens"); - cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue())); + cmd.addOption("--add-opens"); + cmd.addArg(entry.getKey(), String.join(",", entry.getValue())); } for (Map.Entry> entry : _jmodExports.entrySet()) { - cmd.addRawArg("--add-exports"); - cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue())); + cmd.addOption("--add-exports"); + cmd.addArg(entry.getKey(), String.join(",", entry.getValue())); } for (Map.Entry> entry : _jmodReads.entrySet()) { - cmd.addRawArg("--add-reads"); - cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue())); + cmd.addOption("--add-reads"); + cmd.addArg(entry.getKey(), String.join(",", entry.getValue())); } } @@ -1154,6 +1146,12 @@ public class StartArgs int colon = arg.indexOf('='); for (String part : arg.substring(colon + 1).split(",")) { + if ("multiline".equalsIgnoreCase(part)) + { + multiLine = true; + continue; + } + if (!ALL_PARTS.contains(part)) throw new UsageException(UsageException.ERR_BAD_ARG, "Unrecognized --dry-run=\"%s\" in %s", part, source); diff --git a/jetty-core/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt b/jetty-core/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt index 64f8461abbf..e316011a83d 100644 --- a/jetty-core/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt +++ b/jetty-core/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt @@ -60,12 +60,13 @@ Report Commands: --dry-run Prints the command line that start.jar generates, - then exits. + in a format usable by a POSIX compliant shell, then exits. This may be used to generate command lines into scripts: $ java -jar start.jar --dry-run > jetty.sh --dry-run=(,)* - Prints specific parts of the command line. The parts are: + Prints specific parts of the command line in a format usable by + a POSIX compliant shell. The parts are: o "java" - the JVM to run o "opts" - the JVM options (e.g. -D, -X and -XX flags) o "path" - the JVM class-path and/or the JPMS module-path diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java index 06753229e7e..6f938f7ae00 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java @@ -13,7 +13,12 @@ package org.eclipse.jetty.start; +import java.util.stream.Stream; + import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -23,43 +28,90 @@ public class CommandLineBuilderTest @Test public void testSimpleCommandline() { - CommandLineBuilder cmd = new CommandLineBuilder("java"); - cmd.addEqualsArg("-Djava.io.tmpdir", "/home/java/temp dir/"); + CommandLineBuilder cmd = new CommandLineBuilder(); + cmd.addArg("java"); + cmd.addArg("-Djava.io.tmpdir", "/home/java/temp dir/"); cmd.addArg("--version"); - assertThat(cmd.toQuotedString(), is("java '-Djava.io.tmpdir=/home/java/temp dir/' --version")); + assertThat(cmd.toCommandLine(), is("java -Djava.io.tmpdir='/home/java/temp dir/' --version")); } @Test public void testSimpleHomeNoSpace() { - CommandLineBuilder cmd = new CommandLineBuilder("java"); - cmd.addEqualsArg("-Djetty.home", "/opt/jetty"); - assertThat(cmd.toQuotedString(), is("java -Djetty.home=/opt/jetty")); + CommandLineBuilder cmd = new CommandLineBuilder(); + cmd.addArg("java"); + cmd.addArg("-Djetty.home", "/opt/jetty"); + assertThat(cmd.toCommandLine(), is("java -Djetty.home=/opt/jetty")); } @Test public void testSimpleHomeWithSpace() { - CommandLineBuilder cmd = new CommandLineBuilder("java"); - cmd.addEqualsArg("-Djetty.home", "/opt/jetty 10/home"); - assertThat(cmd.toQuotedString(), is("java '-Djetty.home=/opt/jetty 10/home'")); + CommandLineBuilder cmd = new CommandLineBuilder(); + cmd.addArg("java"); + cmd.addArg("-Djetty.home", "/opt/jetty 10/home"); + assertThat(cmd.toCommandLine(), is("java -Djetty.home='/opt/jetty 10/home'")); } @Test public void testEscapedFormattingString() { - CommandLineBuilder cmd = new CommandLineBuilder("java"); - cmd.addEqualsArg("-Djetty.home", "/opt/jetty"); - cmd.addEqualsArg("jetty.requestlog.formatter", "%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t \"%r\" %s %O \"%{Referer}i\" \"%{User-Agent}i\""); - assertThat(cmd.toQuotedString(), is("java -Djetty.home=/opt/jetty 'jetty.requestlog.formatter=%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t \"%r\" %s %O \"%{Referer}i\" \"%{User-Agent}i\"'")); + CommandLineBuilder cmd = new CommandLineBuilder(); + cmd.addArg("java"); + cmd.addArg("-Djetty.home", "/opt/jetty"); + cmd.addArg("jetty.requestlog.formatter", "%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t \"%r\" %s %O \"%{Referer}i\" \"%{User-Agent}i\""); + assertThat(cmd.toCommandLine(), is("java -Djetty.home=/opt/jetty jetty.requestlog.formatter='%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t \"%r\" %s %O \"%{Referer}i\" \"%{User-Agent}i\"'")); } @Test public void testEscapeUnicode() { - CommandLineBuilder cmd = new CommandLineBuilder("java"); - cmd.addEqualsArg("-Djetty.home", "/opt/jetty"); - cmd.addEqualsArg("monetary.symbol", "€"); - assertThat(cmd.toQuotedString(), is("java -Djetty.home=/opt/jetty monetary.symbol=€")); + CommandLineBuilder cmd = new CommandLineBuilder(); + cmd.addArg("java"); + cmd.addArg("-Djetty.home", "/opt/jetty"); + cmd.addArg("monetary.symbol", "€"); + assertThat(cmd.toCommandLine(), is("java -Djetty.home=/opt/jetty monetary.symbol='€'")); + } + + public static Stream shellQuoting() + { + return Stream.of( + Arguments.of(null, null), + Arguments.of("", "''"), + Arguments.of("Hello", "Hello"), + Arguments.of("Hell0", "Hell0"), + Arguments.of("Hello$World", "'Hello$World'"), + Arguments.of("Hello\\World", "'Hello\\World'"), + Arguments.of("Hello`World", "'Hello`World'"), + Arguments.of("'Hello World'", "\\''Hello World'\\'"), + Arguments.of("\"Hello World\"", "'\"Hello World\"'"), + Arguments.of("H-llo_world", "H-llo_world"), + Arguments.of("H:llo/world", "H:llo/world"), + Arguments.of("Hello World", "'Hello World'"), + Arguments.of("foo\\bar", "'foo\\bar'"), + Arguments.of("foo'bar", "'foo'\\''bar'"), + Arguments.of("some 'internal' quoting", "'some '\\''internal'\\'' quoting'"), + Arguments.of("monetary.symbol=€", "'monetary.symbol=€'") + ); + } + + @ParameterizedTest + @MethodSource("shellQuoting") + public void testShellQuoting(String string, String expected) + { + assertThat(CommandLineBuilder.shellQuoteIfNeeded(string), is(expected)); + } + + @Test + public void testMultiLine() + { + CommandLineBuilder cmd = new CommandLineBuilder(true); + cmd.addArg("java"); + cmd.addArg("-Djetty.home", "/opt/jetty"); + cmd.addArg("monetary.symbol", "€"); + assertThat(cmd.toCommandLine(), + is("java \\" + System.lineSeparator() + + " -Djetty.home=/opt/jetty \\" + System.lineSeparator() + + " monetary.symbol='€'")); } } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java index 036668f152f..98051e391eb 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java @@ -177,7 +177,7 @@ public class MainTest assertThat("jetty.base", baseHome.getBase(), is(homePath.toString())); CommandLineBuilder commandLineBuilder = args.getMainArgs(StartArgs.ALL_PARTS); - String commandLine = commandLineBuilder.toString("\n"); + String commandLine = commandLineBuilder.toString(); String expectedExpansion = String.format("-Xloggc:%s/logs/gc-%s.log", baseHome.getBase(), System.getProperty("java.version") ); diff --git a/jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java b/jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java index bf374c9d50f..6165ac4b708 100644 --- a/jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java +++ b/jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java @@ -104,11 +104,16 @@ public class XmlParser return _lock.lock(); } + protected SAXParserFactory newSAXParserFactory() + { + return SAXParserFactory.newInstance(); + } + public void setValidating(boolean validating) { try { - SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParserFactory factory = newSAXParserFactory(); factory.setValidating(validating); _parser = factory.newSAXParser(); @@ -150,6 +155,11 @@ public class XmlParser return _parser.isValidating(); } + public SAXParser getSAXParser() + { + return _parser; + } + /** * Load the specified URI as a catalog for entity mapping purposes. * diff --git a/jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java b/jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java index d0863a19392..3a84117d0d9 100644 --- a/jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java +++ b/jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java @@ -15,12 +15,18 @@ package org.eclipse.jetty.xml; import java.net.URL; import java.nio.file.Path; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class XmlParserTest { @@ -73,4 +79,32 @@ public class XmlParserTest assertTrue(testDocStr.startsWith("")); } + + /** + * Customize SAXParserFactory behavior. + */ + @Test + public void testNewSAXParserFactory() throws SAXException + { + XmlParser xmlParser = new XmlParser() + { + @Override + protected SAXParserFactory newSAXParserFactory() + { + SAXParserFactory saxParserFactory = super.newSAXParserFactory(); + // Configure at factory level + saxParserFactory.setXIncludeAware(false); + return saxParserFactory; + } + }; + + SAXParser saxParser = xmlParser.getSAXParser(); + assertNotNull(saxParser); + + XMLReader xmlReader = saxParser.getXMLReader(); + // Only run testcase if Xerces is being used. + assumeTrue(xmlReader.getClass().getName().contains("org.apache.xerces.")); + // look to see it was set at XMLReader level + assertFalse(xmlReader.getFeature("http://apache.org/xml/features/xinclude")); + } } diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/pom.xml b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/pom.xml index 1fec9811ca6..c30c30552dd 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/pom.xml +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/pom.xml @@ -97,11 +97,6 @@ jetty-http2-server test - - org.eclipse.jetty - jetty-slf4j-impl - test - org.eclipse.jetty.toolchain jetty-test-helper diff --git a/pom.xml b/pom.xml index b6c986f1415..58fd854ea7c 100644 --- a/pom.xml +++ b/pom.xml @@ -36,9 +36,9 @@ 1.11.1 4.5.14 4.4.16 - 2.2.8 + 2.2.9 2.5.10 - 2.2.1 + 2.2.2 9.5 4.2.0 6.4.1 @@ -46,7 +46,7 @@ 10.6.0 1.16.0 1.23.0 - 2.12.0 + 2.13.0 3.12.0 2.5.2 3.4.2 @@ -140,12 +140,11 @@ 4.0.2 2.0.7 1.3.6 - 2.1.1.RELEASE 1.2.5 1.2.5 1.18.3 1.6.0.Final - 2.2.0.Final + 2.2.1.Final 2.4.7 @@ -162,7 +161,7 @@ 3.1.0 3.6.0 5.1.9 - 3.2.0 + 3.3.1 3.3.0 3.11.0 3.6.0 @@ -171,19 +170,19 @@ 3.1.0 3.1.0 3.1.1 - 3.5.1 + 3.6.0 4.0.6 3.3.0 3.5.0 3.9.0 3.9.0 - 3.0.0 + 3.0.1 3.1.0 3.3.1 - 3.4.1 - 3.1.0 + 3.5.0 + 3.1.2 3.3.0 - 3.3.2 + 3.4.0 4.7.2.0 2.14.2