Skip to content

Commit b6cfb75

Browse files
committed
APT: fileupload + path injection
1 parent ae799df commit b6cfb75

File tree

13 files changed

+346
-105
lines changed

13 files changed

+346
-105
lines changed

jooby/src/main/java/io/jooby/Context.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,7 @@ public interface Context extends Registry {
492492
/**
493493
* Get a multipart field that matches the given name.
494494
*
495-
* File upload retrieval is available using {@link Value#fileUpload()} or consider using the
496-
* {@link #file(String)} instead.
495+
* File upload retrieval is available using {@link Context#file(String)}.
497496
*
498497
* Only for <code>multipart/form-data</code> request.
499498
*

jooby/src/main/java/io/jooby/DefaultContext.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.nio.file.Path;
2525
import java.time.Instant;
2626
import java.util.ArrayList;
27+
import java.util.Collections;
2728
import java.util.Date;
2829
import java.util.List;
2930
import java.util.Map;
@@ -277,23 +278,34 @@ public interface DefaultContext extends Context {
277278
List<FileUpload> result = new ArrayList<>();
278279
for (Value value : multipart) {
279280
if (value.isUpload()) {
280-
result.add(value.fileUpload());
281+
result.add((FileUpload) value);
281282
}
282283
}
283284
return result;
284285
}
285286

286287
@Override @Nonnull default List<FileUpload> files(@Nonnull String name) {
287288
Value multipart = multipart(name);
289+
if (multipart instanceof FileUpload) {
290+
return Collections.singletonList((FileUpload) multipart);
291+
}
288292
List<FileUpload> result = new ArrayList<>();
289293
for (Value value : multipart) {
290-
result.add(value.fileUpload());
294+
if (value instanceof FileUpload) {
295+
result.add((FileUpload) value);
296+
} else {
297+
throw new TypeMismatchException(name, FileUpload.class);
298+
}
291299
}
292300
return result;
293301
}
294302

295303
@Override @Nonnull default FileUpload file(@Nonnull String name) {
296-
return multipart(name).fileUpload();
304+
Value value = multipart(name);
305+
if (value instanceof FileUpload) {
306+
return (FileUpload) value;
307+
}
308+
throw new TypeMismatchException(name, FileUpload.class);
297309
}
298310

299311
@Override default @Nonnull <T> T body(@Nonnull Reified<T> type) {

jooby/src/main/java/io/jooby/FileUpload.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.nio.file.Path;
1616
import java.util.Collections;
1717
import java.util.HashMap;
18+
import java.util.Iterator;
1819
import java.util.List;
1920
import java.util.Map;
2021

@@ -63,6 +64,11 @@ public interface FileUpload extends Value {
6364
return 1;
6465
}
6566

67+
@Nonnull @Override default Iterator<Value> iterator() {
68+
Iterator iterator = Collections.singletonList(this).iterator();
69+
return iterator;
70+
}
71+
6672
@Override default @Nonnull String value() {
6773
return value(StandardCharsets.UTF_8);
6874
}
@@ -116,10 +122,6 @@ public interface FileUpload extends Value {
116122
*/
117123
long getFileSize();
118124

119-
@Override default FileUpload fileUpload() {
120-
return this;
121-
}
122-
123125
/**
124126
* Free resources, delete temporary file.
125127
*/

jooby/src/main/java/io/jooby/Formdata.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import javax.annotation.Nonnull;
1111
import java.util.Collection;
12+
import java.util.List;
1213

1314
/**
1415
* Formdata class for direct MVC parameter provisioning.

jooby/src/main/java/io/jooby/Value.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,6 @@ default boolean isMissing() {
392392
return to(Reified.optional(type));
393393
}
394394

395-
/**
396-
* Get a file upload from this value.
397-
*
398-
* @return A file upload.
399-
*/
400-
default FileUpload fileUpload() {
401-
throw new TypeMismatchException(name(), FileUpload.class);
402-
}
403-
404395
/* ***********************************************************************************************
405396
* Node methods
406397
* ***********************************************************************************************

jooby/src/main/java/io/jooby/internal/mvc/MvcCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ private static void tryParamBlock(MvcMethod method, MethodVisitor visitor, Param
442442
true);
443443
} else if (paramClass == FlashMap.class) {
444444
visitor
445-
.visitMethodInsn(INVOKEINTERFACE, CTX_INTERNAL, "flashMap", "()Lio/jooby/FlashMap;",
445+
.visitMethodInsn(INVOKEINTERFACE, CTX_INTERNAL, "flash", "()Lio/jooby/FlashMap;",
446446
true);
447447
} else {
448448
String source;

jooby/src/test/java/io/jooby/internal/mvc/MvcHandlerASM.java

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.jooby.internal.mvc;
22

33
import io.jooby.Context;
4+
import io.jooby.FileUpload;
45
import io.jooby.ProvisioningException;
56
import io.jooby.QueryString;
67
import io.jooby.Reified;
@@ -33,8 +34,8 @@ class Poc {
3334

3435
@POST
3536
@Path(("/body/json"))
36-
public String getIt(@PathParam Integer p1) {
37-
return p1.toString();
37+
public String getIt(java.nio.file.Path file) {
38+
return file.toString();
3839
}
3940

4041
@GET
@@ -53,22 +54,27 @@ public MvcHandlerImpl(Provider<Poc> provider) {
5354
this.provider = provider;
5455
}
5556

56-
// private double tryParam0(Context ctx, String desc) {
57-
// try {
58-
// return ctx.path("l").doubleValue();
59-
// } catch (ProvisioningException x) {
60-
// throw x;
61-
// } catch (Exception x) {
62-
// throw new ProvisioningException(desc, x);
63-
// }
64-
// }
65-
//
57+
// private double tryParam0(Context ctx, String desc) {
58+
// try {
59+
// return ctx.path("l").doubleValue();
60+
// } catch (ProvisioningException x) {
61+
// throw x;
62+
// } catch (Exception x) {
63+
// throw new ProvisioningException(desc, x);
64+
// }
65+
// }
66+
//
6667
public final Object[] arguments(Context ctx) {
6768
return null;
6869
}
6970

7071
@Nonnull @Override public Object apply(@Nonnull Context ctx) throws Exception {
71-
return provider.get().getIt(ctx.path("p1").to(Integer.class));
72+
return provider.get().getIt(ctx.file("xxx").path());
73+
}
74+
75+
private static java.nio.file.Path path(Context ctx) {
76+
FileUpload upload = ctx.file("xxx");
77+
return upload.path();
7278
}
7379
}
7480

@@ -78,9 +84,9 @@ public class MvcHandlerASM {
7884
public void compare() throws IOException, NoSuchMethodException, ClassNotFoundException {
7985
// Lio/jooby/SneakyThrows$Supplier<Lio/jooby/mvc/NoTopLevelPath;>;
8086
// ASMifier.main(new String[] {"-debug",MvcHandler.class.getName()});
81-
//public String mix(@PathParam String s, @PathParam Integer i, @PathParam double d, Context ctx,
87+
//public String mix(@PathParam String s, @PathParam Integer i, @PathParam double d, Context ctx,
8288
// @PathParam long j, @PathParam double f, @PathParam boolean b) {
83-
Method handler = Poc.class.getDeclaredMethod("getIt", Integer.class);
89+
Method handler = Poc.class.getDeclaredMethod("getIt", java.nio.file.Path.class);
8490
Class runtime = MvcCompiler.compileClass(mvc(handler));
8591

8692
System.out.println("Loaded: " + runtime);

modules/jooby-mvc-compiler/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@
8080
<groupId>io.jooby</groupId>
8181
<artifactId>jooby-test</artifactId>
8282
<version>${jooby.version}</version>
83+
<scope>test</scope>
84+
</dependency>
85+
86+
<dependency>
87+
<groupId>org.mockito</groupId>
88+
<artifactId>mockito-core</artifactId>
89+
<scope>test</scope>
8390
</dependency>
8491
</dependencies>
8592

0 commit comments

Comments
 (0)