undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
236
test/jdk/java/net/httpclient/websocket/WebSocketBuilderTest.java
Normal file
236
test/jdk/java/net/httpclient/websocket/WebSocketBuilderTest.java
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8159053
|
||||
* @build DummyWebSocketServer
|
||||
* Support
|
||||
* @run junit/othervm WebSocketBuilderTest
|
||||
*/
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/*
|
||||
* In some places in this test a new String is created out of a string literal.
|
||||
* The idea is to make sure the code under test relies on something better than
|
||||
* the reference equality ( == ) for string equality checks.
|
||||
*/
|
||||
public final class WebSocketBuilderTest {
|
||||
|
||||
private final static URI VALID_URI = URI.create("ws://websocket.example.com");
|
||||
|
||||
@Test
|
||||
public void nullArguments() {
|
||||
HttpClient c = HttpClient.newHttpClient();
|
||||
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.buildAsync(null, listener()));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.buildAsync(VALID_URI, null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.buildAsync(null, null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.header(null, "value"));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.header("name", null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.header(null, null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols(null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols(null, "sub2.example.com"));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols("sub1.example.com", (String) null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols("sub1.example.com", (String[]) null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols("sub1.example.com", "sub2.example.com", null));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.subprotocols("sub1.example.com", null, "sub3.example.com"));
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> c.newWebSocketBuilder()
|
||||
.connectTimeout(null));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("badURIs")
|
||||
void illegalURI(URI uri) {
|
||||
WebSocket.Builder b = HttpClient.newHttpClient().newWebSocketBuilder();
|
||||
assertFails(IllegalArgumentException.class,
|
||||
b.buildAsync(uri, listener()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void illegalHeaders() {
|
||||
List<String> headers =
|
||||
List.of("Sec-WebSocket-Accept",
|
||||
"Sec-WebSocket-Extensions",
|
||||
"Sec-WebSocket-Key",
|
||||
"Sec-WebSocket-Protocol",
|
||||
"Sec-WebSocket-Version")
|
||||
.stream()
|
||||
.flatMap(s -> Stream.of(s, new String(s))) // a string and a copy of it
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Function<String, CompletionStage<?>> f =
|
||||
header -> HttpClient.newHttpClient()
|
||||
.newWebSocketBuilder()
|
||||
.header(header, "value")
|
||||
.buildAsync(VALID_URI, listener());
|
||||
|
||||
headers.forEach(h -> assertFails(IllegalArgumentException.class, f.apply(h)));
|
||||
}
|
||||
|
||||
// TODO: test for bad syntax headers
|
||||
// TODO: test for overwrites (subprotocols) and additions (headers)
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("badSubprotocols")
|
||||
public void illegalSubprotocolsSyntax(String s) {
|
||||
WebSocket.Builder b = HttpClient.newHttpClient()
|
||||
.newWebSocketBuilder()
|
||||
.subprotocols(s);
|
||||
assertFails(IllegalArgumentException.class,
|
||||
b.buildAsync(VALID_URI, listener()));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("duplicatingSubprotocols")
|
||||
public void illegalSubprotocolsDuplicates(String mostPreferred,
|
||||
String[] lesserPreferred) {
|
||||
WebSocket.Builder b = HttpClient.newHttpClient()
|
||||
.newWebSocketBuilder()
|
||||
.subprotocols(mostPreferred, lesserPreferred);
|
||||
assertFails(IllegalArgumentException.class,
|
||||
b.buildAsync(VALID_URI, listener()));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("badConnectTimeouts")
|
||||
public void illegalConnectTimeout(Duration d) {
|
||||
WebSocket.Builder b = HttpClient.newHttpClient()
|
||||
.newWebSocketBuilder()
|
||||
.connectTimeout(d);
|
||||
assertFails(IllegalArgumentException.class,
|
||||
b.buildAsync(VALID_URI, listener()));
|
||||
}
|
||||
|
||||
public static Object[][] badURIs() {
|
||||
return new Object[][]{
|
||||
{URI.create("http://example.com")},
|
||||
{URI.create("ftp://example.com")},
|
||||
{URI.create("wss://websocket.example.com/hello#fragment")},
|
||||
{URI.create("ws://websocket.example.com/hello#fragment")},
|
||||
};
|
||||
}
|
||||
|
||||
public static Object[][] badConnectTimeouts() {
|
||||
return new Object[][]{
|
||||
{Duration.ofDays(0)},
|
||||
{Duration.ofDays(-1)},
|
||||
{Duration.ofHours(0)},
|
||||
{Duration.ofHours(-1)},
|
||||
{Duration.ofMinutes(0)},
|
||||
{Duration.ofMinutes(-1)},
|
||||
{Duration.ofSeconds(0)},
|
||||
{Duration.ofSeconds(-1)},
|
||||
{Duration.ofMillis(0)},
|
||||
{Duration.ofMillis(-1)},
|
||||
{Duration.ofNanos(0)},
|
||||
{Duration.ofNanos(-1)},
|
||||
{Duration.ZERO},
|
||||
};
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc7230#section-3.2.6
|
||||
// https://tools.ietf.org/html/rfc20
|
||||
public static Object[][] badSubprotocols() {
|
||||
return new Object[][]{
|
||||
{""},
|
||||
{new String("")},
|
||||
{"round-brackets("},
|
||||
{"round-brackets)"},
|
||||
{"comma,"},
|
||||
{"slash/"},
|
||||
{"colon:"},
|
||||
{"semicolon;"},
|
||||
{"angle-brackets<"},
|
||||
{"angle-brackets>"},
|
||||
{"equals="},
|
||||
{"question-mark?"},
|
||||
{"at@"},
|
||||
{"brackets["},
|
||||
{"backslash\\"},
|
||||
{"brackets]"},
|
||||
{"curly-brackets{"},
|
||||
{"curly-brackets}"},
|
||||
{"space "},
|
||||
{"non-printable-character " + Character.toString((char) 31)},
|
||||
{"non-printable-character " + Character.toString((char) 127)},
|
||||
};
|
||||
}
|
||||
|
||||
public static Object[][] duplicatingSubprotocols() {
|
||||
return new Object[][]{
|
||||
{"a.b.c", new String[]{"a.b.c"}},
|
||||
{"a.b.c", new String[]{"x.y.z", "p.q.r", "x.y.z"}},
|
||||
{"a.b.c", new String[]{new String("a.b.c")}},
|
||||
};
|
||||
}
|
||||
|
||||
private static WebSocket.Listener listener() {
|
||||
return new WebSocket.Listener() { };
|
||||
}
|
||||
|
||||
/* shortcut */
|
||||
public static void assertFails(Class<? extends Throwable> clazz,
|
||||
CompletionStage<?> stage) {
|
||||
Support.assertCompletesExceptionally(clazz, stage);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue