Skip to content

Commit

Permalink
Merge pull request #30252 from luozhenyu:content-disposition
Browse files Browse the repository at this point in the history
* gh-30252:
  Polish contribution
  Quote question marks in content-disposition
  • Loading branch information
poutsma committed Apr 18, 2023
2 parents a465b16 + 74d3268 commit 685548b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.BitSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -58,6 +59,19 @@ public final class ContentDisposition {
private static final String INVALID_HEADER_FIELD_PARAMETER_FORMAT =
"Invalid header field parameter format (as defined in RFC 5987)";

private static final BitSet PRINTABLE = new BitSet(256);


static {
// RFC 2045, Section 6.7, and RFC 2047, Section 4.2
for (int i=33; i<= 126; i++) {
PRINTABLE.set(i);
}
PRINTABLE.set(61, false); // =
PRINTABLE.set(63, false); // ?
PRINTABLE.set(95, false); // _
}


@Nullable
private final String type;
Expand Down Expand Up @@ -545,7 +559,7 @@ private static String decodeQuotedPrintableFilename(String filename, Charset cha
int index = 0;
while (index < value.length) {
byte b = value[index];
if (b == '_') {
if (b == '_') { // RFC 2047, section 4.2, rule (2)
baos.write(' ');
index++;
}
Expand Down Expand Up @@ -583,7 +597,10 @@ private static String encodeQuotedPrintableFilename(String filename, Charset cha
sb.append(charset.name());
sb.append("?Q?");
for (byte b : source) {
if (isPrintable(b)) {
if (b == 32) { // RFC 2047, section 4.2, rule (2)
sb.append('_');
}
else if (isPrintable(b)) {
sb.append((char) b);
}
else {
Expand All @@ -599,7 +616,11 @@ private static String encodeQuotedPrintableFilename(String filename, Charset cha
}

private static boolean isPrintable(byte c) {
return (c >= '!' && c <= '<') || (c >= '>' && c <= '~');
int b = c;
if (b < 0) {
b = 256 + b;
}
return PRINTABLE.get(b);
}

private static String encodeQuotedPairs(String filename) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,26 @@ void parseFormatted() {
assertThat(parsed.toString()).isEqualTo(cd.toString());
}

@Test // gh-30252
void parseFormattedWithQuestionMark() {
String filename = "filename with ?问号.txt";
ContentDisposition cd = ContentDisposition.attachment()
.filename(filename, StandardCharsets.UTF_8)
.build();
String result = cd.toString();
assertThat(result).isEqualTo("attachment; " +
"filename=\"=?UTF-8?Q?filename_with_=3F=E9=97=AE=E5=8F=B7.txt?=\"; " +
"filename*=UTF-8''filename%20with%20%3F%E9%97%AE%E5%8F%B7.txt");

String[] parts = result.split("; ");

String quotedPrintableFilename = parts[0] + "; " + parts[1];
assertThat(ContentDisposition.parse(quotedPrintableFilename).getFilename())
.isEqualTo(filename);

String rfc5987Filename = parts[0] + "; " + parts[2];
assertThat(ContentDisposition.parse(rfc5987Filename).getFilename())
.isEqualTo(filename);
}

}

0 comments on commit 685548b

Please sign in to comment.