[ 
https://issues.apache.org/jira/browse/WW-5474?focusedWorklogId=1031687&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1031687
 ]

ASF GitHub Bot logged work on WW-5474:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 22/Jul/26 14:03
            Start Date: 22/Jul/26 14:03
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1806:
URL: https://github.com/apache/struts/pull/1806

   Fixes [WW-5474](https://issues.apache.org/jira/browse/WW-5474)
   
   ## Problem
   
   `struts.multipart.maxFiles` (default `256`) is documented as a cap on the 
**number of uploaded files**, but it did not behave that way, and the two 
Jakarta parsers disagreed:
   
   - **`jakarta` parser (default)** passed the value to commons-fileupload2 
`setMaxFileCount`, whose `parseRequest` counts **every** part — form fields 
*and* files. So `maxFiles` actually limited the **total number of parameters**, 
firing spuriously on forms with many normal fields and few (or zero) files. 
This is the reported bug.
   - **`jakarta-stream` parser** never received commons enforcement (its 
streaming iterator ignores `maxFileCount`) and counted **distinct field names** 
via its own `exceedsMaxFiles`, so multiple files under one field name collapsed 
to one.
   
   ## Change
   
   - `struts.multipart.maxFiles` now counts **file parts only**, identically in 
both parsers.
   - New `struts.multipart.maxParameterCount` (default `256`) caps **non-file 
form fields**, restoring the DoS guard the old accidental total-part cap 
incidentally provided. The two limits are orthogonal.
   - Breaching either limit is **fail-closed**: the request is rejected with a 
recorded upload error and the action receives **no** partial parameters or 
files.
   - A negative value (`-1`) or unset limit means *unlimited*, following the 
commons-fileupload2 convention.
   - The `jakarta` parser keeps a coarse total-parts backstop (`maxFiles + 
maxParameterCount`, only when both are finite) so gross floods abort early 
inside commons.
   
   Design: 
`docs/superpowers/specs/2026-07-22-WW-5474-multipart-maxfiles-semantics-design.md`
   
   ## Behavior changes to be aware of (please review)
   
   1. **`jakarta-stream` gains a parameter-count cap it never had.** A 
`jakarta-stream` app legitimately posting **more than 256 form fields** will 
now fail at field 257 unless it raises `struts.multipart.maxParameterCount`. 
The default `jakarta` parser is strictly *more* permissive than before 
(previously fields+files shared one 256 budget; now 256 each).
   2. **Fail-closed now discards partial data on `maxSize`/`maxFileSize` 
breaches too** (not only the new limits). Previously the stream parser could 
expose parts collected before a size breach; now a rejected request exposes 
nothing. This is intentional hardening.
   3. **Gross-flood message differs by parser** (spec §6, accepted tradeoff): 
an all-fields flood exceeding the combined `512` total on the `jakarta` parser 
surfaces the generic `FileUploadFileCountLimitException` via the commons 
backstop, while the stream parser reports the precise 
`FileUploadParameterCountLimitException`. Both fail closed.
   
   ## Tests
   
   New/updated unit tests in `JakartaMultiPartRequestTest`, 
`JakartaStreamMultiPartRequestTest`, `AbstractMultiPartRequestTest` cover: many 
fields + few files accepted (the reported regression), over-`maxFiles` and 
over-`maxParameterCount` fail-closed, multiple files under one field name 
counted individually, and `maxFiles=-1` not clamped by the backstop. Full 
`core` module suite green (3003 tests); `ActionFileUploadInterceptorTest` 
regression green.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1031687)
    Remaining Estimate: 0h
            Time Spent: 10m

> struts.multipart.maxFiles does not work as described/expected
> -------------------------------------------------------------
>
>                 Key: WW-5474
>                 URL: https://issues.apache.org/jira/browse/WW-5474
>             Project: Struts 2
>          Issue Type: Bug
>    Affects Versions: 6.3.0
>            Reporter: nikos dimitrakas
>            Priority: Major
>             Fix For: 7.3.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> According to the documentation the property struts.multipart.maxFiles (which 
> defaults to 256) is supposed to set a limit to how many files a multi-part 
> form submission may include. But in reality, the specified value sets a limit 
> to how many parameter values the form may submit, including strings, 
> integers, booleans (from all input fields, checkboxes, hiddens, etc).
> The problem is in the method JakartaMultiPartRequest.parsePrequest (part of 
> struts) when in the last line it calls upload.parseRequest which is in 
> FileUploadBase (part of commons-fileupload). That methods tries to find the 
> FileItems from the provided RequestContext, but considers every parameter 
> value to be a FileItem and then throws a new FileCountLimitExceededException 
> when the number of parameter values (of any type) reaches the fileCountMax.
> I am not sure if the problem is in struts or in fileupload. Maybe the 
> provided RequestContext should somehow only include the file parameters so 
> that only they get counted. Or perhaps the documentation should be changed to 
> clarify that struts.multipart.maxFiles specifies the maximum number of 
> parameter values a multipart form may include.
> I also found the issue 
> [FILEUPLOAD-351|https://issues.apache.org/jira/browse/FILEUPLOAD-351] that 
> seems to point out the confusing behaviour. But until the issue has been 
> resolved in fileupload, struts behaves contrary to its own documentation at 
> [https://struts.apache.org/core-developers/file-upload]
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to