@@ -878,6 +878,88 @@ Call<ResponseBody> method(@Path(value = "ping", encoded = true) String ping) {
878
878
assertThat (request .body ()).isNull ();
879
879
}
880
880
881
+ @ Test public void pathParametersAndPathTraversal () {
882
+ class Example {
883
+ @ GET ("/foo/bar/{ping}/" ) //
884
+ Call <ResponseBody > method (@ Path (value = "ping" ) String ping ) {
885
+ return null ;
886
+ }
887
+ }
888
+
889
+ assertMalformedRequest (Example .class , "." );
890
+ assertMalformedRequest (Example .class , ".." );
891
+
892
+ assertThat (buildRequest (Example .class , "./a" ).url ().encodedPath ())
893
+ .isEqualTo ("/foo/bar/.%2Fa/" );
894
+ assertThat (buildRequest (Example .class , "a/." ).url ().encodedPath ())
895
+ .isEqualTo ("/foo/bar/a%2F./" );
896
+ assertThat (buildRequest (Example .class , "a/.." ).url ().encodedPath ())
897
+ .isEqualTo ("/foo/bar/a%2F../" );
898
+ assertThat (buildRequest (Example .class , "../a" ).url ().encodedPath ())
899
+ .isEqualTo ("/foo/bar/..%2Fa/" );
900
+ assertThat (buildRequest (Example .class , "..\\ .." ).url ().encodedPath ())
901
+ .isEqualTo ("/foo/bar/..%5C../" );
902
+
903
+ assertThat (buildRequest (Example .class , "%2E" ).url ().encodedPath ())
904
+ .isEqualTo ("/foo/bar/%252E/" );
905
+ assertThat (buildRequest (Example .class , "%2E%2E" ).url ().encodedPath ())
906
+ .isEqualTo ("/foo/bar/%252E%252E/" );
907
+ }
908
+
909
+ @ Test public void encodedPathParametersAndPathTraversal () {
910
+ class Example {
911
+ @ GET ("/foo/bar/{ping}/" ) //
912
+ Call <ResponseBody > method (@ Path (value = "ping" , encoded = true ) String ping ) {
913
+ return null ;
914
+ }
915
+ }
916
+
917
+ assertMalformedRequest (Example .class , "." );
918
+ assertMalformedRequest (Example .class , "%2E" );
919
+ assertMalformedRequest (Example .class , "%2e" );
920
+ assertMalformedRequest (Example .class , ".." );
921
+ assertMalformedRequest (Example .class , "%2E." );
922
+ assertMalformedRequest (Example .class , "%2e." );
923
+ assertMalformedRequest (Example .class , ".%2E" );
924
+ assertMalformedRequest (Example .class , ".%2e" );
925
+ assertMalformedRequest (Example .class , "%2E%2e" );
926
+ assertMalformedRequest (Example .class , "%2e%2E" );
927
+ assertMalformedRequest (Example .class , "./a" );
928
+ assertMalformedRequest (Example .class , "a/." );
929
+ assertMalformedRequest (Example .class , "../a" );
930
+ assertMalformedRequest (Example .class , "a/.." );
931
+ assertMalformedRequest (Example .class , "a/../b" );
932
+ assertMalformedRequest (Example .class , "a/%2e%2E/b" );
933
+
934
+ assertThat (buildRequest (Example .class , "..." ).url ().encodedPath ())
935
+ .isEqualTo ("/foo/bar/.../" );
936
+ assertThat (buildRequest (Example .class , "a..b" ).url ().encodedPath ())
937
+ .isEqualTo ("/foo/bar/a..b/" );
938
+ assertThat (buildRequest (Example .class , "a.." ).url ().encodedPath ())
939
+ .isEqualTo ("/foo/bar/a../" );
940
+ assertThat (buildRequest (Example .class , "a..b" ).url ().encodedPath ())
941
+ .isEqualTo ("/foo/bar/a..b/" );
942
+ assertThat (buildRequest (Example .class , "..b" ).url ().encodedPath ())
943
+ .isEqualTo ("/foo/bar/..b/" );
944
+ assertThat (buildRequest (Example .class , "..\\ .." ).url ().encodedPath ())
945
+ .isEqualTo ("/foo/bar/..%5C../" );
946
+ }
947
+
948
+ @ Test public void dotDotsOkayWhenNotFullPathSegment () {
949
+ class Example {
950
+ @ GET ("/foo{ping}bar/" ) //
951
+ Call <ResponseBody > method (@ Path (value = "ping" , encoded = true ) String ping ) {
952
+ return null ;
953
+ }
954
+ }
955
+
956
+ assertMalformedRequest (Example .class , "/./" );
957
+ assertMalformedRequest (Example .class , "/../" );
958
+
959
+ assertThat (buildRequest (Example .class , "." ).url ().encodedPath ()).isEqualTo ("/foo.bar/" );
960
+ assertThat (buildRequest (Example .class , ".." ).url ().encodedPath ()).isEqualTo ("/foo..bar/" );
961
+ }
962
+
881
963
@ Test public void pathParamRequired () {
882
964
class Example {
883
965
@ GET ("/foo/bar/{ping}/" ) //
@@ -2783,4 +2865,12 @@ static <T> Request buildRequest(Class<T> cls, Object... args) {
2783
2865
2784
2866
return buildRequest (cls , retrofitBuilder , args );
2785
2867
}
2868
+
2869
+ static void assertMalformedRequest (Class <?> cls , Object ... args ) {
2870
+ try {
2871
+ Request request = buildRequest (cls , args );
2872
+ fail ("expected a malformed request but was " + request );
2873
+ } catch (IllegalArgumentException expected ) {
2874
+ }
2875
+ }
2786
2876
}
0 commit comments