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) {
|
||||
super(request);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
package org.springframework.web.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -89,6 +92,19 @@ class ContentCachingRequestWrapperTests {
|
|||
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
|
||||
void cachedContentWithOverflow() throws Exception {
|
||||
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(
|
||||
|
|
Loading…
Reference in New Issue