diff --git a/owasp-suppressions.xml b/owasp-suppressions.xml index d9b70048c71..467a3224dab 100644 --- a/owasp-suppressions.xml +++ b/owasp-suppressions.xml @@ -10,10 +10,16 @@ CVE-2022-29546 + ^pkg:maven/xerces/xercesImpl@.*$ CVE-2017-10355 + ^pkg:maven/xalan/xalan@.*$ CVE-2022-34169 @@ -21,8 +27,4 @@ ^pkg:maven/xalan/serializer@.*$ CVE-2022-34169 - - ^pkg:maven/.*jetty.io.9\.4\.48\.v20220622.*$ - CVE-2022-2191 - \ No newline at end of file diff --git a/pom.xml b/pom.xml index aa3b6e83f77..f85464e256c 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 1.12.0 2.64.0 2.64.0 - 1.0.0-SNAPSHOT + 2.65.0-SNAPSHOT 4.5.13 9.4.49.v20220914 diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 06d3e6af5b1..79c01ac0c86 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -8,6 +8,12 @@ + + com.gargoylesoftware.htmlunit.util.TextUtils removed. + + + Switch from xalan to htmlunit-xpath. + Upgrade Jetty to 9.4.49.v20220914. @@ -15,7 +21,6 @@ Introducing a PrintHandler configurable at the WebClient. You can provide your own Window.print() implementations if required. - A bug in one faq sample code that might result in wrong encoding is fixed. diff --git a/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java b/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java index 87e9eaa9719..239ab42a2f9 100644 --- a/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java +++ b/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java @@ -30,7 +30,6 @@ import com.gargoylesoftware.htmlunit.util.MimeType; import com.gargoylesoftware.htmlunit.util.NameValuePair; -import com.gargoylesoftware.htmlunit.util.TextUtils; /** * A fake {@link WebConnection} designed to mock out the actual HTTP connections. @@ -103,7 +102,7 @@ else if (stringContent_ == null) { content = new byte[] {}; } else { - content = TextUtils.stringToByteArray(stringContent_, charset_); + content = stringContent_.getBytes(charset_); } return new WebResponseData(content, statusCode_, statusMessage_, headers_); } diff --git a/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java b/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java index dc8988bd4e9..4803477afc8 100644 --- a/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java +++ b/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java @@ -24,7 +24,7 @@ import org.apache.http.HttpStatus; import com.gargoylesoftware.htmlunit.util.NameValuePair; -import com.gargoylesoftware.htmlunit.util.TextUtils; +import com.gargoylesoftware.htmlunit.util.StringUtils; /** * A simple WebResponse created from a string. Content is assumed to be of type text/html. @@ -68,7 +68,7 @@ public StringWebResponse(final String content, final Charset charset, final URL * @return a simple WebResponseData with defaults specified */ private static WebResponseData getWebResponseData(final String contentString, final Charset charset) { - final byte[] content = TextUtils.stringToByteArray(contentString, charset); + final byte[] content = StringUtils.toByteArray(contentString, charset); final List compiledHeaders = new ArrayList<>(); compiledHeaders.add(new NameValuePair(HttpHeader.CONTENT_TYPE, "text/html; charset=" + charset)); return new WebResponseData(content, HttpStatus.SC_OK, "OK", compiledHeaders); diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java b/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java index 41d62ba6640..6bdb93d8b4c 100644 --- a/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java +++ b/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java @@ -106,7 +106,6 @@ import com.gargoylesoftware.htmlunit.util.Cookie; import com.gargoylesoftware.htmlunit.util.MimeType; import com.gargoylesoftware.htmlunit.util.NameValuePair; -import com.gargoylesoftware.htmlunit.util.TextUtils; import com.gargoylesoftware.htmlunit.util.UrlUtils; import com.gargoylesoftware.htmlunit.webstart.WebStartHandler; import com.shapesecurity.salvation2.Policy; @@ -1424,7 +1423,8 @@ private WebResponse makeWebResponseForFileUrl(final WebRequest webRequest) throw compiledHeaders.add(new NameValuePair(HttpHeader.CONTENT_TYPE, MimeType.TEXT_HTML)); final WebResponseData responseData = new WebResponseData( - TextUtils.stringToByteArray("File: " + file.getAbsolutePath(), UTF_8), + com.gargoylesoftware.htmlunit.util.StringUtils + .toByteArray("File: " + file.getAbsolutePath(), UTF_8), 404, "Not Found", compiledHeaders); return new WebResponse(responseData, webRequest, 0); } diff --git a/src/main/java/com/gargoylesoftware/htmlunit/protocol/javascript/JavaScriptURLConnection.java b/src/main/java/com/gargoylesoftware/htmlunit/protocol/javascript/JavaScriptURLConnection.java index 9199c610862..fc9cf5b0376 100644 --- a/src/main/java/com/gargoylesoftware/htmlunit/protocol/javascript/JavaScriptURLConnection.java +++ b/src/main/java/com/gargoylesoftware/htmlunit/protocol/javascript/JavaScriptURLConnection.java @@ -17,8 +17,9 @@ import java.io.InputStream; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.StandardCharsets; -import com.gargoylesoftware.htmlunit.util.TextUtils; +import org.apache.commons.io.IOUtils; /** * A URLConnection for supporting JavaScript URLs. @@ -56,7 +57,7 @@ public void connect() { */ @Override public InputStream getInputStream() { - return TextUtils.toInputStream(content_); + return IOUtils.toInputStream(content_, StandardCharsets.ISO_8859_1); } } diff --git a/src/main/java/com/gargoylesoftware/htmlunit/util/StringUtils.java b/src/main/java/com/gargoylesoftware/htmlunit/util/StringUtils.java index 8c39fc2d713..332dad305cd 100644 --- a/src/main/java/com/gargoylesoftware/htmlunit/util/StringUtils.java +++ b/src/main/java/com/gargoylesoftware/htmlunit/util/StringUtils.java @@ -14,6 +14,7 @@ */ package com.gargoylesoftware.htmlunit.util; +import java.nio.charset.Charset; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -385,4 +386,19 @@ public static String cssDeCamelize(final String string) { } return builder.toString(); } + + /** + * Converts a string into a byte array using the specified encoding. + * + * @param charset the charset + * @param content the string to convert + * @return the String as a byte[]; if the specified encoding is not supported an empty byte[] will be returned + */ + public static byte[] toByteArray(final String content, final Charset charset) { + if (content == null || content.isEmpty()) { + return new byte[0]; + } + + return content.getBytes(charset); + } } diff --git a/src/main/java/com/gargoylesoftware/htmlunit/util/TextUtils.java b/src/main/java/com/gargoylesoftware/htmlunit/util/TextUtils.java deleted file mode 100644 index 7bd7ad91835..00000000000 --- a/src/main/java/com/gargoylesoftware/htmlunit/util/TextUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2002-2022 Gargoyle Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gargoylesoftware.htmlunit.util; - -import static java.nio.charset.StandardCharsets.ISO_8859_1; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; - -/** - * Utility methods relating to text. - * - * @author Mike Bowler - * @author Brad Clarke - * @author Ahmed Ashour - * @author Ronald Brill - */ -public final class TextUtils { - - /** Private constructor to prevent instantiation. */ - private TextUtils() { - } - - /** - * Convert a string into an input stream. - * @param content the string - * @return the resulting input stream - */ - public static InputStream toInputStream(final String content) { - return toInputStream(content, ISO_8859_1); - } - - /** - * Convert a string into an input stream. - * @param content the string - * @param charset the encoding to use when converting the string to a stream - * @return the resulting input stream - */ - public static InputStream toInputStream( - final String content, - final Charset charset) { - - try { - final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(content.length() * 2); - final OutputStreamWriter writer = new OutputStreamWriter(byteArrayOutputStream, charset); - writer.write(content); - writer.flush(); - - final byte[] byteArray = byteArrayOutputStream.toByteArray(); - return new ByteArrayInputStream(byteArray); - } - catch (final IOException e) { - // Theoretically impossible since all the "IO" is in memory but it's a - // checked exception so we have to catch it. - throw new IllegalStateException("Exception when converting a string to an input stream: '" + e + "'", e); - } - } - - /** - * Converts a string into a byte array using the specified encoding. - * - * @param charset the charset - * @param content the string to convert - * @return the String as a byte[]; if the specified encoding is not supported an empty byte[] will be returned - */ - public static byte[] stringToByteArray(final String content, final Charset charset) { - if (content == null || content.isEmpty() || charset == null) { - return new byte[0]; - } - - return content.getBytes(charset); - } -} diff --git a/src/test/java/com/gargoylesoftware/htmlunit/html/DomTextTest.java b/src/test/java/com/gargoylesoftware/htmlunit/html/DomTextTest.java index 528a9e330f5..159638cadd7 100644 --- a/src/test/java/com/gargoylesoftware/htmlunit/html/DomTextTest.java +++ b/src/test/java/com/gargoylesoftware/htmlunit/html/DomTextTest.java @@ -27,7 +27,7 @@ import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.junit.BrowserRunner; import com.gargoylesoftware.htmlunit.util.MimeType; -import com.gargoylesoftware.htmlunit.util.TextUtils; +import com.gargoylesoftware.htmlunit.util.StringUtils; /** * Tests for {@link DomText}. @@ -161,7 +161,7 @@ public void asXml() throws Exception { final WebClient client = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); - webConnection.setDefaultResponse(TextUtils.stringToByteArray(html, UTF_8), 200, "OK", MimeType.TEXT_HTML); + webConnection.setDefaultResponse(StringUtils.toByteArray(html, UTF_8), 200, "OK", MimeType.TEXT_HTML); client.setWebConnection(webConnection); final HtmlPage page = client.getPage(URL_FIRST); diff --git a/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlPageTest.java b/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlPageTest.java index b446d28756f..7fac6c428c0 100644 --- a/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlPageTest.java +++ b/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlPageTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -33,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SerializationUtils; import org.junit.Test; import org.junit.runner.RunWith; @@ -59,7 +61,7 @@ import com.gargoylesoftware.htmlunit.util.Cookie; import com.gargoylesoftware.htmlunit.util.MimeType; import com.gargoylesoftware.htmlunit.util.NameValuePair; -import com.gargoylesoftware.htmlunit.util.TextUtils; +import com.gargoylesoftware.htmlunit.util.StringUtils; /** * Tests for {@link HtmlPage}. @@ -998,7 +1000,7 @@ public void asXml2() throws Exception { assertNotNull("xml document could not be parsed", page.asXml()); final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); final DocumentBuilder builder = factory.newDocumentBuilder(); - builder.parse(TextUtils.toInputStream(page.asXml())); + builder.parse(IOUtils.toInputStream(page.asXml(), StandardCharsets.ISO_8859_1)); } /** @@ -1014,7 +1016,7 @@ public void asXml_unicode() throws Exception { final WebClient client = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); - webConnection.setDefaultResponse(TextUtils.stringToByteArray(html, UTF_8), 200, "OK", MimeType.TEXT_HTML); + webConnection.setDefaultResponse(StringUtils.toByteArray(html, UTF_8), 200, "OK", MimeType.TEXT_HTML); client.setWebConnection(webConnection); final HtmlPage page = client.getPage(URL_FIRST); diff --git a/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/WindowTest.java b/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/WindowTest.java index 9000d02758d..716844f8c2b 100644 --- a/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/WindowTest.java +++ b/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/WindowTest.java @@ -1766,110 +1766,6 @@ public void handlePrint(final HtmlPage page) { assertEquals(getExpectedAlerts()[0], page.getTitleText()); } - /** - * @throws Exception if the test fails - */ - @Test - @Alerts(DEFAULT = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-false-[object Window]" - + "-false-2-true-true-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-false-[object Window]" - + "-false-2-true-true-[object Window]-[object Window]-afterprint" - + "§printed§", - IE = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-undefined-[object Window]" - + "-false-2-true-undefined-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-undefined-[object Window]" - + "-false-2-true-undefined-[object Window]-[object Window]-afterprint" - + "§printed§") - @HtmlUnitNYI(CHROME = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-afterprint" - + "§printed§", - EDGE = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-afterprint" - + "§printed§", - FF = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-afterprint" - + "§printed§", - FF_ESR = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-false-[object Window]" - + "-false-2-undefined-true-[object Window]-[object Window]-afterprint" - + "§printed§", - IE = "before print" - + "§event beforeprint" - + "§[object Event]beforeprint-false-false-undefined-[object Window]" - + "-false-2-undefined-undefined-[object Window]-[object Window]-beforeprint" - + "§event afterprint" - + "§[object Event]afterprint-false-false-undefined-[object Window]" - + "-false-2-undefined-undefined-[object Window]-[object Window]-afterprint" - + "§printed§") - public void printEventCancel() throws Exception { - // we have to test this manually - - final WebClient webClient = getWebClient(); - final MockWebConnection webConnection = new MockWebConnection(); - - // without an print handler set the print method is a noop - webClient.setPrintHandler(new PrintHandler() { - @Override - public void handlePrint(final HtmlPage page) { - } - }); - - - final String firstContent - = "\n" - + "\n" - + "\n" - + "\n" - + " \n" - + ""; - - final URL url = URL_FIRST; - webConnection.setResponse(url, firstContent); - webClient.setWebConnection(webConnection); - - final HtmlPage page = webClient.getPage(URL_FIRST); - page.getElementById("click").click(); - webClient.waitForBackgroundJavaScript(DEFAULT_WAIT_TIME); - - assertEquals(getExpectedAlerts()[0], page.getTitleText()); - } - /** * @throws Exception if the test fails */ diff --git a/src/test/java/com/gargoylesoftware/htmlunit/util/StringUtilsTest.java b/src/test/java/com/gargoylesoftware/htmlunit/util/StringUtilsTest.java index 874b1478408..7fd109ec5f0 100644 --- a/src/test/java/com/gargoylesoftware/htmlunit/util/StringUtilsTest.java +++ b/src/test/java/com/gargoylesoftware/htmlunit/util/StringUtilsTest.java @@ -14,6 +14,8 @@ */ package com.gargoylesoftware.htmlunit.util; +import static java.nio.charset.StandardCharsets.UTF_8; + import org.junit.Test; import com.gargoylesoftware.htmlunit.SimpleWebTestCase; @@ -131,4 +133,20 @@ public void sanitizeForFileName() { assertEquals("Html_Uni_", StringUtils.sanitizeForFileName("Html:Uni\t")); assertEquals("Html_Unit", StringUtils.sanitizeForFileName("Html\\Unit")); } + + /** + * @throws Exception if the test fails + */ + @Test + public void stringToByteArray() throws Exception { + byte[] result = StringUtils.toByteArray(null, UTF_8); + assertEquals(0, result.length); + + result = StringUtils.toByteArray("", UTF_8); + assertEquals(0, result.length); + + result = StringUtils.toByteArray("htmlunit", UTF_8); + assertEquals(8, result.length); + assertEquals(104, result[0]); + } } diff --git a/src/test/java/com/gargoylesoftware/htmlunit/util/TextUtilsTest.java b/src/test/java/com/gargoylesoftware/htmlunit/util/TextUtilsTest.java deleted file mode 100644 index 92fb9e32d0a..00000000000 --- a/src/test/java/com/gargoylesoftware/htmlunit/util/TextUtilsTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2002-2022 Gargoyle Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gargoylesoftware.htmlunit.util; - -import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.fail; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.Charset; - -import org.junit.Test; - -import com.gargoylesoftware.htmlunit.SimpleWebTestCase; - -/** - * Tests for {@link TextUtils}. - * - * @author Mike Bowler - */ -public class TextUtilsTest extends SimpleWebTestCase { - - /** - * @throws Exception if the test fails - */ - @Test - public void toInputStream_null() throws Exception { - try { - TextUtils.toInputStream(null); - fail("Expected NullPointerException"); - } - catch (final NullPointerException e) { - // Expected path - } - } - - /** - * @throws Exception if the test fails - */ - @Test - public void toInputStream() throws Exception { - final String[][] data = { - {"", null}, - {"a", "a"}, - {"abcdefABCDEF", "abcdefABCDEF"}, - }; - final Charset encoding = ISO_8859_1; - - for (final String[] entry : data) { - final String input = entry[0]; - final String expectedResult = entry[1]; - - try (InputStream inputStream = TextUtils.toInputStream(input, encoding)) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, encoding))) { - assertEquals(expectedResult, reader.readLine()); - } - } - } - } - - /** - * @throws Exception if the test fails - */ - @Test - public void stringToByteArray() throws Exception { - byte[] result = TextUtils.stringToByteArray(null, UTF_8); - assertEquals(0, result.length); - - result = TextUtils.stringToByteArray("", UTF_8); - assertEquals(0, result.length); - - result = TextUtils.stringToByteArray("htmlunit", UTF_8); - assertEquals(8, result.length); - assertEquals(104, result[0]); - - result = TextUtils.stringToByteArray("htmlunit", null); - assertEquals(0, result.length); - } - -} diff --git a/src/test/java/com/gargoylesoftware/htmlunit/xml/XmlPageTest.java b/src/test/java/com/gargoylesoftware/htmlunit/xml/XmlPageTest.java index 36b4f278c7e..f9c35fd00d6 100644 --- a/src/test/java/com/gargoylesoftware/htmlunit/xml/XmlPageTest.java +++ b/src/test/java/com/gargoylesoftware/htmlunit/xml/XmlPageTest.java @@ -41,7 +41,7 @@ import com.gargoylesoftware.htmlunit.html.DomText; import com.gargoylesoftware.htmlunit.junit.BrowserRunner; import com.gargoylesoftware.htmlunit.util.MimeType; -import com.gargoylesoftware.htmlunit.util.TextUtils; +import com.gargoylesoftware.htmlunit.util.StringUtils; /** * Tests for {@link XmlPage}. @@ -177,7 +177,7 @@ public void defaultEncoding() throws Exception { + "\u0434\n" + ""; - final byte[] bytes = TextUtils.stringToByteArray(content, UTF_8); + final byte[] bytes = StringUtils.toByteArray(content, UTF_8); final WebClient client = getWebClient(); final MockWebConnection webConnection = new MockWebConnection();