mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
WW-5501 Reverts changes related to WW-5501 (#1219)
This commit is contained in:
+2
-60
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.fileupload2.core.FileUploadByteCountLimitException;
|
||||
import org.apache.commons.fileupload2.core.FileUploadContentTypeException;
|
||||
import org.apache.commons.fileupload2.core.FileUploadException;
|
||||
@@ -30,11 +32,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.security.DefaultExcludedPatternsChecker;
|
||||
import org.apache.struts2.security.ExcludedPatternsChecker;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
@@ -45,8 +43,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.normalizeSpace;
|
||||
|
||||
/**
|
||||
* Abstract class with some helper methods, it should be used
|
||||
* when starting development of another implementation of {@link MultiPartRequest}
|
||||
@@ -54,14 +50,9 @@ import static org.apache.commons.lang3.StringUtils.normalizeSpace;
|
||||
public abstract class AbstractMultiPartRequest implements MultiPartRequest {
|
||||
|
||||
protected static final String STRUTS_MESSAGES_UPLOAD_ERROR_PARAMETER_TOO_LONG_KEY = "struts.messages.upload.error.parameter.too.long";
|
||||
protected static final String STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_FIELD = "struts.messages.upload.error.illegal.characters.field";
|
||||
protected static final String STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_NAME = "struts.messages.upload.error.illegal.characters.name";
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(AbstractMultiPartRequest.class);
|
||||
|
||||
private static final String EXCLUDED_FILE_PATTERN = "^(.*[<>&\"'|;\\\\/?*:]+.*|.*\\.\\..*)$";
|
||||
private static final String EXCLUDED_FILE_PATTERN_WITH_DMI_SUPPORT = "^(?!action:[^<>&\"'|;\\\\/?*:]+(![^<>&\"'|;\\\\/?*:]+)?$)(.*[<>&\"'|;\\\\/?*:]+.*|.*\\.\\..*)$\n";
|
||||
|
||||
/**
|
||||
* Defines the internal buffer size used during streaming operations.
|
||||
*/
|
||||
@@ -117,19 +108,6 @@ public abstract class AbstractMultiPartRequest implements MultiPartRequest {
|
||||
*/
|
||||
protected Map<String, List<String>> parameters = new HashMap<>();
|
||||
|
||||
|
||||
private final ExcludedPatternsChecker patternsChecker;
|
||||
|
||||
protected AbstractMultiPartRequest() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
protected AbstractMultiPartRequest(boolean dmiValue) {
|
||||
var patternsChecker = new DefaultExcludedPatternsChecker();
|
||||
patternsChecker.setAdditionalExcludePatterns(dmiValue ? EXCLUDED_FILE_PATTERN_WITH_DMI_SUPPORT : EXCLUDED_FILE_PATTERN);
|
||||
this.patternsChecker = patternsChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bufferSize Sets the buffer size to be used.
|
||||
*/
|
||||
@@ -431,40 +409,4 @@ public abstract class AbstractMultiPartRequest implements MultiPartRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName file name to check
|
||||
* @return true if the file name is excluded
|
||||
*/
|
||||
protected boolean isExcluded(String fileName) {
|
||||
return patternsChecker.isExcluded(fileName).isExcluded();
|
||||
}
|
||||
|
||||
protected boolean isInvalidInput(String fieldName, String fileName) {
|
||||
// Skip file uploads that don't have a file name - meaning that no file was selected.
|
||||
if (fileName == null || fileName.isBlank()) {
|
||||
LOG.debug(() -> "No file has been uploaded for the field: " + normalizeSpace(fieldName));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isExcluded(fileName)) {
|
||||
var normalizedFileName = normalizeSpace(fileName);
|
||||
LOG.debug("File name [{}] is not accepted", normalizedFileName);
|
||||
errors.add(new LocalizedMessage(getClass(), STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_NAME, null,
|
||||
new String[]{normalizedFileName}));
|
||||
return true;
|
||||
}
|
||||
|
||||
return isInvalidInput(fieldName);
|
||||
}
|
||||
|
||||
protected boolean isInvalidInput(String fieldName) {
|
||||
if (isExcluded(fieldName)) {
|
||||
var normalizedFieldName = normalizeSpace(fieldName);
|
||||
LOG.debug("Form field [{}}] is rejected!", normalizedFieldName);
|
||||
errors.add(new LocalizedMessage(getClass(), STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_FIELD, null,
|
||||
new String[]{normalizedFieldName}));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-20
@@ -18,17 +18,14 @@
|
||||
*/
|
||||
package org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.fileupload2.core.DiskFileItem;
|
||||
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
@@ -44,15 +41,6 @@ public class JakartaMultiPartRequest extends AbstractMultiPartRequest {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JakartaMultiPartRequest.class);
|
||||
|
||||
public JakartaMultiPartRequest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, required = false)
|
||||
public JakartaMultiPartRequest(String dmiValue) {
|
||||
super(BooleanUtils.toBoolean(dmiValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processUpload(HttpServletRequest request, String saveDir) throws IOException {
|
||||
Charset charset = readCharsetEncoding(request);
|
||||
@@ -89,14 +77,10 @@ public class JakartaMultiPartRequest extends AbstractMultiPartRequest {
|
||||
}
|
||||
|
||||
protected void processNormalFormField(DiskFileItem item, Charset charset) throws IOException {
|
||||
var fieldName = item.getFieldName();
|
||||
LOG.debug("Item: {} is a normal form field", fieldName);
|
||||
|
||||
if (isInvalidInput(fieldName)) {
|
||||
return;
|
||||
}
|
||||
LOG.debug("Item: {} is a normal form field", normalizeSpace(item.getName()));
|
||||
|
||||
List<String> values;
|
||||
String fieldName = item.getFieldName();
|
||||
if (parameters.get(fieldName) != null) {
|
||||
values = parameters.get(fieldName);
|
||||
} else {
|
||||
@@ -116,7 +100,9 @@ public class JakartaMultiPartRequest extends AbstractMultiPartRequest {
|
||||
}
|
||||
|
||||
protected void processFileField(DiskFileItem item) {
|
||||
if (isInvalidInput(item.getFieldName(), item.getName())) {
|
||||
// Skip file uploads that don't have a file name - meaning that no file was selected.
|
||||
if (item.getName() == null || item.getName().trim().isEmpty()) {
|
||||
LOG.debug(() -> "No file has been uploaded for the field: " + normalizeSpace(item.getFieldName()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+6
-21
@@ -18,19 +18,16 @@
|
||||
*/
|
||||
package org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload2.core.FileItemInput;
|
||||
import org.apache.commons.fileupload2.core.FileUploadFileCountLimitException;
|
||||
import org.apache.commons.fileupload2.core.FileUploadSizeException;
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -59,15 +56,6 @@ public class JakartaStreamMultiPartRequest extends AbstractMultiPartRequest {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JakartaStreamMultiPartRequest.class);
|
||||
|
||||
public JakartaStreamMultiPartRequest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, required = false)
|
||||
public JakartaStreamMultiPartRequest(String dmiValue) {
|
||||
super(BooleanUtils.toBoolean(dmiValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the upload.
|
||||
*
|
||||
@@ -126,11 +114,8 @@ public class JakartaStreamMultiPartRequest extends AbstractMultiPartRequest {
|
||||
*/
|
||||
protected void processFileItemAsFormField(FileItemInput fileItemInput) throws IOException {
|
||||
String fieldName = fileItemInput.getFieldName();
|
||||
if (isInvalidInput(fieldName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String fieldValue = readStream(fileItemInput.getInputStream());
|
||||
|
||||
if (exceedsMaxStringLength(fieldName, fieldValue)) {
|
||||
return;
|
||||
}
|
||||
@@ -202,7 +187,9 @@ public class JakartaStreamMultiPartRequest extends AbstractMultiPartRequest {
|
||||
* @param location location
|
||||
*/
|
||||
protected void processFileItemAsFileField(FileItemInput fileItemInput, Path location) throws IOException {
|
||||
if (isInvalidInput(fileItemInput.getFieldName(), fileItemInput.getName())) {
|
||||
// Skip file uploads that don't have a file name - meaning that no file was selected.
|
||||
if (fileItemInput.getName() == null || fileItemInput.getName().trim().isEmpty()) {
|
||||
LOG.debug(() -> "No file has been uploaded for the field: " + normalizeSpace(fileItemInput.getFieldName()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -245,9 +232,7 @@ public class JakartaStreamMultiPartRequest extends AbstractMultiPartRequest {
|
||||
InputStream input = fileItemInput.getInputStream();
|
||||
try (OutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()), bufferSize)) {
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Streaming file: {} using buffer size: {}", normalizeSpace(fileItemInput.getName()), bufferSize);
|
||||
}
|
||||
LOG.debug("Streaming file: {} using buffer size: {}", normalizeSpace(fileItemInput.getName()), bufferSize);
|
||||
for (int length; ((length = input.read(buffer)) > 0); ) {
|
||||
output.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
@@ -40,10 +40,6 @@ struts.messages.error.file.too.large=The file is too large to be uploaded: {0} "
|
||||
# 1 - max string length
|
||||
# 2 - actual size
|
||||
struts.messages.upload.error.parameter.too.long=The request parameter "{0}" was too long. Max length allowed is {1}, but found {2}!
|
||||
# 0 - field name
|
||||
struts.messages.upload.error.illegal.characters.field=The multipart upload field name "{0}" contains illegal characters!
|
||||
# 0 - file name
|
||||
struts.messages.upload.error.illegal.characters.name=The multipart upload filename "{0}" contains illegal characters!
|
||||
# 0 - input name
|
||||
# 1 - original filename
|
||||
# 2 - file name after uploading the file
|
||||
|
||||
+1
-56
@@ -19,13 +19,7 @@
|
||||
package org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.apache.struts2.config.Configuration;
|
||||
import org.apache.struts2.config.ConfigurationManager;
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
import org.apache.struts2.inject.Container;
|
||||
import org.apache.struts2.util.StrutsTestCaseHelper;
|
||||
import org.apache.struts2.views.jsp.StrutsMockServletContext;
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -37,7 +31,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -54,7 +47,6 @@ abstract class AbstractMultiPartRequestTest {
|
||||
protected final String endline = "\r\n";
|
||||
|
||||
protected AbstractMultiPartRequest multiPart;
|
||||
protected Container container;
|
||||
|
||||
abstract protected AbstractMultiPartRequest createMultipartRequest();
|
||||
|
||||
@@ -67,13 +59,7 @@ abstract class AbstractMultiPartRequestTest {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
StrutsMockServletContext servletContext = new StrutsMockServletContext();
|
||||
Dispatcher dispatcher = StrutsTestCaseHelper.initDispatcher(servletContext, Collections.emptyMap());
|
||||
ConfigurationManager configurationManager = dispatcher.getConfigurationManager();
|
||||
Configuration configuration = configurationManager.getConfiguration();
|
||||
container = configuration.getContainer();
|
||||
|
||||
public void before() {
|
||||
mockRequest = new MockHttpServletRequest();
|
||||
mockRequest.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
mockRequest.setMethod("post");
|
||||
@@ -506,47 +492,6 @@ abstract class AbstractMultiPartRequestTest {
|
||||
.containsExactly("struts.messages.upload.error.FileUploadException");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void maliciousFields() throws IOException {
|
||||
String content = formFile("file1", "test1.csv", "1,2,3,4") +
|
||||
formField("top.param", "expression") +
|
||||
endline + "--" + boundary + "--";
|
||||
|
||||
mockRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertThat(JakartaServletDiskFileUpload.isMultipartContent(mockRequest)).isTrue();
|
||||
|
||||
multiPart.parse(mockRequest, tempDir);
|
||||
|
||||
assertThat(multiPart.getErrors()).extracting(LocalizedMessage::getTextKey)
|
||||
.containsExactly(AbstractMultiPartRequest.STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_FIELD);
|
||||
|
||||
assertThat(multiPart.getParameterNames().asIterator()).toIterable()
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void maliciousFilename() throws IOException {
|
||||
String content = formFile("file1", "../test1.csv", "1,2,3,4") +
|
||||
formField("param", "expression") +
|
||||
endline + "--" + boundary + "--";
|
||||
|
||||
mockRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertThat(JakartaServletDiskFileUpload.isMultipartContent(mockRequest)).isTrue();
|
||||
|
||||
multiPart.parse(mockRequest, tempDir);
|
||||
|
||||
assertThat(multiPart.getErrors()).extracting(LocalizedMessage::getTextKey)
|
||||
.containsExactly(AbstractMultiPartRequest.STRUTS_MESSAGES_UPLOAD_ERROR_ILLEGAL_CHARACTERS_NAME);
|
||||
|
||||
assertThat(multiPart.getParameterNames().asIterator()).toIterable()
|
||||
.hasSize(1);
|
||||
assertThat(multiPart.getParameterNames().asIterator()).toIterable()
|
||||
.containsOnly("param");
|
||||
assertThat(multiPart.getFileNames("file1")).isEmpty();
|
||||
}
|
||||
|
||||
protected String formFile(String fieldName, String filename, String content) {
|
||||
return endline +
|
||||
"--" + boundary + endline +
|
||||
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
abstract class AbstractMultiPartRequestWithDMITest extends AbstractMultiPartRequestTest {
|
||||
|
||||
@Test
|
||||
public void actionField() throws IOException {
|
||||
String content = formFile("file1", "test1.csv", "1,2,3,4") +
|
||||
formField("action:myUploads", "") +
|
||||
endline + "--" + boundary + "--";
|
||||
|
||||
mockRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertThat(JakartaServletDiskFileUpload.isMultipartContent(mockRequest)).isTrue();
|
||||
|
||||
multiPart.parse(mockRequest, tempDir);
|
||||
|
||||
assertThat(multiPart.getErrors())
|
||||
.isEmpty();
|
||||
|
||||
assertThat(multiPart.getParameterNames().asIterator()).toIterable()
|
||||
.containsOnly("action:myUploads");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actionFieldWithBang() throws IOException {
|
||||
String content = formFile("file1", "test1.csv", "1,2,3,4") +
|
||||
formField("action:myUploads!upload", "") +
|
||||
endline + "--" + boundary + "--";
|
||||
|
||||
mockRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertThat(JakartaServletDiskFileUpload.isMultipartContent(mockRequest)).isTrue();
|
||||
|
||||
multiPart.parse(mockRequest, tempDir);
|
||||
|
||||
assertThat(multiPart.getErrors())
|
||||
.isEmpty();
|
||||
|
||||
assertThat(multiPart.getParameterNames().asIterator()).toIterable()
|
||||
.containsOnly("action:myUploads!upload");
|
||||
}
|
||||
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
public class JakartaMultiPartRequestWithDMITest extends AbstractMultiPartRequestWithDMITest {
|
||||
|
||||
@Override
|
||||
protected AbstractMultiPartRequest createMultipartRequest() {
|
||||
return new JakartaMultiPartRequest(Boolean.TRUE.toString());
|
||||
}
|
||||
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
public class JakartaStreamMultiPartRequestWithDMITest extends AbstractMultiPartRequestWithDMITest {
|
||||
|
||||
@Override
|
||||
protected AbstractMultiPartRequest createMultipartRequest() {
|
||||
return new JakartaStreamMultiPartRequest(Boolean.TRUE.toString());
|
||||
}
|
||||
|
||||
}
|
||||
+8
-70
@@ -18,21 +18,21 @@
|
||||
*/
|
||||
package org.apache.struts2.interceptor;
|
||||
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.locale.DefaultLocaleProvider;
|
||||
import org.apache.struts2.ValidationAwareSupport;
|
||||
import org.apache.struts2.mock.MockActionInvocation;
|
||||
import org.apache.struts2.mock.MockActionProxy;
|
||||
import org.apache.struts2.util.ClassLoaderUtil;
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletDiskFileUpload;
|
||||
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.action.UploadedFilesAware;
|
||||
import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
|
||||
import org.apache.struts2.dispatcher.multipart.StrutsUploadedFile;
|
||||
import org.apache.struts2.dispatcher.multipart.UploadedFile;
|
||||
import org.apache.struts2.locale.DefaultLocaleProvider;
|
||||
import org.apache.struts2.mock.MockActionInvocation;
|
||||
import org.apache.struts2.mock.MockActionProxy;
|
||||
import org.apache.struts2.util.ClassLoaderUtil;
|
||||
import org.assertj.core.util.Files;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
@@ -514,73 +514,11 @@ public class ActionFileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
assertTrue(msg.startsWith("Der Request übertraf die maximal erlaubte Größe"));
|
||||
}
|
||||
|
||||
public void testUnacceptedFieldName() throws Exception {
|
||||
request.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
request.setMethod("post");
|
||||
request.addHeader("Content-type", "multipart/form-data; boundary=---1234");
|
||||
|
||||
// inspired by the unit tests for jakarta commons fileupload
|
||||
String content = ("-----1234\r\n" +
|
||||
"Content-Disposition: form-data; name=\"top.file\"; filename=\"deleteme.txt\"\r\n" +
|
||||
"Content-Type: text/html\r\n" +
|
||||
"\r\n" +
|
||||
"Unit test of ActionFileUploadInterceptor" +
|
||||
"\r\n" +
|
||||
"-----1234--\r\n");
|
||||
request.setContent(content.getBytes(StandardCharsets.US_ASCII));
|
||||
|
||||
MyFileUploadAction action = container.inject(MyFileUploadAction.class);
|
||||
|
||||
MockActionInvocation mai = new MockActionInvocation();
|
||||
mai.setAction(action);
|
||||
mai.setResultCode("success");
|
||||
mai.setInvocationContext(ActionContext.getContext());
|
||||
ActionContext.getContext()
|
||||
.withServletRequest(createMultipartRequestMaxSize(2000));
|
||||
|
||||
interceptor.intercept(mai);
|
||||
|
||||
assertThat(action.getActionErrors())
|
||||
.containsExactly("The multipart upload field name \"top.file\" contains illegal characters!");
|
||||
assertNull(action.getUploadFiles());
|
||||
}
|
||||
|
||||
public void testUnacceptedFileName() throws Exception {
|
||||
request.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
request.setMethod("post");
|
||||
request.addHeader("Content-type", "multipart/form-data; boundary=---1234");
|
||||
|
||||
// inspired by the unit tests for jakarta commons fileupload
|
||||
String content = ("-----1234\r\n" +
|
||||
"Content-Disposition: form-data; name=\"file\"; filename=\"../deleteme.txt\"\r\n" +
|
||||
"Content-Type: text/html\r\n" +
|
||||
"\r\n" +
|
||||
"Unit test of ActionFileUploadInterceptor" +
|
||||
"\r\n" +
|
||||
"-----1234--\r\n");
|
||||
request.setContent(content.getBytes(StandardCharsets.US_ASCII));
|
||||
|
||||
MyFileUploadAction action = container.inject(MyFileUploadAction.class);
|
||||
|
||||
MockActionInvocation mai = new MockActionInvocation();
|
||||
mai.setAction(action);
|
||||
mai.setResultCode("success");
|
||||
mai.setInvocationContext(ActionContext.getContext());
|
||||
ActionContext.getContext()
|
||||
.withServletRequest(createMultipartRequestMaxSize(2000));
|
||||
|
||||
interceptor.intercept(mai);
|
||||
|
||||
assertThat(action.getActionErrors())
|
||||
.containsExactly("The multipart upload filename \"../deleteme.txt\" contains illegal characters!");
|
||||
assertNull(action.getUploadFiles());
|
||||
}
|
||||
|
||||
private String encodeTextFile(String filename, String contentType, String content) {
|
||||
return endline +
|
||||
"--" + boundary +
|
||||
endline +
|
||||
"Content-Disposition: form-data; name=\"" + "file" + "\"; filename=\"" + filename + "\"" +
|
||||
"Content-Disposition: form-data; name=\"" + "file" + "\"; filename=\"" + filename +
|
||||
endline +
|
||||
"Content-Type: " + contentType +
|
||||
endline +
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ public class DefaultExcludedPatternsCheckerTest extends XWorkTestCase {
|
||||
|
||||
public void testDefaultExcludePatterns() throws Exception {
|
||||
// given
|
||||
List<String> prefixes = Arrays.asList("#[0].%s", "[0].%s", "top.%s", "%{[0].%s}", "%{#[0].%s}", "%{top.%s}", "%{#top.%s}", "%{#%s}", "%{%s}", "#%s", "top.param", "%{top.request}", "#top.param");
|
||||
List<String> prefixes = Arrays.asList("#[0].%s", "[0].%s", "top.%s", "%{[0].%s}", "%{#[0].%s}", "%{top.%s}", "%{#top.%s}", "%{#%s}", "%{%s}", "#%s");
|
||||
List<String> inners = Arrays.asList("servletRequest", "servletResponse", "servletContext", "application", "session", "struts", "request", "response", "dojo", "parameters");
|
||||
List<String> suffixes = Arrays.asList("['test']", "[\"test\"]", ".test");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user