Skip to content

Commit 5a1aacc

Browse files
authored
fix(java/restclient): avoid IndexOutOfBoundsException for empty multipart list params (#23153) (#23314)
1 parent ba08b77 commit 5a1aacc

File tree

13 files changed

+110
-84
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

+110
-84
lines changed

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -846,14 +846,14 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
846846
847847
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
848848
formParams.forEach(
849-
(k, v) -> {
850-
if (v instanceof java.util.ArrayList) {
851-
Object o = v.get(0);
852-
if (o != null && o.getClass().getEnumConstants() != null) {
853-
v.set(0, o.toString());
854-
}
849+
(k, v) -> {
850+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
851+
Object first = v.get(0);
852+
if (first != null && first.getClass().isEnum()) {
853+
v.set(0, first.toString());
855854
}
856-
});
855+
}
856+
});
857857
}
858858
859859
var selectedBody = selectBody(body, formParams, contentType);

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,4 +4211,30 @@ 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")
4215+
public void testRestClientMultipartFormParamsGuardAgainstEmptyLists() {
4216+
final Path output = newTempFolder();
4217+
final CodegenConfigurator configurator = new CodegenConfigurator()
4218+
.setGeneratorName(JAVA_GENERATOR)
4219+
.setLibrary(JavaClientCodegen.RESTCLIENT)
4220+
.setAdditionalProperties(Map.of(CodegenConstants.API_PACKAGE, "xyz.abcdef.api"))
4221+
.setInputSpec("src/test/resources/3_0/form-multipart-binary-array.yaml")
4222+
.setOutputDir(output.toString().replace("\\", "/"));
4223+
4224+
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
4225+
4226+
validateJavaSourceFiles(files);
4227+
4228+
assertFileContains(
4229+
output.resolve("src/main/java/xyz/abcdef/ApiClient.java"),
4230+
"if (v instanceof java.util.ArrayList && !v.isEmpty()) {",
4231+
"first.getClass().isEnum()"
4232+
);
4233+
4234+
TestUtils.assertFileNotContains(
4235+
output.resolve("src/main/java/xyz/abcdef/ApiClient.java"),
4236+
"if (v instanceof java.util.ArrayList) {",
4237+
"o.getClass().getEnumConstants() != null"
4238+
);
4239+
}
42144240
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -724,14 +724,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
724724

725725
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
726726
formParams.forEach(
727-
(k, v) -> {
728-
if (v instanceof java.util.ArrayList) {
729-
Object o = v.get(0);
730-
if (o != null && o.getClass().getEnumConstants() != null) {
731-
v.set(0, o.toString());
732-
}
727+
(k, v) -> {
728+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
729+
Object first = v.get(0);
730+
if (first != null && first.getClass().isEnum()) {
731+
v.set(0, first.toString());
733732
}
734-
});
733+
}
734+
});
735735
}
736736

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,14 +723,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
723723

724724
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
725725
formParams.forEach(
726-
(k, v) -> {
727-
if (v instanceof java.util.ArrayList) {
728-
Object o = v.get(0);
729-
if (o != null && o.getClass().getEnumConstants() != null) {
730-
v.set(0, o.toString());
731-
}
726+
(k, v) -> {
727+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
728+
Object first = v.get(0);
729+
if (first != null && first.getClass().isEnum()) {
730+
v.set(0, first.toString());
732731
}
733-
});
732+
}
733+
});
734734
}
735735

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724724
formParams.forEach(
725-
(k, v) -> {
726-
if (v instanceof java.util.ArrayList) {
727-
Object o = v.get(0);
728-
if (o != null && o.getClass().getEnumConstants() != null) {
729-
v.set(0, o.toString());
730-
}
725+
(k, v) -> {
726+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
727+
Object first = v.get(0);
728+
if (first != null && first.getClass().isEnum()) {
729+
v.set(0, first.toString());
731730
}
732-
});
731+
}
732+
});
733733
}
734734

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724724
formParams.forEach(
725-
(k, v) -> {
726-
if (v instanceof java.util.ArrayList) {
727-
Object o = v.get(0);
728-
if (o != null && o.getClass().getEnumConstants() != null) {
729-
v.set(0, o.toString());
730-
}
725+
(k, v) -> {
726+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
727+
Object first = v.get(0);
728+
if (first != null && first.getClass().isEnum()) {
729+
v.set(0, first.toString());
731730
}
732-
});
731+
}
732+
});
733733
}
734734

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
722722

723723
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
724724
formParams.forEach(
725-
(k, v) -> {
726-
if (v instanceof java.util.ArrayList) {
727-
Object o = v.get(0);
728-
if (o != null && o.getClass().getEnumConstants() != null) {
729-
v.set(0, o.toString());
730-
}
725+
(k, v) -> {
726+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
727+
Object first = v.get(0);
728+
if (first != null && first.getClass().isEnum()) {
729+
v.set(0, first.toString());
731730
}
732-
});
731+
}
732+
});
733733
}
734734

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -748,14 +748,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
748748

749749
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
750750
formParams.forEach(
751-
(k, v) -> {
752-
if (v instanceof java.util.ArrayList) {
753-
Object o = v.get(0);
754-
if (o != null && o.getClass().getEnumConstants() != null) {
755-
v.set(0, o.toString());
756-
}
751+
(k, v) -> {
752+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
753+
Object first = v.get(0);
754+
if (first != null && first.getClass().isEnum()) {
755+
v.set(0, first.toString());
757756
}
758-
});
757+
}
758+
});
759759
}
760760

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -741,14 +741,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
741741

742742
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
743743
formParams.forEach(
744-
(k, v) -> {
745-
if (v instanceof java.util.ArrayList) {
746-
Object o = v.get(0);
747-
if (o != null && o.getClass().getEnumConstants() != null) {
748-
v.set(0, o.toString());
749-
}
744+
(k, v) -> {
745+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
746+
Object first = v.get(0);
747+
if (first != null && first.getClass().isEnum()) {
748+
v.set(0, first.toString());
750749
}
751-
});
750+
}
751+
});
752752
}
753753

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

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,14 +795,14 @@ protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod meth
795795

796796
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
797797
formParams.forEach(
798-
(k, v) -> {
799-
if (v instanceof java.util.ArrayList) {
800-
Object o = v.get(0);
801-
if (o != null && o.getClass().getEnumConstants() != null) {
802-
v.set(0, o.toString());
803-
}
798+
(k, v) -> {
799+
if (v instanceof java.util.ArrayList && !v.isEmpty()) {
800+
Object first = v.get(0);
801+
if (first != null && first.getClass().isEnum()) {
802+
v.set(0, first.toString());
804803
}
805-
});
804+
}
805+
});
806806
}
807807

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

0 commit comments

Comments
 (0)