Bug 64384 - <multipart-config> is ignored if any of max-file-size/max-request-size/file-threshold-size elements are missing
Summary: <multipart-config> is ignored if any of max-file-size/max-request-size/file-t...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.51
Hardware: PC Mac OS X 10.1
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-27 16:14 UTC by Christopher Schultz
Modified: 2020-04-28 14:43 UTC (History)
0 users



Attachments
Sample WAR file which reproduces the issue (3.31 KB, application/zip)
2020-04-27 16:17 UTC, Christopher Schultz
Details
Proposed patch (2.26 KB, patch)
2020-04-27 16:46 UTC, Christopher Schultz
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Christopher Schultz 2020-04-27 16:14:06 UTC
When a <multipart-config> element is present without any <file-size-threshold> child element, the whole <multipart-config> appears to be ignored. Specifying <file-size-threshold>0</file-size-threshold> (which is the default) results in expected behavior.

With sample configuration:
    <multipart-config>
      <max-file-size>1048576</max-file-size><!-- 1MiB -->
      <max-request-size>1049600</max-request-size><!-- 1 MiB + 1 kiB -->
      <file-size-threshold>1024</file-size-threshold><!-- 1KiB -->
    </multipart-config>

File sizes larger than 1MiB are rejected as expected. Removing the <file-size-threshold> element completely causes large files to be accepted as if the configuration were not there.

Attaching a debugger, I can see that the multipartConfigElement is essentially all defaults:

multipartConfigElement	MultipartConfigElement  (id=545)
	fileSizeThreshold	0
	location	"" (id=550)
	maxFileSize	-1
	maxRequestSize	-1
Comment 1 Christopher Schultz 2020-04-27 16:17:06 UTC
Created attachment 37198 [details]
Sample WAR file which reproduces the issue

This WAR file (including source) will work as expected:

1. Deploy the WAR file
2. Navigate to /test which will load index.html
3. Choose an arbitrary file and upload
4a. A small enough file will yield a debug output
4b. A large enough file (> 1MiB) will cause an error

If you edit WEB-INF/web.xml to remove the <file-size-threshold>, you will be able to upload any size file without error.
Comment 2 Remy Maucherat 2020-04-27 16:24:21 UTC
Ok, ok, the check here looks inaccurate:
https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/startup/ContextConfig.java#L1365

Unless all are set, only the location would be used.
Comment 3 Christopher Schultz 2020-04-27 16:40:35 UTC
I think I've found the problem, at ContextConfig:1355:

1355        MultipartDef multipartdef = servlet.getMultipartDef();
1356        if (multipartdef != null) {
1357             if (multipartdef.getMaxFileSize() != null &&
1358                    multipartdef.getMaxRequestSize()!= null &&
1359                    multipartdef.getFileSizeThreshold() != null) {
1360                wrapper.setMultipartConfigElement(new MultipartConfigElement(
                            multipartdef.getLocation(),
                            Long.parseLong(multipartdef.getMaxFileSize()),
                            Long.parseLong(multipartdef.getMaxRequestSize()),
                            Integer.parseInt(
                                    multipartdef.getFileSizeThreshold())));
                } else {
                    wrapper.setMultipartConfigElement(new MultipartConfigElement(
                            multipartdef.getLocation()));
                }
            }

When execution reaches 1355, the MultipartDef object contains the expected values:

maxFileSize=1048576
maxRequestSize=1049600
fileSizeThreshold=null

The predicate on lines 1357 - 1359 cause this configuration to not be applied if any of the items are missing.

The servlet spec allows any of these items to be missing, so I believe this is a bug and spec violation together in one.
Comment 4 Christopher Schultz 2020-04-27 16:46:01 UTC
Created attachment 37199 [details]
Proposed patch
Comment 5 Christopher Schultz 2020-04-27 16:48:50 UTC
Updating description to reflect the fact that any missing element can cause this.
Comment 6 Christopher Schultz 2020-04-27 20:20:20 UTC
Initial testing indicates this patch is correct.

I'll commit once I build a proper test-case.

My guess is that this will not affect uses of @MultipartConfig annotation, as this bug occurs when copying the web.xml config to the live servlet (wrapper) object.

Temporary workaround for anyone observing lack of <multipart-config>: Make sure to specify all of max-file-size, max-request-size, file-size-threshold
Comment 7 Christopher Schultz 2020-04-27 22:05:55 UTC
Fixed in trunk (tc10) in commit 8dddc11512fbd3b91ed9d737a42e4b8415458ddf

Working on my git-fu to back-port to other supported branches.
Comment 8 Christopher Schultz 2020-04-28 14:43:55 UTC
Rémy has back-ported to 9.0.x and 8.5.x.