Skip to content

Commit 846d0bb

Browse files
committed
Don't assume that multipart part without filename is text
Fixes: quarkusio#38703
1 parent 45e6c57 commit 846d0bb

File tree

4 files changed

+87
-10
lines changed

4 files changed

+87
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package io.quarkus.resteasy.reactive.server.test.multipart;
2+
3+
import static io.restassured.RestAssured.given;
4+
import static org.assertj.core.api.Assertions.assertThat;
5+
6+
import java.io.File;
7+
import java.io.IOException;
8+
import java.nio.file.Files;
9+
import java.util.function.Supplier;
10+
11+
import jakarta.ws.rs.POST;
12+
import jakarta.ws.rs.Path;
13+
import jakarta.ws.rs.core.MediaType;
14+
15+
import org.jboss.resteasy.reactive.PartType;
16+
import org.jboss.resteasy.reactive.RestForm;
17+
import org.jboss.shrinkwrap.api.ShrinkWrap;
18+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.api.extension.RegisterExtension;
21+
22+
import io.quarkus.test.QuarkusUnitTest;
23+
24+
public class MultipartBinaryWithoutFilenameTest {
25+
26+
@RegisterExtension
27+
static QuarkusUnitTest test = new QuarkusUnitTest()
28+
.setArchiveProducer(new Supplier<>() {
29+
@Override
30+
public JavaArchive get() {
31+
return ShrinkWrap.create(JavaArchive.class)
32+
.addClasses(MultipartDataInputTest.Resource.class, MultipartDataInputTest.Item.class,
33+
MultipartDataInputTest.Result.class);
34+
}
35+
});
36+
private final File IMAGE_FILE = new File("./src/test/resources/image.png");
37+
38+
@Test
39+
public void test() throws IOException {
40+
byte[] bytes = given()
41+
.contentType("multipart/form-data")
42+
.multiPart("bytes", IMAGE_FILE, "application/png")
43+
.when()
44+
.post("/test")
45+
.then()
46+
.statusCode(200)
47+
.extract().body().asByteArray();
48+
49+
assertThat(bytes).isEqualTo(Files.readAllBytes(IMAGE_FILE.toPath()));
50+
}
51+
52+
@Path("/test")
53+
public static class Resource {
54+
55+
@POST
56+
public byte[] testMultipart(Input input) {
57+
return input.bytes;
58+
}
59+
}
60+
61+
public static class Input {
62+
@RestForm("bytes")
63+
@PartType(MediaType.APPLICATION_OCTET_STREAM)
64+
public byte[] bytes;
65+
66+
}
67+
}

independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java

+13-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import jakarta.ws.rs.WebApplicationException;
2424
import jakarta.ws.rs.container.CompletionCallback;
2525
import jakarta.ws.rs.core.HttpHeaders;
26+
import jakarta.ws.rs.core.MediaType;
2627
import jakarta.ws.rs.core.Response;
2728

2829
import org.jboss.logging.Logger;
@@ -339,20 +340,24 @@ public void endPart() {
339340
contentBytes.reset();
340341
} else {
341342

342-
try {
343-
String charset = defaultEncoding;
344-
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
345-
if (contentType != null) {
343+
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
344+
if ((contentType != null) && !contentType.isEmpty()
345+
&& MediaType.TEXT_PLAIN_TYPE.isCompatible(MediaType.valueOf(contentType))) {
346+
try {
347+
String charset = defaultEncoding;
346348
String cs = HeaderUtil.extractQuotedValueFromHeader(contentType, "charset");
347349
if (cs != null) {
348350
charset = cs;
349351
}
350-
}
351352

352-
data.add(currentName, contentBytes.toString(charset), charset, headers);
353-
} catch (UnsupportedEncodingException e) {
354-
throw new RuntimeException(e);
353+
data.add(currentName, contentBytes.toString(charset), charset, headers);
354+
} catch (UnsupportedEncodingException e) {
355+
throw new RuntimeException(e);
356+
}
357+
} else {
358+
data.add(currentName, Arrays.copyOf(contentBytes.toByteArray(), contentBytes.size()), null, headers);
355359
}
360+
356361
contentBytes.reset();
357362
}
358363
}

independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartSupport.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;
3131
import org.jboss.resteasy.reactive.server.core.ServerSerialisers;
3232
import org.jboss.resteasy.reactive.server.handlers.RequestDeserializeHandler;
33+
import org.jboss.resteasy.reactive.server.multipart.FileItem;
3334
import org.jboss.resteasy.reactive.server.multipart.FormValue;
3435
import org.jboss.resteasy.reactive.server.multipart.MultipartFormDataInput;
3536
import org.jboss.resteasy.reactive.server.multipart.MultipartPartReadingException;
@@ -90,7 +91,7 @@ private static Object read(MessageBodyReader<?> reader, String attributeName, Fo
9091
@Override
9192
public InputStream get() {
9293
try {
93-
return Files.newInputStream(value.getFileItem().getFile());
94+
return value.getFileItem().getInputStream();
9495
} catch (IOException e) {
9596
throw new UncheckedIOException(e);
9697
}
@@ -248,7 +249,11 @@ public static byte[] getByteArray(String formName, ResteasyReactiveRequestContex
248249
}
249250
if (value.isFileItem()) {
250251
try {
251-
return Files.readAllBytes(value.getFileItem().getFile());
252+
FileItem fileItem = value.getFileItem();
253+
if (fileItem.isInMemory()) {
254+
return fileItem.getInputStream().readAllBytes();
255+
}
256+
return Files.readAllBytes(fileItem.getFile());
252257
} catch (IOException e) {
253258
throw new MultipartPartReadingException(e);
254259
}

0 commit comments

Comments
 (0)