From 4c0ece944aad373adea3a85874552ae982c989d7 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 30 Aug 2022 12:11:22 +0200 Subject: [PATCH] Fix race condition in PartGenerator This commit fixes a race condition in PartGenerator, used by DefaultPartHttpMessageReader. The condition can occur when a completion signal comes in, and the state is changed to IdleFileState at the same time. Closes gh-28963 --- .../http/codec/multipart/PartGenerator.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java index 6492c583f1..11ed75d970 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java @@ -746,8 +746,15 @@ final class PartGenerator extends BaseSubscriber { @Override public void partComplete(boolean finalPart) { - this.completed = true; - this.finalPart = finalPart; + State state = PartGenerator.this.state.get(); + // writeComplete might have changed our state to IdleFileState + if (state != this) { + state.partComplete(finalPart); + } + else { + this.completed = true; + this.finalPart = finalPart; + } } public void writeBuffer(DataBuffer dataBuffer) { @@ -771,14 +778,16 @@ final class PartGenerator extends BaseSubscriber { private void writeComplete() { IdleFileState newState = new IdleFileState(this); - if (this.completed) { - newState.partComplete(this.finalPart); - } - else if (this.disposed) { + if (this.disposed) { newState.dispose(); } else if (changeState(this, newState)) { - requestToken(); + if (this.completed) { + newState.partComplete(this.finalPart); + } + else { + requestToken(); + } } else { MultipartUtils.closeChannel(this.channel);