Restrict memory allocation in ContentCachingRequestWrapper
Prior to this commit, the `ContentCachingRequestWrapper` could allocate a `FastByteArrayOutputStream` block that was larger than the content cache limit given as a consturctor argument. This was due to an optimization applied in gh-31834 for allocating the right content cache size when the request size is known. Fixes gh-32987
This commit is contained in:
parent
6681394886
commit
0ca393c0dc
|
@ -89,7 +89,12 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
|
||||||
public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) {
|
public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) {
|
||||||
super(request);
|
super(request);
|
||||||
int contentLength = request.getContentLength();
|
int contentLength = request.getContentLength();
|
||||||
this.cachedContent = (contentLength > 0) ? new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream();
|
if (contentLength > 0) {
|
||||||
|
this.cachedContent = new FastByteArrayOutputStream(Math.min(contentLength, contentCacheLimit));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.cachedContent = new FastByteArrayOutputStream();
|
||||||
|
}
|
||||||
this.contentCacheLimit = contentCacheLimit;
|
this.contentCacheLimit = contentCacheLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
package org.springframework.web.util;
|
package org.springframework.web.util;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.FastByteArrayOutputStream;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -89,6 +92,19 @@ class ContentCachingRequestWrapperTests {
|
||||||
assertThat(wrapper.getContentAsString()).isEqualTo(new String("Hel".getBytes(CHARSET), CHARSET));
|
assertThat(wrapper.getContentAsString()).isEqualTo(new String("Hel".getBytes(CHARSET), CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotAllocateMoreThanCacheLimit() throws Exception {
|
||||||
|
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"), CONTENT_CACHE_LIMIT);
|
||||||
|
Field field = ReflectionUtils.findField(ContentCachingRequestWrapper.class, "cachedContent");
|
||||||
|
ReflectionUtils.makeAccessible(field);
|
||||||
|
FastByteArrayOutputStream cachedContent = (FastByteArrayOutputStream) ReflectionUtils.getField(field, wrapper);
|
||||||
|
field = ReflectionUtils.findField(FastByteArrayOutputStream.class, "initialBlockSize");
|
||||||
|
ReflectionUtils.makeAccessible(field);
|
||||||
|
int blockSize = (int) ReflectionUtils.getField(field, cachedContent);
|
||||||
|
assertThat(blockSize).isEqualTo(CONTENT_CACHE_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void cachedContentWithOverflow() throws Exception {
|
void cachedContentWithOverflow() throws Exception {
|
||||||
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(
|
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(
|
||||||
|
|
Loading…
Reference in New Issue