Skip to content

Commit

Permalink
[RESTEASY-2100] - The byte[] type of input parameter in proxy/MP-rest…
Browse files Browse the repository at this point in the history
…-client will cause large JVM stack used.
  • Loading branch information
MMarus authored and asoldano committed Feb 12, 2019
1 parent 6f95a31 commit 3e54a40
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 77 deletions.
Expand Up @@ -310,17 +310,21 @@ public ResteasyWebTarget queryParamNoTemplate(String name, Object... values) thr
{
client.abortIfClosed();
if (name == null) throw new NullPointerException(Messages.MESSAGES.nameWasNull());

//The whole array can be represented as one object, so we need to cast it to array of objects
if (values.length == 1 && values[0].getClass().isArray() && !values[0].getClass().getComponentType().isPrimitive()) {
values = (Object[]) values[0];
}

String[] stringValues = toStringValues(values);
ResteasyUriBuilder copy;
if (uriBuilder instanceof ResteasyUriBuilder) {
copy = (ResteasyUriBuilder)uriBuilder.clone();
} else {
copy = ResteasyUriBuilder.fromTemplate(uriBuilder.toTemplate());
}
for (String obj : stringValues)
{
copy.clientQueryParam(name, obj);
}

copy.clientQueryParam(name, stringValues);
return newInstance(client, copy, configuration);
}

Expand Down
@@ -1,6 +1,7 @@
package org.jboss.resteasy.client.jaxrs.internal.proxy.processors;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.Collection;

Expand Down Expand Up @@ -32,7 +33,7 @@ public AbstractCollectionProcessor(final String paramName, final Type type, fina
this.config = config;
}

protected abstract T apply(T target, Object object);
protected abstract T apply(T target, Object... objects);

@SuppressWarnings("unchecked")
public T buildIt(T target, Object object)
Expand All @@ -50,10 +51,7 @@ public T buildIt(T target, Object object)
}
else
{
for (Object obj : (Collection<?>) object)
{
target = apply(target, obj);
}
target = apply(target, ((Collection<?>) object).toArray());
}
}
}
Expand All @@ -65,46 +63,10 @@ else if (object.getClass().isArray())
object = paramConverter.toString(object);
target = apply(target, object);
}
else if (object.getClass().getComponentType().isPrimitive())
{
Class<?> componentType = object.getClass().getComponentType();
if (componentType.equals(boolean.class))
{
for (boolean bool : (boolean[]) object) target = apply(target, bool);
}
else if (componentType.equals(byte.class))
{
for (byte val : (byte[]) object) target = apply(target, val);
}
else if (componentType.equals(short.class))
{
for (short val : (short[]) object) target = apply(target, val);
}
else if (componentType.equals(int.class))
{
for (int val : (int[]) object) target = apply(target, val);
}
else if (componentType.equals(long.class))
{
for (long val : (long[]) object) target = apply(target, val);
}
else if (componentType.equals(float.class))
{
for (float val : (float[]) object) target = apply(target, val);
}
else if (componentType.equals(double.class))
{
for (double val : (double[]) object) target = apply(target, val);
}
}
else
{
Object[] objs = (Object[]) object;
for (Object obj : objs)
{
target = apply(target, obj);

}
Object[] arr = convertToObjectsArray(object);
target = apply(target, arr);
}
}
else
Expand All @@ -113,4 +75,18 @@ else if (componentType.equals(double.class))
}
return target;
}

private static Object[] convertToObjectsArray(Object array) {
if(array instanceof Object[])
return (Object[]) array;

int length = Array.getLength(array);

Object[] objects = new Object[length];
for (int i = 0; i < length; i++) {
objects[i] = Array.get(array, i);
}

return objects;
}
}
Expand Up @@ -28,28 +28,30 @@ public FormParamProcessor(final String paramName, final Type type, final Annotat
}

@Override
protected ClientInvocation apply(ClientInvocation invocation, Object object)
protected ClientInvocation apply(ClientInvocation invocation, Object... objects)
{
Form form = null;
Object entity = invocation.getEntity();
if (entity != null)
{
if (entity instanceof Form)
for (Object object : objects) {
Form form = null;
Object entity = invocation.getEntity();
if (entity != null)
{
form = (Form) entity;
if (entity instanceof Form)
{
form = (Form) entity;
}
else
{
throw new RuntimeException(Messages.MESSAGES.cannotSetFormParameter());
}
}
else
{
throw new RuntimeException(Messages.MESSAGES.cannotSetFormParameter());
form = new Form();
invocation.setEntity(Entity.form(form));
}
String value = invocation.getClientConfiguration().toString(object);
form.param(paramName, value);
}
else
{
form = new Form();
invocation.setEntity(Entity.form(form));
}
String value = invocation.getClientConfiguration().toString(object);
form.param(paramName, value);
return invocation;
}

Expand Down
Expand Up @@ -24,9 +24,11 @@ public HeaderParamProcessor(final String paramName, final Type type, final Annot
}

@Override
protected ClientInvocation apply(ClientInvocation invocation, Object object)
protected ClientInvocation apply(ClientInvocation invocation, Object... objects)
{
invocation.getHeaders().header(paramName, object);
for (Object object : objects) {
invocation.getHeaders().header(paramName, object);
}
return invocation;
}

Expand Down
Expand Up @@ -25,9 +25,9 @@ public MatrixParamProcessor(final String paramName, final Type type, final Annot
}

@Override
protected WebTarget apply(WebTarget target, Object object)
protected WebTarget apply(WebTarget target, Object... objects)
{
return target.matrixParam(paramName, object);
return target.matrixParam(paramName, objects);
}

}
Expand Up @@ -25,10 +25,10 @@ public QueryParamProcessor(final String paramName, final Type type, final Annota
}

@Override
protected WebTarget apply(WebTarget target, Object object)
protected WebTarget apply(WebTarget target, Object... objects)
{
ResteasyWebTarget t = (ResteasyWebTarget)target;
return t.queryParamNoTemplate(paramName, object);
return t.queryParamNoTemplate(paramName, objects);
}


Expand Down
Expand Up @@ -120,7 +120,7 @@ public static ResteasyUriBuilder fromTemplate(String uriTemplate)
* @param value the value of the query parameter.
* @return Returns this instance to allow call chaining.
*/
public abstract UriBuilder clientQueryParam(String name, Object value) throws IllegalArgumentException;
public abstract UriBuilder clientQueryParam(String name, Object... values) throws IllegalArgumentException;

public abstract String getHost();

Expand Down
Expand Up @@ -905,28 +905,50 @@ public UriBuilder replaceMatrixParam(String name, Object... values) throws Illeg
* @return Returns this instance to allow call chaining.
*/
@Override
public UriBuilder clientQueryParam(String name, Object value) throws IllegalArgumentException
public UriBuilder clientQueryParam(String name, Object... values) throws IllegalArgumentException
{
if (name == null) throw new IllegalArgumentException(Messages.MESSAGES.nameParameterNull());
if (value == null) throw new IllegalArgumentException(Messages.MESSAGES.passedInValueNull());
StringBuilder sb = new StringBuilder();
String prefix = "";
if (query == null) query = "";
else query += "&";
query += Encode.encodeQueryParamAsIs(name) + "=" + Encode.encodeQueryParamAsIs(value.toString());
else {
sb.append(query).append("&");
}

if (name == null) throw new IllegalArgumentException(Messages.MESSAGES.nameParameterNull());
if (values == null) throw new IllegalArgumentException(Messages.MESSAGES.valuesParameterNull());
for (Object value : values)
{
if (value == null) throw new IllegalArgumentException(Messages.MESSAGES.passedInValueNull());
sb.append(prefix);
prefix = "&";
sb.append(Encode.encodeQueryParamAsIs(name)).append("=").append(Encode.encodeQueryParamAsIs(value.toString()));
}

query = sb.toString();
return this;
}

@Override
public UriBuilder queryParam(String name, Object... values) throws IllegalArgumentException
{
StringBuilder sb = new StringBuilder();
String prefix = "";
if (query == null) query = "";
else {
sb.append(query).append("&");
}

if (name == null) throw new IllegalArgumentException(Messages.MESSAGES.nameParameterNull());
if (values == null) throw new IllegalArgumentException(Messages.MESSAGES.valuesParameterNull());
for (Object value : values)
{
if (value == null) throw new IllegalArgumentException(Messages.MESSAGES.passedInValueNull());
if (query == null) query = "";
else query += "&";
query += Encode.encodeQueryParam(name) + "=" + Encode.encodeQueryParam(value.toString());
sb.append(prefix);
prefix = "&";
sb.append(Encode.encodeQueryParam(name)).append("=").append(Encode.encodeQueryParam(value.toString()));
}

query = sb.toString();
return this;
}

Expand Down
Expand Up @@ -5,6 +5,8 @@
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.resteasy.client.jaxrs.ProxyBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.ClientBuilder;
import org.jboss.resteasy.test.resource.param.resource.QueryParamAsPrimitiveResource;
import org.jboss.resteasy.test.resource.param.resource.QueryParamAsPrimitiveResourceArray;
Expand Down Expand Up @@ -300,6 +302,24 @@ public void testGetByte() {
resourceQueryPrimitiveArray.doGetByte(array);
}

@Test(timeout = 5000)
public void testProxyClientGetByte() {
final int size = 30000;
byte[] array = new byte[size];
//Test bigger sizes
for (int i = 0; i < size; i++) {
array[i] = (byte) 127;
}

for (int i = 0; i < 5; i++) {
try {
resourceQueryPrimitiveArray.doPostByte(array);
} catch (BadRequestException | ProcessingException e) {
// expected
}
}
}

/**
* @tpTestDetails Test byte primitive object
* @tpSince RESTEasy 3.0.16
Expand Down
Expand Up @@ -4,6 +4,7 @@
import org.junit.Assert;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
Expand All @@ -28,6 +29,15 @@ public String doGetByte(@QueryParam("byte") byte[] v) {
return "content";
}

@POST
@Produces("application/byte")
public String doPostByte(@QueryParam("byte") byte[] v) {
Assert.assertTrue(QueryParamAsPrimitiveTest.ERROR_MESSAGE, (byte) 127 == v[0]);
Assert.assertTrue(QueryParamAsPrimitiveTest.ERROR_MESSAGE, (byte) 127 == v[1]);
Assert.assertTrue(QueryParamAsPrimitiveTest.ERROR_MESSAGE, (byte) 127 == v[2]);
return "content";
}

@GET
@Produces("application/short")
public String doGetShort(@QueryParam("short") short[] v) {
Expand Down
@@ -1,6 +1,7 @@
package org.jboss.resteasy.test.resource.param.resource;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
Expand All @@ -15,6 +16,11 @@ public interface QueryParamAsPrimitiveResourceResourceArray {
@Produces("application/byte")
String doGetByte(@QueryParam("byte") byte[] v);

@POST
@Path("/non/existing/end/point")
@Produces("application/byte")
String doPostByte(@QueryParam("byte") byte[] v);

@GET
@Produces("application/short")
String doGetShort(@QueryParam("short") short[] v);
Expand Down

0 comments on commit 3e54a40

Please sign in to comment.