diff --git a/extensions/websockets-next/server/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessor.java b/extensions/websockets-next/server/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessor.java index fecdd74c0606a..eba1598a6eb6f 100644 --- a/extensions/websockets-next/server/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessor.java +++ b/extensions/websockets-next/server/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessor.java @@ -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 @@ -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); diff --git a/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessorTest.java b/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessorTest.java index 6c774f82c21ce..44e37dc73011d 100644 --- a/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessorTest.java +++ b/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/deployment/WebSocketServerProcessorTest.java @@ -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 diff --git a/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/test/endpoints/InvalidPathParamTest.java b/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/test/endpoints/InvalidPathParamTest.java new file mode 100644 index 0000000000000..264e01f5b01dc --- /dev/null +++ b/extensions/websockets-next/server/deployment/src/test/java/io/quarkus/websockets/next/test/endpoints/InvalidPathParamTest.java @@ -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() { + } + + } + +}