Skip to content

Commit

Permalink
WebSockets Next: detect incorrect path parameter usage
Browse files Browse the repository at this point in the history
- resolves #39182
  • Loading branch information
mkouba committed Mar 15, 2024
1 parent 8713495 commit f17813f
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class WebSocketServerProcessor {
static final String ENDPOINT_SUFFIX = "_WebSocketEndpoint";
static final String NESTED_SEPARATOR = "$_";

// Parameter names consist of alphanumeric characters and underscore
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z0-9_]+\\}");

@BuildStep
Expand Down Expand Up @@ -240,6 +241,14 @@ static String getPath(String path) {
while (m.find()) {
// Replace {foo} with :foo
String match = m.group();
int end = m.end();
if (end < path.length()) {
char nextChar = path.charAt(end);
if (Character.isAlphabetic(nextChar) || Character.isDigit(nextChar) || nextChar == '_') {
throw new WebSocketServerException("Path parameter " + match
+ " may not be followed by an alphanumeric character or underscore: " + path);
}
}
m.appendReplacement(sb, ":" + match.subSequence(1, match.length() - 1));
}
m.appendTail(sb);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
package io.quarkus.websockets.next.deployment;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

import io.quarkus.websockets.next.WebSocketServerException;

public class WebSocketServerProcessorTest {

@Test
public void testGetPath() {
assertEquals("/foo/:id", WebSocketServerProcessor.getPath("/foo/{id}"));
assertEquals("/foo/:id/bar/:id2", WebSocketServerProcessor.getPath("/foo/{id}/bar/{id2}"));
assertEquals("/foo/:bar-:baz", WebSocketServerProcessor.getPath("/foo/{bar}-{baz}"));
assertEquals("/ws/v:version", WebSocketServerProcessor.getPath("/ws/v{version}"));
assertEquals("/foo/v:bar/:bazand:alpha_1-:name",
WebSocketServerProcessor.getPath("/foo/v{bar}/{baz}and{alpha_1}-{name}"));
WebSocketServerException e = assertThrows(WebSocketServerException.class,
() -> WebSocketServerProcessor.getPath("/foo/v{bar}/{baz}and{alpha_1}-{name}"));
assertEquals(
"Path parameter {baz} may not be followed by an alphanumeric character or underscore: /foo/v{bar}/{baz}and{alpha_1}-{name}",
e.getMessage());
e = assertThrows(WebSocketServerException.class,
() -> WebSocketServerProcessor.getPath("/foo/v{bar}/{baz}_{alpha_1}-{name}"));
assertEquals(
"Path parameter {baz} may not be followed by an alphanumeric character or underscore: /foo/v{bar}/{baz}_{alpha_1}-{name}",
e.getMessage());
e = assertThrows(WebSocketServerException.class,
() -> WebSocketServerProcessor.getPath("/foo/v{bar}/{baz}1-{name}"));
assertEquals(
"Path parameter {baz} may not be followed by an alphanumeric character or underscore: /foo/v{bar}/{baz}1-{name}",
e.getMessage());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.quarkus.websockets.next.test.endpoints;

import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.websockets.next.OnOpen;
import io.quarkus.websockets.next.WebSocket;
import io.quarkus.websockets.next.WebSocketServerException;

public class InvalidPathParamTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(InvalidPathParam.class);
})
.setExpectedException(WebSocketServerException.class);

@Test
void testInvalidPathParam() {
fail();
}

@WebSocket(path = "/service/{invalid}_{param}")
public static class InvalidPathParam {

@OnOpen
public void onOpen() {
}

}

}

0 comments on commit f17813f

Please sign in to comment.