Author: mwiederkehr
Date: Thu Jan 22 07:43:01 2009
New Revision: 736679
URL: http://svn.apache.org/viewvc?rev=736679&view=rev
Log:
MIME4J-100: parameter values with space characters have to be quoted
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/FieldsTest.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java?rev=736679&r1=736678&r2=736679&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
(original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
Thu Jan 22 07:43:01 2009
@@ -22,6 +22,7 @@
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
+import java.util.BitSet;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
@@ -32,6 +33,19 @@
import org.apache.james.mime4j.util.MimeUtil;
public class Fields {
+
+ private static final BitSet TOKEN_CHARS;
+
+ static {
+ final String specials = "()<>@,;:\\\"/[]?=";
+ TOKEN_CHARS = new BitSet(128);
+ for (char ch = 33; ch < 127; ch++) {
+ if (specials.indexOf(ch) == -1) {
+ TOKEN_CHARS.set(ch);
+ }
+ }
+ }
+
private Fields() {
}
@@ -52,7 +66,7 @@
sb.append("; ");
sb.append(entry.getKey());
sb.append('=');
- sb.append(quote(entry.getValue()));
+ sb.append(encodeValue(entry.getValue()));
}
String contentType = sb.toString();
return contentType(contentType);
@@ -103,20 +117,38 @@
return (UnstructuredField) Field.parse(Field.SUBJECT, rawValue);
}
- private static String quote(String value) {
- for (int idx = 0; idx < value.length(); idx++) {
- if (isSpecial(value.charAt(idx))) {
- value = value.replaceAll("[\\\"]", "\\\\$0");
- return "\"" + value + "\"";
- }
+ // value := token / quoted-string
+ private static String encodeValue(String value) {
+ if (isToken(value)) {
+ return value;
+ } else {
+ return quote(value);
}
-
- return value;
}
- private static boolean isSpecial(char ch) {
- final String tspecials = "()<>@,;:\\\"/[]?="; // rfc 2045
- return ch < 32 || ch >= 127 || tspecials.indexOf(ch) != -1;
+ // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
+ // tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" / <"> /
+ // "/" / "[" / "]" / "?" / "="
+ // CTL := 0.- 31., 127.
+ private static boolean isToken(String str) {
+ final int length = str.length();
+ for (int idx = 0; idx < length; idx++) {
+ char ch = str.charAt(idx);
+ if (!TOKEN_CHARS.get(ch))
+ return false;
+ }
+ return true;
+ }
+
+ // quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
+ // qcontent = qtext / quoted-pair
+ // qtext = %d33 / %d35-91 / %d93-126
+ // quoted-pair = ("\" (VCHAR / WSP))
+ // VCHAR = %x21-7E
+ // DQUOTE = %x22
+ private static String quote(String str) {
+ String escaped = str.replaceAll("[\\\"]", "\\\\$0");
+ return "\"" + escaped + "\"";
}
private static final ThreadLocal<DateFormat> RFC822_DATE_FORMAT = new
ThreadLocal<DateFormat>() {
Modified:
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/FieldsTest.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/FieldsTest.java?rev=736679&r1=736678&r2=736679&view=diff
==============================================================================
---
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/FieldsTest.java
(original)
+++
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/FieldsTest.java
Thu Jan 22 07:43:01 2009
@@ -54,6 +54,18 @@
assertEquals(expectedRaw, field.getRaw());
}
+ public void testContentTypeStringParametersWithSpaces() throws Exception {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("param", "value with space chars");
+ ContentTypeField field = Fields.contentType("multipart/mixed",
+ parameters);
+ assertTrue(field.isValidField());
+
+ String expectedRaw = "Content-Type: multipart/mixed; "
+ + "param=\"value with space chars\"";
+ assertEquals(expectedRaw, field.getRaw());
+ }
+
public void testContentTypeStringNullParameters() throws Exception {
ContentTypeField field = Fields.contentType("text/plain", null);
assertTrue(field.isValidField());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]