diff --git a/httpclient5-jakarta-rest-client/src/main/java/org/apache/hc/client5/http/rest/RestInvocationHandler.java b/httpclient5-jakarta-rest-client/src/main/java/org/apache/hc/client5/http/rest/RestInvocationHandler.java index c40e9829d7..5df10f7e18 100644 --- a/httpclient5-jakarta-rest-client/src/main/java/org/apache/hc/client5/http/rest/RestInvocationHandler.java +++ b/httpclient5-jakarta-rest-client/src/main/java/org/apache/hc/client5/http/rest/RestInvocationHandler.java @@ -129,6 +129,8 @@ private Object executeRequest(final ResourceMethod rm, switch (param.getType()) { case PATH: Args.check(paramValue != null, "Path parameter '%s' must not be null", param.getName()); + Args.check(!".".equals(paramValue) && !"..".equals(paramValue), + "Path parameter '%s' must not be a '.' or '..' segment", param.getName()); pathParams.put(paramName, paramValue); break; case QUERY: diff --git a/httpclient5-jakarta-rest-client/src/test/java/org/apache/hc/client5/http/rest/RestClientBuilderTest.java b/httpclient5-jakarta-rest-client/src/test/java/org/apache/hc/client5/http/rest/RestClientBuilderTest.java index 1db236e1bf..f5dc1c6713 100644 --- a/httpclient5-jakarta-rest-client/src/test/java/org/apache/hc/client5/http/rest/RestClientBuilderTest.java +++ b/httpclient5-jakarta-rest-client/src/test/java/org/apache/hc/client5/http/rest/RestClientBuilderTest.java @@ -721,6 +721,14 @@ void testNullPathParamThrows() { assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> api.echoPath(null)); } + @Test + void testDotSegmentPathParamThrows() { + final EchoPathApi api = proxy(EchoPathApi.class); + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> api.echoPath("..")); + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> api.echoPath(".")); + assertThat(api.echoPath("..a")).isEqualTo("..a"); + } + @Test void testQueryParamSpaceEncodedAsPercent20() { final EchoApi api = proxy(EchoApi.class);