Ratpack improve support for parsing types

This commit is contained in:
Jonathan Leitschuh
2021-05-10 16:52:12 -04:00
parent ac185d9bd5
commit a3b1736a73
4 changed files with 200 additions and 2 deletions

View File

@@ -24,13 +24,22 @@ private class RatpackHttpSource extends SourceModelCsv {
"Request;true;getRawUri;;;ReturnValue;remote", "Request;true;getUri;;;ReturnValue;remote",
"Request;true;getBody;;;ReturnValue;remote"
]
or
// All Context#parse methods that return a Promise are remote flow sources.
row =
["ratpack.handling;", "ratpack.core.handling;"] + "Context;true;parse;" +
[
"(java.lang.Class);", "(com.google.common.reflect.TypeToken);", "(java.lang.Class,O);",
"(com.google.common.reflect.TypeToken,O);", "(ratpack.core.parse.Parse);",
"(ratpack.parse.Parse);"
] + ";ReturnValue;remote"
}
}
/**
* Ratpack methods that propagate user-supplied request data as tainted.
*/
private class RatpackHttpModel extends SummaryModelCsv {
private class RatpackModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["ratpack.http;", "ratpack.core.http;"] +
@@ -49,6 +58,24 @@ private class RatpackHttpModel extends SummaryModelCsv {
or
row =
["ratpack.form;", "ratpack.core.form;"] +
["UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint"]
[
"UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint",
"Form;true;file;;;Argument[-1];ReturnValue;taint",
"Form;true;files;;;Argument[-1];ReturnValue;taint"
]
or
row =
["ratpack.handling;", "ratpack.core.handling;"] +
[
"Context;true;parse;(ratpack.http.TypedData,ratpack.parse.Parse);;Argument[0];ReturnValue;taint",
"Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue;taint"
]
or
row =
["ratpack.util;", "ratpack.func;"] +
[
"MultiValueMap;true;getAll;;;Argument[-1];ReturnValue;taint",
"MultiValueMap;true;asMultimap;;;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -1,6 +1,8 @@
import ratpack.core.handling.Context;
import ratpack.core.http.TypedData;
import ratpack.core.form.Form;
import ratpack.core.form.UploadedFile;
import ratpack.core.parse.Parse;
import ratpack.exec.Promise;
import java.io.OutputStream;
@@ -67,4 +69,36 @@ class Resource {
.flatMap(a -> Promise.value(a))
.then(this::sink); //$hasTaintFlow
}
void test5(Context ctx) {
ctx
.getRequest()
.getBody()
.map(data -> {
Form form = ctx.parse(data, Form.form());
sink(form); //$hasTaintFlow
return form;
})
.then(form -> {
sink(form.file("questionable_file")); //$hasTaintFlow
sink(form.file("questionable_file").getFileName()); //$hasTaintFlow
sink(form.files("questionable_files")); //$hasTaintFlow
sink(form.files()); //$hasTaintFlow
sink(form.asMultimap()); //$hasTaintFlow
sink(form.asMultimap().asMap()); //$hasTaintFlow
});
}
void test6(Context ctx) {
ctx
.parse(Parse.of(Form.class))
.then(form -> {
sink(form); //$hasTaintFlow
});
ctx
.parse(Form.class)
.then(form -> {
sink(form); //$hasTaintFlow
});
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ratpack.core.form;
import ratpack.core.handling.Context;
import ratpack.core.parse.Parse;
import ratpack.func.Nullable;
import ratpack.func.MultiValueMap;
import java.util.List;
/**
* An uploaded form.
* <p>
* The form is modelled as a {@link MultiValueMap}, with extra methods for dealing with file uploads.
* That is, uploaded files are not visible via the methods provided by {@link MultiValueMap}.
* <p>
* All instances of this type are <b>immutable</b>.
* Calling any mutative method of {@link MultiValueMap} will result in an {@link UnsupportedOperationException}.
* <h3>Example usage:</h3>
* <pre class="java">{@code
* import ratpack.core.handling.Handler;
* import ratpack.core.handling.Context;
* import ratpack.core.form.Form;
* import ratpack.core.form.UploadedFile;
*
* import java.util.List;
*
* public class Example {
* public static class FormHandler implements Handler {
* public void handle(Context context) throws Exception {
* context.parse(Form.class).then(form -> {
* UploadedFile file = form.file("someFile.txt");
* String param = form.get("param");
* List<String> multi = form.getAll("multi");
* context.render("form uploaded!");
* });
* }
* }
* }
* }</pre>
*
* <p>
* To include the query parameters from the request in the parsed form, use {@link Form#form(boolean)}.
* This can be useful if you want to support both {@code GET} and {@code PUT} submission with a single handler.
*/
public interface Form extends MultiValueMap<String, String> {
/**
* Return the first uploaded file with the given name.
*
* @param name The name of the uploaded file in the form
* @return The uploaded file, or {@code null} if no file was uploaded by that name
*/
@Nullable
UploadedFile file(String name);
/**
* Return all of the uploaded files with the given name.
*
* @param name The name of the uploaded files in the form
* @return The uploaded files, or an empty list if no files were uploaded by that name
*/
List<UploadedFile> files(String name);
/**
* Returns all of the uploaded files.
*
* @return all of the uploaded files.
*/
MultiValueMap<String, UploadedFile> files();
/**
* Creates a {@link Context#parse parseable object} to parse a request body into a {@link Form}.
* <p>
* Default options will be used (no query parameters included).
*
* @return a parse object
*/
static Parse<Form, FormParseOpts> form() {
return null;
}
/**
* Creates a {@link Context#parse parseable object} to parse a request body into a {@link Form}.
*
* @param includeQueryParams whether to include the query parameters from the request in the parsed form
* @return a parse object
*/
static Parse<Form, FormParseOpts> form(boolean includeQueryParams) {
return null;
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ratpack.core.form;
/**
* Options for parsing a {@link Form}.
*/
public interface FormParseOpts {
/**
* Whether to include the query parameters from the request in the parsed form.
*
* @return whether to include the query parameters from the request in the parsed form
*/
boolean isIncludeQueryParams();
}