Affects:5.2.8

When submitting files and parameters simultaneously, if the parameter only has name but no value, a null pointer exception will occur. In the parseFileItems section of CommonsFileUploadSupport, 'value=fileItem. getString (partEncoding)` When obtaining parameter values, the 'new String (this. get(), charset)' in DiskFileItem will be called, and at this time, this. get() returns null.

request

curl --location --request POST 'http://127.0.0.1:8101/api/upload-platform/file/upload/img' \
--header 'User-Agent: Apifox/1.0.0 (https://www.apifox.cn)' \
--header 'Accept: */*' \
--header 'Host: 127.0.0.1:8101' \
--header 'Connection: keep-alive' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------358337624414903010199957' \
--form 'appType=""' \
--form 'files=@"D:\\tmp\\gkk\\1693447402973011968.jpeg"'

version

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.8</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.5</version>
</dependency>

Can I handle null pointer exceptions here

try {
                    value = fileItem.getString(partEncoding);
                } catch (UnsupportedEncodingException var12) {
                    if (this.logger.isWarnEnabled()) {
                        this.logger.warn("Could not decode multipart item '" + fileItem.getFieldName() + "' with encoding '" + partEncoding + "': using platform default");
                    }

                    value = fileItem.getString();
                }

Comment From: snicoll

This has been removed in Spring Framework 6.0.x, see the release notes but if the issue is serious enough we could consider fixing it in 5.3.x. For that to happen, we need to understand the issue more and the code snippet above is not a way to do that.

Can you please create a small sample that reproduces the problem you've described? You can attach a zip to this issue or push the code to a separate GitHub repository.

Comment From: wo94zj

request:

curl --location --request POST 'http://127.0.0.1:8080/web/upload' \
--header 'User-Agent: Apifox/1.0.0 (https://www.apifox.cn)' \
--header 'Accept: */*' \
--header 'Host: 127.0.0.1:8080' \
--header 'Connection: keep-alive' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------359526283014764577946830' \
--form 'testArg=""' \
--form 'file=@"D:\\tmp\\2x.png"'

exception:

o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at java.lang.String.<init>(String.java:491) ~[na:1.8.0_281]
    at org.apache.commons.fileupload.disk.DiskFileItem.getString(DiskFileItem.java:338) ~[commons-fileupload-1.5.jar:1.5]
    at org.springframework.web.multipart.commons.CommonsFileUploadSupport.parseFileItems(CommonsFileUploadSupport.java:260) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:160) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.commons.CommonsMultipartResolver$1.initializeMultipart(CommonsMultipartResolver.java:135) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest.getMultipartParameters(DefaultMultipartHttpServletRequest.java:174) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest.getParameter(DefaultMultipartHttpServletRequest.java:85) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.context.request.ServletWebRequest.getParameter(ServletWebRequest.java:147) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.getRequestValueForAttribute(ServletModelAttributeMethodProcessor.java:104) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:76) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:139) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]

Source file in zip spring-upload-demo.zip

Comment From: snicoll

Thanks for the sample. The NullPointerException is actually hiding

java.io.FileNotFoundException: /private/var/folders/hn/7bzmb6w56w3550705qmk6m4m0000gn/T/tomcat.8080.5366242701537499768/work/Tomcat/localhost/ROOT/upload_151b2c4d_21fd_499c_8e82_0a231a95f324_00000008.tmp (No such file or directory)

@poutsma I can reproduce with 5.3.x, I wonder if that rings a bell?

Comment From: poutsma

@poutsma I can reproduce with 5.3.x, I wonder if that rings a bell?

I know little about the innards of Commons Multipart, apart from the obvious: it uses file to storage parts that exceed a certain memory limit, so apparently the file backing this particular part is missing.

Comment From: poutsma

Fixed in d3ec9395e17e4a2e357be6dc7c90cc4f00cc1bf9.