Skip to content

Commit c0eaf2b

Browse files
committed
fix(java/restclient): review creating a normalized copy instead of modifying original list (#23153)
1 parent 176fe27 commit c0eaf2b

File tree

13 files changed

+125
-78
lines changed
  • modules/openapi-generator/src
  • samples/client
    • echo_api/java/restclient/src/main/java/org/openapitools/client
    • others/java
      • restclient-enum-in-multipart/src/main/java/org/openapitools/client
      • restclient-sealedInterface/src/main/java/org/openapitools/client
      • restclient-useAbstractionForFiles/src/main/java/org/openapitools/client
    • petstore/java
      • restclient-nullable-arrays/src/main/java/org/openapitools/client
      • restclient-springBoot4-jackson2/src/main/java/org/openapitools/client
      • restclient-springBoot4-jackson3/src/main/java/org/openapitools/client
      • restclient-swagger2/src/main/java/org/openapitools/client
      • restclient-useSingleRequestParameter-static/src/main/java/org/openapitools/client
      • restclient-useSingleRequestParameter/src/main/java/org/openapitools/client
      • restclient/src/main/java/org/openapitools/client

13 files changed

+125
-78
lines changed

modules/openapi-generator/src/main/resources/Java/libraries/restclient/ApiClient.mustache

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -845,20 +845,24 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
845845
addCookiesToRequest(defaultCookies, requestBuilder);
846846
847847
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
848+
Map<String, Object> normalizedParams = new HashMap<>();
848849
formParams.forEach((k, v) -> {
850+
Object normalizedValue = v;
849851
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
850-
List<Object> list = (List<Object>) v;
852+
List<?> list = (List<?>) v;
851853
Object first = list.get(0);
852854
if (first != null && first.getClass().isEnum()) {
853-
for (int i = 0; i < list.size(); i++) {
854-
Object item = list.get(i);
855-
if (item != null) {
856-
list.set(i, item.toString());
857-
}
855+
List<Object> normalized = new ArrayList<>(list.size());
856+
for (Object item : list) {
857+
normalized.add(item != null ? item.toString() : null);
858858
}
859+
normalizedValue = normalized;
859860
}
860861
}
862+
normalizedParams.put(k, normalizedValue);
861863
});
864+
formParams.clear();
865+
formParams.putAll(normalizedParams);
862866
}
863867
864868
var selectedBody = selectBody(body, formParams, contentType);

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,7 +4211,7 @@ public void testFeignHc5CustomTemplateDirIsPreserved() {
42114211
"feign-hc5 must preserve a user-provided templateDir and not overwrite it with 'feign'");
42124212
}
42134213

4214-
@Test(description = "Regression test for multipart/form-data list handling in restclient ApiClient to avoid IndexOutOfBoundsException on empty lists")
4214+
@Test(description = "Regression test for restclient multipart form list normalization")
42154215
public void testRestClientMultipartFormParamsGuardAgainstEmptyLists() {
42164216
final Path output = newTempFolder();
42174217
final CodegenConfigurator configurator = new CodegenConfigurator()
@@ -4228,13 +4228,12 @@ public void testRestClientMultipartFormParamsGuardAgainstEmptyLists() {
42284228
assertFileContains(
42294229
output.resolve("src/main/java/xyz/abcdef/ApiClient.java"),
42304230
"if (v instanceof List<?> && !((List<?>) v).isEmpty()) {",
4231-
"List<Object> list = (List<Object>) v;",
4231+
"List<?> list = (List<?>) v;",
42324232
"Object first = list.get(0);",
42334233
"if (first != null && first.getClass().isEnum()) {",
4234-
"for (int i = 0; i < list.size(); i++) {",
4235-
"Object item = list.get(i);",
4236-
"if (item != null) {",
4237-
"list.set(i, item.toString());"
4234+
"List<Object> normalized = new ArrayList<>(list.size());",
4235+
"for (Object item : list) {",
4236+
"normalized.add(item != null ? item.toString() : null);"
42384237
);
42394238

42404239
TestUtils.assertFileNotContains(

samples/client/echo_api/java/restclient/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -723,20 +723,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
723723
addCookiesToRequest(defaultCookies, requestBuilder);
724724

725725
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
726+
Map<String, Object> normalizedParams = new HashMap<>();
726727
formParams.forEach((k, v) -> {
728+
Object normalizedValue = v;
727729
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
728-
List<Object> list = (List<Object>) v;
730+
List<?> list = (List<?>) v;
729731
Object first = list.get(0);
730732
if (first != null && first.getClass().isEnum()) {
731-
for (int i = 0; i < list.size(); i++) {
732-
Object item = list.get(i);
733-
if (item != null) {
734-
list.set(i, item.toString());
735-
}
733+
List<Object> normalized = new ArrayList<>(list.size());
734+
for (Object item : list) {
735+
normalized.add(item != null ? item.toString() : null);
736736
}
737+
normalizedValue = normalized;
737738
}
738739
}
740+
normalizedParams.put(k, normalizedValue);
739741
});
742+
formParams.clear();
743+
formParams.putAll(normalizedParams);
740744
}
741745

742746
var selectedBody = selectBody(body, formParams, contentType);

samples/client/others/java/restclient-enum-in-multipart/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -722,20 +722,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
722722
addCookiesToRequest(defaultCookies, requestBuilder);
723723

724724
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
725+
Map<String, Object> normalizedParams = new HashMap<>();
725726
formParams.forEach((k, v) -> {
727+
Object normalizedValue = v;
726728
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
727-
List<Object> list = (List<Object>) v;
729+
List<?> list = (List<?>) v;
728730
Object first = list.get(0);
729731
if (first != null && first.getClass().isEnum()) {
730-
for (int i = 0; i < list.size(); i++) {
731-
Object item = list.get(i);
732-
if (item != null) {
733-
list.set(i, item.toString());
734-
}
732+
List<Object> normalized = new ArrayList<>(list.size());
733+
for (Object item : list) {
734+
normalized.add(item != null ? item.toString() : null);
735735
}
736+
normalizedValue = normalized;
736737
}
737738
}
739+
normalizedParams.put(k, normalizedValue);
738740
});
741+
formParams.clear();
742+
formParams.putAll(normalizedParams);
739743
}
740744

741745
var selectedBody = selectBody(body, formParams, contentType);

samples/client/others/java/restclient-sealedInterface/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,20 +721,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
721721
addCookiesToRequest(defaultCookies, requestBuilder);
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724+
Map<String, Object> normalizedParams = new HashMap<>();
724725
formParams.forEach((k, v) -> {
726+
Object normalizedValue = v;
725727
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
726-
List<Object> list = (List<Object>) v;
728+
List<?> list = (List<?>) v;
727729
Object first = list.get(0);
728730
if (first != null && first.getClass().isEnum()) {
729-
for (int i = 0; i < list.size(); i++) {
730-
Object item = list.get(i);
731-
if (item != null) {
732-
list.set(i, item.toString());
733-
}
731+
List<Object> normalized = new ArrayList<>(list.size());
732+
for (Object item : list) {
733+
normalized.add(item != null ? item.toString() : null);
734734
}
735+
normalizedValue = normalized;
735736
}
736737
}
738+
normalizedParams.put(k, normalizedValue);
737739
});
740+
formParams.clear();
741+
formParams.putAll(normalizedParams);
738742
}
739743

740744
var selectedBody = selectBody(body, formParams, contentType);

samples/client/others/java/restclient-useAbstractionForFiles/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,20 +721,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
721721
addCookiesToRequest(defaultCookies, requestBuilder);
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724+
Map<String, Object> normalizedParams = new HashMap<>();
724725
formParams.forEach((k, v) -> {
726+
Object normalizedValue = v;
725727
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
726-
List<Object> list = (List<Object>) v;
728+
List<?> list = (List<?>) v;
727729
Object first = list.get(0);
728730
if (first != null && first.getClass().isEnum()) {
729-
for (int i = 0; i < list.size(); i++) {
730-
Object item = list.get(i);
731-
if (item != null) {
732-
list.set(i, item.toString());
733-
}
731+
List<Object> normalized = new ArrayList<>(list.size());
732+
for (Object item : list) {
733+
normalized.add(item != null ? item.toString() : null);
734734
}
735+
normalizedValue = normalized;
735736
}
736737
}
738+
normalizedParams.put(k, normalizedValue);
737739
});
740+
formParams.clear();
741+
formParams.putAll(normalizedParams);
738742
}
739743

740744
var selectedBody = selectBody(body, formParams, contentType);

samples/client/petstore/java/restclient-nullable-arrays/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,20 +721,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
721721
addCookiesToRequest(defaultCookies, requestBuilder);
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724+
Map<String, Object> normalizedParams = new HashMap<>();
724725
formParams.forEach((k, v) -> {
726+
Object normalizedValue = v;
725727
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
726-
List<Object> list = (List<Object>) v;
728+
List<?> list = (List<?>) v;
727729
Object first = list.get(0);
728730
if (first != null && first.getClass().isEnum()) {
729-
for (int i = 0; i < list.size(); i++) {
730-
Object item = list.get(i);
731-
if (item != null) {
732-
list.set(i, item.toString());
733-
}
731+
List<Object> normalized = new ArrayList<>(list.size());
732+
for (Object item : list) {
733+
normalized.add(item != null ? item.toString() : null);
734734
}
735+
normalizedValue = normalized;
735736
}
736737
}
738+
normalizedParams.put(k, normalizedValue);
737739
});
740+
formParams.clear();
741+
formParams.putAll(normalizedParams);
738742
}
739743

740744
var selectedBody = selectBody(body, formParams, contentType);

samples/client/petstore/java/restclient-springBoot4-jackson2/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -747,20 +747,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
747747
addCookiesToRequest(defaultCookies, requestBuilder);
748748

749749
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
750+
Map<String, Object> normalizedParams = new HashMap<>();
750751
formParams.forEach((k, v) -> {
752+
Object normalizedValue = v;
751753
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
752-
List<Object> list = (List<Object>) v;
754+
List<?> list = (List<?>) v;
753755
Object first = list.get(0);
754756
if (first != null && first.getClass().isEnum()) {
755-
for (int i = 0; i < list.size(); i++) {
756-
Object item = list.get(i);
757-
if (item != null) {
758-
list.set(i, item.toString());
759-
}
757+
List<Object> normalized = new ArrayList<>(list.size());
758+
for (Object item : list) {
759+
normalized.add(item != null ? item.toString() : null);
760760
}
761+
normalizedValue = normalized;
761762
}
762763
}
764+
normalizedParams.put(k, normalizedValue);
763765
});
766+
formParams.clear();
767+
formParams.putAll(normalizedParams);
764768
}
765769

766770
var selectedBody = selectBody(body, formParams, contentType);

samples/client/petstore/java/restclient-springBoot4-jackson3/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -740,20 +740,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
740740
addCookiesToRequest(defaultCookies, requestBuilder);
741741

742742
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
743+
Map<String, Object> normalizedParams = new HashMap<>();
743744
formParams.forEach((k, v) -> {
745+
Object normalizedValue = v;
744746
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
745-
List<Object> list = (List<Object>) v;
747+
List<?> list = (List<?>) v;
746748
Object first = list.get(0);
747749
if (first != null && first.getClass().isEnum()) {
748-
for (int i = 0; i < list.size(); i++) {
749-
Object item = list.get(i);
750-
if (item != null) {
751-
list.set(i, item.toString());
752-
}
750+
List<Object> normalized = new ArrayList<>(list.size());
751+
for (Object item : list) {
752+
normalized.add(item != null ? item.toString() : null);
753753
}
754+
normalizedValue = normalized;
754755
}
755756
}
757+
normalizedParams.put(k, normalizedValue);
756758
});
759+
formParams.clear();
760+
formParams.putAll(normalizedParams);
757761
}
758762

759763
var selectedBody = selectBody(body, formParams, contentType);

samples/client/petstore/java/restclient-swagger2/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -794,20 +794,24 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
794794
addCookiesToRequest(defaultCookies, requestBuilder);
795795

796796
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
797+
Map<String, Object> normalizedParams = new HashMap<>();
797798
formParams.forEach((k, v) -> {
799+
Object normalizedValue = v;
798800
if (v instanceof List<?> && !((List<?>) v).isEmpty()) {
799-
List<Object> list = (List<Object>) v;
801+
List<?> list = (List<?>) v;
800802
Object first = list.get(0);
801803
if (first != null && first.getClass().isEnum()) {
802-
for (int i = 0; i < list.size(); i++) {
803-
Object item = list.get(i);
804-
if (item != null) {
805-
list.set(i, item.toString());
806-
}
804+
List<Object> normalized = new ArrayList<>(list.size());
805+
for (Object item : list) {
806+
normalized.add(item != null ? item.toString() : null);
807807
}
808+
normalizedValue = normalized;
808809
}
809810
}
811+
normalizedParams.put(k, normalizedValue);
810812
});
813+
formParams.clear();
814+
formParams.putAll(normalizedParams);
811815
}
812816

813817
var selectedBody = selectBody(body, formParams, contentType);

0 commit comments

Comments
 (0)