Content-Disposition can parse BASE64 encoded filename

See gh-26463
This commit is contained in:
Yusuke Yamamoto 2021-01-28 11:48:22 +09:00 committed by Rossen Stoyanchev
parent cd80b6b4ac
commit a264013d7a
2 changed files with 24 additions and 1 deletions

View File

@ -22,7 +22,10 @@ import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@ -320,6 +323,7 @@ public final class ContentDisposition {
return new ContentDisposition("", null, null, null, null, null, null, null);
}
private final static Pattern BASE64_ENCODED_PATTERN = Pattern.compile("=\\?([0-9a-zA-Z-_]+)\\?B\\?([+/0-9a-zA-Z]+=*)\\?=");
/**
* Parse a {@literal Content-Disposition} header value as defined in RFC 2183.
* @param contentDisposition the {@literal Content-Disposition} header value
@ -362,7 +366,14 @@ public final class ContentDisposition {
}
}
else if (attribute.equals("filename") && (filename == null)) {
filename = value;
final Matcher matcher = BASE64_ENCODED_PATTERN.matcher(value);
if (matcher.find()) {
String charsetName = matcher.group(1);
String encoded = matcher.group(2);
filename = new String(Base64.getDecoder().decode(encoded), Charset.forName(charsetName));
} else {
filename = value;
}
}
else if (attribute.equals("size") ) {
size = Long.parseLong(value);

View File

@ -80,6 +80,18 @@ class ContentDispositionTests {
.build());
}
@Test
void parseBase64EncodedUTF8Filename() {
assertThat(parse("attachment; filename=\"=?UTF-8?B?5pel5pys6KqeLmNzdg==?=\"").getFilename())
.isEqualTo("日本語.csv");
}
@Test
void parseBase64EncodedShiftJISFilename() {
assertThat(parse("attachment; filename=\"=?SHIFT_JIS?B?k/qWe4zqLmNzdg==?=\"").getFilename())
.isEqualTo("日本語.csv");
}
@Test
void parseEncodedFilenameWithoutCharset() {
assertThat(parse("form-data; name=\"name\"; filename*=test.txt"))