Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
049fa74
Bootstrapping Mail 1.6 spec
jgallimore Aug 4, 2020
14800ed
1. MailSessionDefinition should use Repeatable annotation for Java EE…
jgallimore Aug 4, 2020
6d944d1
2. MimeMessage.updateHeaders should set Date header if not already set
jgallimore Aug 4, 2020
f1ec079
3. Update public API to use generics
jgallimore Aug 4, 2020
e830b3d
4. MailDateFormat changes for version 1.6
jgallimore Aug 4, 2020
438dfc0
5. Store, Transport, and Folder should implement AutoCloseable
jgallimore Aug 4, 2020
8d5bb71
6. The UIDFolder interface should have a getter for UIDNEXT
cesarhernandezgt Aug 4, 2020
4300b0c
6. The UIDFolder interface should have a getter for UIDNEXT
jgallimore Aug 4, 2020
6bdedcd
7. The UIDFolder interface should have a MAXUID constant
jgallimore Aug 4, 2020
473bb28
8. MimeMultipart should throw ParseException for parsing errors
jgallimore Aug 4, 2020
d3ec322
Stubs for 8. MimeMultipart should throw ParseException for parsing er…
jgallimore Aug 4, 2020
8f32fef
Add stubs for 11. Flags convenience methods
jgallimore Aug 4, 2020
229a022
Merge branch 'trunk' of https://github.com/jgallimore/geronimo-specs …
cesarhernandezgt Aug 4, 2020
8e74f2e
9. Support addressing i18n via RFC 6530/6531/6532
cesarhernandezgt Aug 4, 2020
ddf3fe4
10. Look for resource files in <java.home>/conf on JDK 1.9
cesarhernandezgt Aug 5, 2020
12f2e83
Merge pull request #1 from cesarhernandezgt/1.6
jgallimore Aug 5, 2020
d283809
Merge pull request #2 from cesarhernandezgt/1.6-10
jgallimore Aug 5, 2020
f246d8b
Implement new methods on Flags
jgallimore Aug 5, 2020
f57b170
fixes for signature test
cesarhernandezgt Aug 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
9. Support addressing i18n via RFC 6530/6531/6532
  • Loading branch information
cesarhernandezgt committed Aug 4, 2020
commit 8e74f2ea733d5b109dccbf9d83bb518cf2b2218b
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

import javax.mail.Address;
import javax.mail.Session;
Expand Down Expand Up @@ -587,7 +588,7 @@ public void validate() throws AddressException {
* @since JavaMail 1.6
*/
public static String toUnicodeString(Address[] addresses) {
throw new UnsupportedOperationException("Implement me");
return toUnicodeString(addresses, 0);
}

/**
Expand All @@ -608,9 +609,70 @@ public static String toUnicodeString(Address[] addresses) {
* given array is not an InternetAddress object.
* Note that this is a RuntimeException.
* @return comma separated string of addresses
* @since JavaMail 1.6
* @Since JavaMail 1.6
*/
public static String toUnicodeString(Address[] addresses, int used) {
throw new UnsupportedOperationException("Implement me");

if (addresses == null || addresses.length == 0) {
return null;
}

boolean sawNonAsciiCharacters = false;

if (addresses.length == 1) {

String converted = ((InternetAddress)addresses[0]).toUnicodeString();
if (MimeUtility.verifyAscii(converted) != MimeUtility.ALL_ASCII){
sawNonAsciiCharacters = true;
converted = new String(converted.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

}

if (used + converted.length() > 72) {
converted = "\r\n " + converted;
}

if(sawNonAsciiCharacters){
return new String(converted.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
}

return converted;
} else {
final StringBuffer buf = new StringBuffer(addresses.length * 32);
for (int i = 0; i < addresses.length; i++) {

String converted = ((InternetAddress)addresses[0]).toUnicodeString();

if (MimeUtility.verifyAscii(converted) != MimeUtility.ALL_ASCII){
sawNonAsciiCharacters = true;
converted = new String(converted.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

}

if (i == 0) {
if (used + converted.length() + 1 > 72) {
buf.append("\r\n ");
used = 2;
}
} else {
if (used + converted.length() + 1 > 72) {
buf.append(",\r\n ");
used = 2;
} else {
buf.append(", ");
used += 2;
}
}
buf.append(converted);
used += converted.length();
}

String finalString = buf.toString();

if(sawNonAsciiCharacters){
return new String(finalString.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
}
return finalString;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
Expand Down Expand Up @@ -82,73 +83,49 @@ public InternetHeaders() {
* Create a new InternetHeaders initialized by reading headers from the
* stream.
*
* @param in
* the RFC822 input stream to load from
* @throws MessagingException
* if there is a problem pasring the stream
* @param in RFC822 input stream
* @param allowUtf8 if UTF-8 encoded headers are allowed
* @exception MessagingException if there is a problem parsing the stream
* @since JavaMail 1.6
*/
public InternetHeaders(final InputStream in) throws MessagingException {
load(in);
public InternetHeaders(final InputStream in, boolean allowUtf8) throws MessagingException {
load(in, allowUtf8);
}

/**
* Read and parse the given RFC822 message stream till the
* blank line separating the header from the body. The input
* stream is left positioned at the start of the body. The
* header lines are stored internally. <p>
*
* For efficiency, wrap a BufferedInputStream around the actual
* input stream and pass it as the parameter. <p>
* Create a new InternetHeaders initialized by reading headers from the
* stream.
*
* No placeholder entries are inserted; the original order of
* the headers is preserved.
* @param in the RFC822 input stream to load from
* @throws MessagingException if there is a problem parsing the stream
*
* @param is RFC822 input stream
* @param allowutf8 if UTF-8 encoded headers are allowed
* @exception MessagingException for any I/O error reading the stream
* @since JavaMail 1.6
*/
public InternetHeaders(InputStream is, boolean allowutf8) throws MessagingException {
// Implement me
public InternetHeaders(final InputStream in) throws MessagingException {
load(in, false);
}


/**
* Read and parse the given RFC822 message stream till the
* blank line separating the header from the body. Store the
* header lines inside this InternetHeaders object. The order
* of header lines is preserved. <p>
* of header lines is preserved.
*
* Note that the header lines are added into this InternetHeaders
* object, so any existing headers in this object will not be
* affected. Headers are added to the end of the existing list
* of headers, in order.
*
* @param is RFC822 input stream
* @param allowutf8 if UTF-8 encoded headers are allowed
* @exception MessagingException for any I/O error reading the stream
* @since JavaMail 1.6
* @param is RFC822 input stream
* @param allowUtf8 if UTF-8 encoded headers are allowed
* @exception MessagingException for any I/O error reading the stream
* @since JavaMail 1.6
*/
public void load(InputStream is, boolean allowutf8) throws MessagingException {
// Implement me
}


/**
* Read and parse the supplied stream and add all headers to the current
* set.
*
* @param in
* the RFC822 input stream to load from
* @throws MessagingException
* if there is a problem pasring the stream
*/
public void load(final InputStream in) throws MessagingException {
public void load(InputStream is, boolean allowUtf8) throws MessagingException {
try {
final StringBuffer buffer = new StringBuffer(128);
String line;
// loop until we hit the end or a null line
while ((line = readLine(in)) != null) {
while ((line = readLine(is, allowUtf8)) != null) {
// lines beginning with white space get special handling
if (line.startsWith(" ") || line.startsWith("\t")) {
// this gets handled using the logic defined by
Expand All @@ -157,14 +134,12 @@ public void load(final InputStream in) throws MessagingException {
// to the last header in the headers list
if (buffer.length() == 0) {
addHeaderLine(line);
}
else {
} else {
// preserve the line break and append the continuation
buffer.append("\r\n");
buffer.append(line);
}
}
else {
} else {
// if we have a line pending in the buffer, flush it
if (buffer.length() > 0) {
addHeaderLine(buffer.toString());
Expand All @@ -184,6 +159,17 @@ public void load(final InputStream in) throws MessagingException {
}
}

/**
* Read and parse the supplied stream and add all headers to the current
* set.
*
* @param in the RFC822 input stream to load from
* @throws MessagingException if there is a problem pasring the stream
*/
public void load(final InputStream in) throws MessagingException {
load(in, false);
}


/**
* Read a single line from the input stream
Expand All @@ -192,7 +178,7 @@ public void load(final InputStream in) throws MessagingException {
*
* @return The string value of the line (without line separators)
*/
private String readLine(final InputStream in) throws IOException {
private String readLine(final InputStream in, boolean allowUtf8) throws IOException {
final StringBuffer buffer = new StringBuffer(128);

int c;
Expand All @@ -218,7 +204,13 @@ else if (c == '\r') {
return null;
}

return buffer.toString();
String finalString = buffer.toString();

if(allowUtf8){
return new String(finalString.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
}

return finalString;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public class MimeMessage extends Message implements MimePart {
// static used to ensure message ID uniqueness
private static int messageID = 0;

// is UTF-8 allowed in headers?
private boolean allowUtf8 = false;

/**
* Extends {@link javax.mail.Message.RecipientType} to support addition recipient types.
Expand Down Expand Up @@ -1616,7 +1618,7 @@ else if (!contentType.match("message/rfc822")) {
*/
protected InternetHeaders createInternetHeaders(final InputStream in) throws MessagingException {
// internet headers has a constructor for just this purpose
return new InternetHeaders(in);
return new InternetHeaders(in, allowUtf8);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public class MimeUtility {
private static final String MIME_DECODE_TEXT_STRICT = "mail.mime.decodetext.strict";
private static final String MIME_FOLDTEXT = "mail.mime.foldtext";
private static final int FOLD_THRESHOLD = 76;
static final int ALL_ASCII = 1;
static final int MOSTLY_ASCII = 2;
static final int MOSTLY_NONASCII = 3;


private MimeUtility() {
}
Expand Down Expand Up @@ -1292,6 +1296,39 @@ else if (ch == '\n' || ch == '\r') {
}
return newString.toString();
}

/**
* Verifies if a given string contains non US-ASCII characters
*
* @param s The String
* @return ALL_ASCII if all characters in the string belong to the US-ASCII
* character. MOSTLY_ASCII if more than half of the available characters are
* US-ASCII characters. Else MOSTLY_NONASCII.
*/
public static int verifyAscii(String s) {
int ascii_characters = 0;
int non_ascii_characters = 0;

for (int i = 0; i < s.length(); i++) {
if (nonascii((int) s.charAt(i))) {
non_ascii_characters++;
} else {
ascii_characters++;
}
}

if (non_ascii_characters == 0) {
return ALL_ASCII;
} else if (ascii_characters > non_ascii_characters) {
return MOSTLY_ASCII;
} else {
return MOSTLY_NONASCII;
}
}

public static final boolean nonascii (int a){
return a >= 0177 || (a < 040 && a != '\r' && a != '\n' && a != '\t');
}
}


Expand Down