Polish contribution
This commit polishes an external contribution, ensuring that not just spaces are encoded as underscores, and that underscores are encoded as non-printable. See gh-30252
This commit is contained in:
		
							parent
							
								
									5a4a46af78
								
							
						
					
					
						commit
						74d3268656
					
				| 
						 | 
				
			
			@ -23,6 +23,7 @@ import java.time.ZonedDateTime;
 | 
			
		|||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			@ -545,7 +559,7 @@ public final class ContentDisposition {
 | 
			
		|||
		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++;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -583,7 +597,10 @@ public final class ContentDisposition {
 | 
			
		|||
		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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -599,7 +616,11 @@ public final class ContentDisposition {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private static boolean isPrintable(byte c) {
 | 
			
		||||
		return (c >= '!' && c <= '<') || (c >= '@' && c <= '~') || c == '>';
 | 
			
		||||
		int b = c;
 | 
			
		||||
		if (b < 0) {
 | 
			
		||||
			b = 256 + b;
 | 
			
		||||
		}
 | 
			
		||||
		return PRINTABLE.get(b);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static String encodeQuotedPairs(String filename) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -331,7 +331,12 @@ class ContentDispositionTests {
 | 
			
		|||
		ContentDisposition cd = ContentDisposition.attachment()
 | 
			
		||||
				.filename(filename, StandardCharsets.UTF_8)
 | 
			
		||||
				.build();
 | 
			
		||||
		String[] parts = cd.toString().split("; ");
 | 
			
		||||
		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())
 | 
			
		||||
| 
						 | 
				
			
			@ -341,4 +346,5 @@ class ContentDispositionTests {
 | 
			
		|||
		assertThat(ContentDisposition.parse(rfc5987Filename).getFilename())
 | 
			
		||||
				.isEqualTo(filename);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue