commit
dadf5e0865
18 changed files with 197 additions and 285 deletions
|
@ -88,7 +88,7 @@ public class K9 extends Application {
|
||||||
*
|
*
|
||||||
* @see ApplicationAware
|
* @see ApplicationAware
|
||||||
*/
|
*/
|
||||||
private static List<ApplicationAware> observers = new ArrayList<ApplicationAware>();
|
private static final List<ApplicationAware> observers = new ArrayList<ApplicationAware>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will be {@code true} once the initialization is complete and {@link #notifyObservers()}
|
* This will be {@code true} once the initialization is complete and {@link #notifyObservers()}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.nio.charset.Charset;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -284,10 +284,7 @@ public final class PRNGFixes {
|
||||||
if (serial != null) {
|
if (serial != null) {
|
||||||
result.append(serial);
|
result.append(serial);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
return result.toString().getBytes("UTF-8");
|
return result.toString().getBytes(Charset.forName("UTF-8"));
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new RuntimeException("UTF-8 encoding not supported");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -1890,13 +1891,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
||||||
private InputStream getOpenPgpInputStream() {
|
private InputStream getOpenPgpInputStream() {
|
||||||
String text = buildText(false).getText();
|
String text = buildText(false).getText();
|
||||||
|
|
||||||
InputStream is = null;
|
return new ByteArrayInputStream(text.getBytes(Charset.forName("UTF-8")));
|
||||||
try {
|
|
||||||
is = new ByteArrayInputStream(text.getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
Log.e(K9.LOG_TAG, "UnsupportedEncodingException.", e);
|
|
||||||
}
|
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeOpenPgpMethod(Intent intent) {
|
private void executeOpenPgpMethod(Intent intent) {
|
||||||
|
|
|
@ -3,10 +3,8 @@ package com.fsck.k9.activity.setup;
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
@ -35,6 +33,7 @@ import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.activity.K9Activity;
|
import com.fsck.k9.activity.K9Activity;
|
||||||
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.AuthType;
|
import com.fsck.k9.mail.AuthType;
|
||||||
import com.fsck.k9.mail.ConnectionSecurity;
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
|
@ -281,8 +280,8 @@ public class AccountSetupBasics extends K9Activity
|
||||||
URI incomingUri = null;
|
URI incomingUri = null;
|
||||||
URI outgoingUri = null;
|
URI outgoingUri = null;
|
||||||
try {
|
try {
|
||||||
String userEnc = URLEncoder.encode(user, "UTF-8");
|
String userEnc = UrlEncodingHelper.encodeUtf8(user);
|
||||||
String passwordEnc = URLEncoder.encode(password, "UTF-8");
|
String passwordEnc = UrlEncodingHelper.encodeUtf8(password);
|
||||||
|
|
||||||
String incomingUsername = mProvider.incomingUsernameTemplate;
|
String incomingUsername = mProvider.incomingUsernameTemplate;
|
||||||
incomingUsername = incomingUsername.replaceAll("\\$email", email);
|
incomingUsername = incomingUsername.replaceAll("\\$email", email);
|
||||||
|
@ -338,9 +337,6 @@ public class AccountSetupBasics extends K9Activity
|
||||||
}
|
}
|
||||||
// Check incoming here. Then check outgoing in onActivityResult()
|
// Check incoming here. Then check outgoing in onActivityResult()
|
||||||
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);
|
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This really shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
Log.e(K9.LOG_TAG, "Couldn't urlencode username or password.", enc);
|
|
||||||
} catch (URISyntaxException use) {
|
} catch (URISyntaxException use) {
|
||||||
/*
|
/*
|
||||||
* If there is some problem with the URI we give up and go on to
|
* If there is some problem with the URI we give up and go on to
|
||||||
|
|
|
@ -42,9 +42,9 @@ public class EmailProviderCache {
|
||||||
|
|
||||||
|
|
||||||
private String mAccountUuid;
|
private String mAccountUuid;
|
||||||
private Map<Long, Map<String, String>> mMessageCache = new HashMap<Long, Map<String, String>>();
|
private final Map<Long, Map<String, String>> mMessageCache = new HashMap<Long, Map<String, String>>();
|
||||||
private Map<Long, Map<String, String>> mThreadCache = new HashMap<Long, Map<String, String>>();
|
private final Map<Long, Map<String, String>> mThreadCache = new HashMap<Long, Map<String, String>>();
|
||||||
private Map<Long, Long> mHiddenMessageCache = new HashMap<Long, Long>();
|
private final Map<Long, Long> mHiddenMessageCache = new HashMap<Long, Long>();
|
||||||
|
|
||||||
|
|
||||||
private EmailProviderCache(String accountUuid) {
|
private EmailProviderCache(String accountUuid) {
|
||||||
|
|
|
@ -319,7 +319,7 @@ public class MessagingController implements Runnable {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Key is accountNumber
|
// Key is accountNumber
|
||||||
private ConcurrentHashMap<Integer, NotificationData> notificationData = new ConcurrentHashMap<Integer, NotificationData>();
|
private final ConcurrentMap<Integer, NotificationData> notificationData = new ConcurrentHashMap<Integer, NotificationData>();
|
||||||
|
|
||||||
private static final Flag[] SYNC_FLAGS = new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED };
|
private static final Flag[] SYNC_FLAGS = new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED };
|
||||||
|
|
||||||
|
|
33
src/com/fsck/k9/helper/UrlEncodingHelper.java
Normal file
33
src/com/fsck/k9/helper/UrlEncodingHelper.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the java.net.URLDecoder to avoid unhelpful checked exceptions.
|
||||||
|
*/
|
||||||
|
public class UrlEncodingHelper {
|
||||||
|
|
||||||
|
public static String decodeUtf8(String s) {
|
||||||
|
try {
|
||||||
|
return URLDecoder.decode(s, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
/*
|
||||||
|
* This is impossible, UTF-8 is always supported
|
||||||
|
*/
|
||||||
|
throw new RuntimeException("UTF-8 not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeUtf8(String s) {
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(s, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
/*
|
||||||
|
* This is impossible, UTF-8 is always supported
|
||||||
|
*/
|
||||||
|
throw new RuntimeException("UTF-8 not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ import com.fsck.k9.mail.filter.Base64;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -189,8 +189,8 @@ public class Utility {
|
||||||
* hundreds of times in places that slow down the UI, so it helps.
|
* hundreds of times in places that slow down the UI, so it helps.
|
||||||
*/
|
*/
|
||||||
public static String fastUrlDecode(String s) {
|
public static String fastUrlDecode(String s) {
|
||||||
try {
|
|
||||||
byte[] bytes = s.getBytes("UTF-8");
|
byte[] bytes = s.getBytes(Charset.forName("UTF-8"));
|
||||||
byte ch;
|
byte ch;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int i = 0, count = bytes.length; i < count; i++) {
|
for (int i = 0, count = bytes.length; i < count; i++) {
|
||||||
|
@ -213,10 +213,8 @@ public class Utility {
|
||||||
}
|
}
|
||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
return new String(bytes, 0, length, "UTF-8");
|
return new String(bytes, 0, length, Charset.forName("UTF-8"));
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
package com.fsck.k9.mail.filter;
|
package com.fsck.k9.mail.filter;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides Base64 encoding and decoding as defined by RFC 2045.
|
* Provides Base64 encoding and decoding as defined by RFC 2045.
|
||||||
|
@ -225,12 +225,8 @@ public class Base64 {
|
||||||
}
|
}
|
||||||
this.decodeSize = encodeSize - 1;
|
this.decodeSize = encodeSize - 1;
|
||||||
if (containsBase64Byte(lineSeparator)) {
|
if (containsBase64Byte(lineSeparator)) {
|
||||||
String sep;
|
String sep = new String(lineSeparator, Charset.forName("UTF-8"));
|
||||||
try {
|
|
||||||
sep = new String(lineSeparator, "UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
sep = new String(lineSeparator);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]");
|
throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import org.apache.james.mime4j.codec.Base64InputStream;
|
import org.apache.james.mime4j.codec.Base64InputStream;
|
||||||
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
|
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
|
||||||
import org.apache.james.mime4j.util.CharsetUtil;
|
import org.apache.james.mime4j.util.CharsetUtil;
|
||||||
|
@ -30,12 +31,7 @@ public class DecoderUtil {
|
||||||
* @return the decoded string.
|
* @return the decoded string.
|
||||||
*/
|
*/
|
||||||
private static String decodeB(String encodedWord, String charset) {
|
private static String decodeB(String encodedWord, String charset) {
|
||||||
byte[] bytes;
|
byte[] bytes = encodedWord.getBytes(Charset.forName("US-ASCII"));
|
||||||
try {
|
|
||||||
bytes = encodedWord.getBytes("US-ASCII");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Base64InputStream is = new Base64InputStream(new ByteArrayInputStream(bytes));
|
Base64InputStream is = new Base64InputStream(new ByteArrayInputStream(bytes));
|
||||||
try {
|
try {
|
||||||
|
@ -68,12 +64,7 @@ public class DecoderUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes;
|
byte[] bytes = sb.toString().getBytes(Charset.forName("US-ASCII"));
|
||||||
try {
|
|
||||||
bytes = sb.toString().getBytes("US-ASCII");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
QuotedPrintableInputStream is = new QuotedPrintableInputStream(new ByteArrayInputStream(bytes));
|
QuotedPrintableInputStream is = new QuotedPrintableInputStream(new ByteArrayInputStream(bytes));
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
@ -16,8 +15,6 @@ import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.nio.charset.CharacterCodingException;
|
import java.nio.charset.CharacterCodingException;
|
||||||
|
@ -31,6 +28,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -64,6 +62,7 @@ import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
import com.fsck.k9.helper.StringUtils;
|
import com.fsck.k9.helper.StringUtils;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager;
|
import com.fsck.k9.helper.power.TracingPowerManager;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
||||||
|
@ -198,31 +197,26 @@ public class ImapStore extends Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imapUri.getUserInfo() != null) {
|
if (imapUri.getUserInfo() != null) {
|
||||||
try {
|
String userinfo = imapUri.getUserInfo();
|
||||||
String userinfo = imapUri.getUserInfo();
|
String[] userInfoParts = userinfo.split(":");
|
||||||
String[] userInfoParts = userinfo.split(":");
|
|
||||||
|
|
||||||
if (userinfo.endsWith(":")) {
|
if (userinfo.endsWith(":")) {
|
||||||
// Password is empty. This can only happen after an account was imported.
|
// Password is empty. This can only happen after an account was imported.
|
||||||
authenticationType = AuthType.valueOf(userInfoParts[0]);
|
authenticationType = AuthType.valueOf(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
} else if (userInfoParts.length == 2) {
|
} else if (userInfoParts.length == 2) {
|
||||||
authenticationType = AuthType.PLAIN;
|
authenticationType = AuthType.PLAIN;
|
||||||
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
|
||||||
password = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
} else if (userInfoParts.length == 3) {
|
} else if (userInfoParts.length == 3) {
|
||||||
authenticationType = AuthType.valueOf(userInfoParts[0]);
|
authenticationType = AuthType.valueOf(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
|
|
||||||
if (AuthType.EXTERNAL == authenticationType) {
|
if (AuthType.EXTERNAL == authenticationType) {
|
||||||
clientCertificateAlias = URLDecoder.decode(userInfoParts[2], "UTF-8");
|
clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[2]);
|
||||||
} else {
|
} else {
|
||||||
password = URLDecoder.decode(userInfoParts[2], "UTF-8");
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[2]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
throw new IllegalArgumentException("Couldn't urldecode username or password.", enc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,19 +254,11 @@ public class ImapStore extends Store {
|
||||||
* @see ImapStore#decodeUri(String)
|
* @see ImapStore#decodeUri(String)
|
||||||
*/
|
*/
|
||||||
public static String createUri(ServerSettings server) {
|
public static String createUri(ServerSettings server) {
|
||||||
String userEnc;
|
String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
|
||||||
String passwordEnc;
|
String passwordEnc = (server.password != null) ?
|
||||||
String clientCertificateAliasEnc;
|
UrlEncodingHelper.encodeUtf8(server.password) : "";
|
||||||
try {
|
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
||||||
userEnc = URLEncoder.encode(server.username, "UTF-8");
|
UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
|
||||||
passwordEnc = (server.password != null) ?
|
|
||||||
URLEncoder.encode(server.password, "UTF-8") : "";
|
|
||||||
clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
|
||||||
URLEncoder.encode(server.clientCertificateAlias, "UTF-8") : "";
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalArgumentException("Could not encode username or password", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
String scheme;
|
String scheme;
|
||||||
switch (server.connectionSecurity) {
|
switch (server.connectionSecurity) {
|
||||||
|
@ -439,7 +425,7 @@ public class ImapStore extends Store {
|
||||||
|
|
||||||
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
|
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
|
||||||
|
|
||||||
private LinkedList<ImapConnection> mConnections =
|
private final Deque<ImapConnection> mConnections =
|
||||||
new LinkedList<ImapConnection>();
|
new LinkedList<ImapConnection>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -453,7 +439,7 @@ public class ImapStore extends Store {
|
||||||
* requests. This cache lets us make sure we always reuse, if possible, for a given
|
* requests. This cache lets us make sure we always reuse, if possible, for a given
|
||||||
* folder name.
|
* folder name.
|
||||||
*/
|
*/
|
||||||
private HashMap<String, ImapFolder> mFolderCache = new HashMap<String, ImapFolder>();
|
private final Map<String, ImapFolder> mFolderCache = new HashMap<String, ImapFolder>();
|
||||||
|
|
||||||
public ImapStore(Account account) throws MessagingException {
|
public ImapStore(Account account) throws MessagingException {
|
||||||
super(account);
|
super(account);
|
||||||
|
@ -756,18 +742,10 @@ public class ImapStore extends Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String encodeFolderName(String name) {
|
private String encodeFolderName(String name) {
|
||||||
try {
|
ByteBuffer bb = mModifiedUtf7Charset.encode(name);
|
||||||
ByteBuffer bb = mModifiedUtf7Charset.encode(name);
|
byte[] b = new byte[bb.limit()];
|
||||||
byte[] b = new byte[bb.limit()];
|
bb.get(b);
|
||||||
bb.get(b);
|
return new String(b, Charset.forName("US-ASCII"));
|
||||||
return new String(b, "US-ASCII");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
/*
|
|
||||||
* The only thing that can throw this is getBytes("US-ASCII") and if US-ASCII doesn't
|
|
||||||
* exist we're totally screwed.
|
|
||||||
*/
|
|
||||||
throw new RuntimeException("Unable to encode folder name: " + name, uee);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String decodeFolderName(String name) throws CharacterCodingException {
|
private String decodeFolderName(String name) throws CharacterCodingException {
|
||||||
|
@ -775,18 +753,11 @@ public class ImapStore extends Store {
|
||||||
* Convert the encoded name to US-ASCII, then pass it through the modified UTF-7
|
* Convert the encoded name to US-ASCII, then pass it through the modified UTF-7
|
||||||
* decoder and return the Unicode String.
|
* decoder and return the Unicode String.
|
||||||
*/
|
*/
|
||||||
try {
|
// Make sure the decoder throws an exception if it encounters an invalid encoding.
|
||||||
// Make sure the decoder throws an exception if it encounters an invalid encoding.
|
CharsetDecoder decoder = mModifiedUtf7Charset.newDecoder().onMalformedInput(CodingErrorAction.REPORT);
|
||||||
CharsetDecoder decoder = mModifiedUtf7Charset.newDecoder().onMalformedInput(CodingErrorAction.REPORT);
|
CharBuffer cb = decoder.decode(ByteBuffer.wrap(name.getBytes(Charset.forName("US-ASCII"))));
|
||||||
CharBuffer cb = decoder.decode(ByteBuffer.wrap(name.getBytes("US-ASCII")));
|
return cb.toString();
|
||||||
return cb.toString();
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
/*
|
|
||||||
* The only thing that can throw this is getBytes("US-ASCII") and if US-ASCII doesn't
|
|
||||||
* exist we're totally screwed.
|
|
||||||
*/
|
|
||||||
throw new RuntimeException("Unable to decode folder name: " + name, uee);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3467,7 +3438,7 @@ public class ImapStore extends Store {
|
||||||
final PushReceiver mReceiver;
|
final PushReceiver mReceiver;
|
||||||
private long lastRefresh = -1;
|
private long lastRefresh = -1;
|
||||||
|
|
||||||
HashMap<String, ImapFolderPusher> folderPushers = new HashMap<String, ImapFolderPusher>();
|
final Map<String, ImapFolderPusher> folderPushers = new HashMap<String, ImapFolderPusher>();
|
||||||
|
|
||||||
public ImapPusher(ImapStore store, PushReceiver receiver) {
|
public ImapPusher(ImapStore store, PushReceiver receiver) {
|
||||||
mStore = store;
|
mStore = store;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.filter.Base64;
|
import com.fsck.k9.mail.filter.Base64;
|
||||||
|
@ -115,28 +116,23 @@ public class Pop3Store extends Store {
|
||||||
|
|
||||||
AuthType authType = AuthType.PLAIN;
|
AuthType authType = AuthType.PLAIN;
|
||||||
if (pop3Uri.getUserInfo() != null) {
|
if (pop3Uri.getUserInfo() != null) {
|
||||||
try {
|
int userIndex = 0, passwordIndex = 1;
|
||||||
int userIndex = 0, passwordIndex = 1;
|
String userinfo = pop3Uri.getUserInfo();
|
||||||
String userinfo = pop3Uri.getUserInfo();
|
String[] userInfoParts = userinfo.split(":");
|
||||||
String[] userInfoParts = userinfo.split(":");
|
if (userInfoParts.length > 2 || userinfo.endsWith(":") ) {
|
||||||
if (userInfoParts.length > 2 || userinfo.endsWith(":") ) {
|
// If 'userinfo' ends with ":" the password is empty. This can only happen
|
||||||
// If 'userinfo' ends with ":" the password is empty. This can only happen
|
// after an account was imported (so authType and username are present).
|
||||||
// after an account was imported (so authType and username are present).
|
userIndex++;
|
||||||
userIndex++;
|
passwordIndex++;
|
||||||
passwordIndex++;
|
authType = AuthType.valueOf(userInfoParts[0]);
|
||||||
authType = AuthType.valueOf(userInfoParts[0]);
|
}
|
||||||
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[userIndex]);
|
||||||
|
if (userInfoParts.length > passwordIndex) {
|
||||||
|
if (authType == AuthType.EXTERNAL) {
|
||||||
|
clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[passwordIndex]);
|
||||||
|
} else {
|
||||||
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[passwordIndex]);
|
||||||
}
|
}
|
||||||
username = URLDecoder.decode(userInfoParts[userIndex], "UTF-8");
|
|
||||||
if (userInfoParts.length > passwordIndex) {
|
|
||||||
if (authType == AuthType.EXTERNAL) {
|
|
||||||
clientCertificateAlias = URLDecoder.decode(userInfoParts[passwordIndex], "UTF-8");
|
|
||||||
} else {
|
|
||||||
password = URLDecoder.decode(userInfoParts[passwordIndex], "UTF-8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
throw new IllegalArgumentException("Couldn't urldecode username or password.", enc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,19 +152,11 @@ public class Pop3Store extends Store {
|
||||||
* @see Pop3Store#decodeUri(String)
|
* @see Pop3Store#decodeUri(String)
|
||||||
*/
|
*/
|
||||||
public static String createUri(ServerSettings server) {
|
public static String createUri(ServerSettings server) {
|
||||||
String userEnc;
|
String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
|
||||||
String passwordEnc;
|
String passwordEnc = (server.password != null) ?
|
||||||
String clientCertificateAliasEnc;
|
UrlEncodingHelper.encodeUtf8(server.password) : "";
|
||||||
try {
|
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
||||||
userEnc = URLEncoder.encode(server.username, "UTF-8");
|
UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
|
||||||
passwordEnc = (server.password != null) ?
|
|
||||||
URLEncoder.encode(server.password, "UTF-8") : "";
|
|
||||||
clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
|
||||||
URLEncoder.encode(server.clientCertificateAlias, "UTF-8") : "";
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalArgumentException("Could not encode username or password", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
String scheme;
|
String scheme;
|
||||||
switch (server.connectionSecurity) {
|
switch (server.connectionSecurity) {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.util.Log;
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
|
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
||||||
|
@ -40,8 +42,6 @@ import javax.xml.parsers.SAXParserFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
@ -139,22 +139,17 @@ public class WebDavStore extends Store {
|
||||||
|
|
||||||
String userInfo = webDavUri.getUserInfo();
|
String userInfo = webDavUri.getUserInfo();
|
||||||
if (userInfo != null) {
|
if (userInfo != null) {
|
||||||
try {
|
String[] userInfoParts = userInfo.split(":");
|
||||||
String[] userInfoParts = userInfo.split(":");
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
String userParts[] = username.split("\\\\", 2);
|
||||||
String userParts[] = username.split("\\\\", 2);
|
|
||||||
|
|
||||||
if (userParts.length > 1) {
|
if (userParts.length > 1) {
|
||||||
alias = userParts[1];
|
alias = userParts[1];
|
||||||
} else {
|
} else {
|
||||||
alias = username;
|
alias = username;
|
||||||
}
|
}
|
||||||
if (userInfoParts.length > 1) {
|
if (userInfoParts.length > 1) {
|
||||||
password = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
}
|
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
throw new IllegalArgumentException("Couldn't urldecode username or password.", enc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,16 +189,9 @@ public class WebDavStore extends Store {
|
||||||
* @see WebDavStore#decodeUri(String)
|
* @see WebDavStore#decodeUri(String)
|
||||||
*/
|
*/
|
||||||
public static String createUri(ServerSettings server) {
|
public static String createUri(ServerSettings server) {
|
||||||
String userEnc;
|
String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
|
||||||
String passwordEnc;
|
String passwordEnc = (server.password != null) ?
|
||||||
try {
|
UrlEncodingHelper.encodeUtf8(server.password) : "";
|
||||||
userEnc = URLEncoder.encode(server.username, "UTF-8");
|
|
||||||
passwordEnc = (server.password != null) ?
|
|
||||||
URLEncoder.encode(server.password, "UTF-8") : "";
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalArgumentException("Could not encode username or password", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
String scheme;
|
String scheme;
|
||||||
switch (server.connectionSecurity) {
|
switch (server.connectionSecurity) {
|
||||||
|
@ -479,7 +467,6 @@ public class WebDavStore extends Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folderSlash > 0) {
|
if (folderSlash > 0) {
|
||||||
String folderName;
|
|
||||||
String fullPathName;
|
String fullPathName;
|
||||||
|
|
||||||
// Removes the final slash if present
|
// Removes the final slash if present
|
||||||
|
@ -489,17 +476,8 @@ public class WebDavStore extends Store {
|
||||||
fullPathName = folderUrl.substring(folderSlash + 1);
|
fullPathName = folderUrl.substring(folderSlash + 1);
|
||||||
|
|
||||||
// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
|
// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
|
||||||
try {
|
|
||||||
folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
/**
|
|
||||||
* If we don't support UTF-8 there's a problem, don't decode
|
|
||||||
* it then
|
|
||||||
*/
|
|
||||||
folderName = fullPathName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return folderName;
|
return UrlEncodingHelper.decodeUtf8(fullPathName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1258,21 +1236,16 @@ public class WebDavStore extends Store {
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
|
|
||||||
String encodedName = "";
|
String encodedName = "";
|
||||||
try {
|
String[] urlParts = name.split("/");
|
||||||
String[] urlParts = name.split("/");
|
String url = "";
|
||||||
String url = "";
|
for (int i = 0, count = urlParts.length; i < count; i++) {
|
||||||
for (int i = 0, count = urlParts.length; i < count; i++) {
|
if (i != 0) {
|
||||||
if (i != 0) {
|
url = url + "/" + UrlEncodingHelper.encodeUtf8(urlParts[i]);
|
||||||
url = url + "/" + java.net.URLEncoder.encode(urlParts[i], "UTF-8");
|
} else {
|
||||||
} else {
|
url = UrlEncodingHelper.encodeUtf8(urlParts[i]);
|
||||||
url = java.net.URLEncoder.encode(urlParts[i], "UTF-8");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
encodedName = url;
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
Log.e(K9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
|
|
||||||
encodedName = name;
|
|
||||||
}
|
}
|
||||||
|
encodedName = url;
|
||||||
|
|
||||||
encodedName = encodedName.replaceAll("\\+", "%20");
|
encodedName = encodedName.replaceAll("\\+", "%20");
|
||||||
|
|
||||||
|
@ -1910,7 +1883,7 @@ public class WebDavStore extends Store {
|
||||||
if (!messageURL.endsWith("/")) {
|
if (!messageURL.endsWith("/")) {
|
||||||
messageURL += "/";
|
messageURL += "/";
|
||||||
}
|
}
|
||||||
messageURL += URLEncoder.encode(message.getUid() + ":" + System.currentTimeMillis() + ".eml", "UTF-8");
|
messageURL += UrlEncodingHelper.encodeUtf8(message.getUid() + ":" + System.currentTimeMillis() + ".eml");
|
||||||
|
|
||||||
Log.i(K9.LOG_TAG, "Uploading message as " + messageURL);
|
Log.i(K9.LOG_TAG, "Uploading message as " + messageURL);
|
||||||
|
|
||||||
|
@ -1997,12 +1970,9 @@ public class WebDavStore extends Store {
|
||||||
* We have to decode, then encode the URL because Exchange likes to not properly encode all characters
|
* We have to decode, then encode the URL because Exchange likes to not properly encode all characters
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
end = java.net.URLDecoder.decode(end, "UTF-8");
|
end = UrlEncodingHelper.decodeUtf8(end);
|
||||||
end = java.net.URLEncoder.encode(end, "UTF-8");
|
end = UrlEncodingHelper.encodeUtf8(end);
|
||||||
end = end.replaceAll("\\+", "%20");
|
end = end.replaceAll("\\+", "%20");
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
Log.e(K9.LOG_TAG, "UnsupportedEncodingException caught in setUrl: " + uee + "\nTrace: "
|
|
||||||
+ processException(uee));
|
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
Log.e(K9.LOG_TAG, "IllegalArgumentException caught in setUrl: " + iae + "\nTrace: "
|
Log.e(K9.LOG_TAG, "IllegalArgumentException caught in setUrl: " + iae + "\nTrace: "
|
||||||
+ processException(iae));
|
+ processException(iae));
|
||||||
|
@ -2405,13 +2375,10 @@ public class WebDavStore extends Store {
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
if (length > 3) {
|
if (length > 3) {
|
||||||
end = java.net.URLDecoder.decode(end, "UTF-8");
|
end = UrlEncodingHelper.decodeUtf8(end);
|
||||||
end = java.net.URLEncoder.encode(end, "UTF-8");
|
end = UrlEncodingHelper.encodeUtf8(end);
|
||||||
end = end.replaceAll("\\+", "%20");
|
end = end.replaceAll("\\+", "%20");
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
Log.e(K9.LOG_TAG, "UnsupportedEncodingException caught in HttpGeneric(String uri): " + uee
|
|
||||||
+ "\nTrace: " + processException(uee));
|
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
Log.e(K9.LOG_TAG, "IllegalArgumentException caught in HttpGeneric(String uri): " + iae + "\nTrace: "
|
Log.e(K9.LOG_TAG, "IllegalArgumentException caught in HttpGeneric(String uri): " + iae + "\nTrace: "
|
||||||
+ processException(iae));
|
+ processException(iae));
|
||||||
|
|
|
@ -3,8 +3,6 @@ package com.fsck.k9.mail.store.local;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -28,6 +26,7 @@ import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.Preferences;
|
import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
import com.fsck.k9.helper.StringUtils;
|
import com.fsck.k9.helper.StringUtils;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
import com.fsck.k9.mail.Folder;
|
import com.fsck.k9.mail.Folder;
|
||||||
|
@ -101,7 +100,7 @@ public class LocalStore extends Store implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Maximum number of messages to perform flag updates on at once.
|
* Maximum number of messages to perform flag updates on at once.
|
||||||
*
|
*
|
||||||
* @see #setFlag(List, Flag, boolean, boolean)
|
* @see #setFlag(List, Flag, boolean)
|
||||||
*/
|
*/
|
||||||
private static final int FLAG_UPDATE_BATCH_SIZE = 500;
|
private static final int FLAG_UPDATE_BATCH_SIZE = 500;
|
||||||
|
|
||||||
|
@ -460,23 +459,19 @@ public class LocalStore extends Store implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPendingCommand(PendingCommand command) throws UnavailableStorageException {
|
public void addPendingCommand(PendingCommand command) throws UnavailableStorageException {
|
||||||
try {
|
for (int i = 0; i < command.arguments.length; i++) {
|
||||||
for (int i = 0; i < command.arguments.length; i++) {
|
command.arguments[i] = UrlEncodingHelper.encodeUtf8(command.arguments[i]);
|
||||||
command.arguments[i] = URLEncoder.encode(command.arguments[i], "UTF-8");
|
|
||||||
}
|
|
||||||
final ContentValues cv = new ContentValues();
|
|
||||||
cv.put("command", command.command);
|
|
||||||
cv.put("arguments", Utility.combine(command.arguments, ','));
|
|
||||||
database.execute(false, new DbCallback<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void doDbWork(final SQLiteDatabase db) throws WrappedException {
|
|
||||||
db.insert("pending_commands", "command", cv);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
throw new Error("Aparently UTF-8 has been lost to the annals of history.");
|
|
||||||
}
|
}
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
cv.put("command", command.command);
|
||||||
|
cv.put("arguments", Utility.combine(command.arguments, ','));
|
||||||
|
database.execute(false, new DbCallback<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void doDbWork(final SQLiteDatabase db) throws WrappedException {
|
||||||
|
db.insert("pending_commands", "command", cv);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePendingCommand(final PendingCommand command) throws UnavailableStorageException {
|
public void removePendingCommand(final PendingCommand command) throws UnavailableStorageException {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.Message.RecipientType;
|
import com.fsck.k9.mail.Message.RecipientType;
|
||||||
|
@ -23,7 +24,6 @@ import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -92,28 +92,23 @@ public class SmtpTransport extends Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smtpUri.getUserInfo() != null) {
|
if (smtpUri.getUserInfo() != null) {
|
||||||
try {
|
String[] userInfoParts = smtpUri.getUserInfo().split(":");
|
||||||
String[] userInfoParts = smtpUri.getUserInfo().split(":");
|
if (userInfoParts.length == 1) {
|
||||||
if (userInfoParts.length == 1) {
|
authType = AuthType.PLAIN;
|
||||||
authType = AuthType.PLAIN;
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
} else if (userInfoParts.length == 2) {
|
||||||
} else if (userInfoParts.length == 2) {
|
authType = AuthType.PLAIN;
|
||||||
authType = AuthType.PLAIN;
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
password = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
} else if (userInfoParts.length == 3) {
|
||||||
} else if (userInfoParts.length == 3) {
|
// NOTE: In SmptTransport URIs, the authType comes last!
|
||||||
// NOTE: In SmptTransport URIs, the authType comes last!
|
authType = AuthType.valueOf(userInfoParts[2]);
|
||||||
authType = AuthType.valueOf(userInfoParts[2]);
|
username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
|
||||||
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
if (authType == AuthType.EXTERNAL) {
|
||||||
if (authType == AuthType.EXTERNAL) {
|
clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
clientCertificateAlias = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
} else {
|
||||||
} else {
|
password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
|
||||||
password = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
throw new IllegalArgumentException("Couldn't urldecode username or password.", enc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,20 +128,12 @@ public class SmtpTransport extends Transport {
|
||||||
* @see SmtpTransport#decodeUri(String)
|
* @see SmtpTransport#decodeUri(String)
|
||||||
*/
|
*/
|
||||||
public static String createUri(ServerSettings server) {
|
public static String createUri(ServerSettings server) {
|
||||||
String userEnc;
|
String userEnc = (server.username != null) ?
|
||||||
String passwordEnc;
|
UrlEncodingHelper.encodeUtf8(server.username) : "";
|
||||||
String clientCertificateAliasEnc;
|
String passwordEnc = (server.password != null) ?
|
||||||
try {
|
UrlEncodingHelper.encodeUtf8(server.password) : "";
|
||||||
userEnc = (server.username != null) ?
|
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
||||||
URLEncoder.encode(server.username, "UTF-8") : "";
|
UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
|
||||||
passwordEnc = (server.password != null) ?
|
|
||||||
URLEncoder.encode(server.password, "UTF-8") : "";
|
|
||||||
clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
|
|
||||||
URLEncoder.encode(server.clientCertificateAlias, "UTF-8") : "";
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalArgumentException("Could not encode username or password", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
String scheme;
|
String scheme;
|
||||||
switch (server.connectionSecurity) {
|
switch (server.connectionSecurity) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.database.sqlite.SQLiteStatement;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -59,11 +60,11 @@ public class Storage implements SharedPreferences {
|
||||||
if (transportUriStr != null) {
|
if (transportUriStr != null) {
|
||||||
String[] userInfoParts = uri.getUserInfo().split(":");
|
String[] userInfoParts = uri.getUserInfo().split(":");
|
||||||
|
|
||||||
String usernameEnc = URLEncoder.encode(userInfoParts[0], "UTF-8");
|
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
|
||||||
String passwordEnc = "";
|
String passwordEnc = "";
|
||||||
String authType = "";
|
String authType = "";
|
||||||
if (userInfoParts.length > 1) {
|
if (userInfoParts.length > 1) {
|
||||||
passwordEnc = ":" + URLEncoder.encode(userInfoParts[1], "UTF-8");
|
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
|
||||||
}
|
}
|
||||||
if (userInfoParts.length > 2) {
|
if (userInfoParts.length > 2) {
|
||||||
authType = ":" + userInfoParts[2];
|
authType = ":" + userInfoParts[2];
|
||||||
|
@ -83,34 +84,34 @@ public class Storage implements SharedPreferences {
|
||||||
if (storeUriStr.startsWith("imap")) {
|
if (storeUriStr.startsWith("imap")) {
|
||||||
String[] userInfoParts = uri.getUserInfo().split(":");
|
String[] userInfoParts = uri.getUserInfo().split(":");
|
||||||
if (userInfoParts.length == 2) {
|
if (userInfoParts.length == 2) {
|
||||||
String usernameEnc = URLEncoder.encode(userInfoParts[0], "UTF-8");
|
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
|
||||||
String passwordEnc = URLEncoder.encode(userInfoParts[1], "UTF-8");
|
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
|
||||||
|
|
||||||
newUserInfo = usernameEnc + ":" + passwordEnc;
|
newUserInfo = usernameEnc + ":" + passwordEnc;
|
||||||
} else {
|
} else {
|
||||||
String authType = userInfoParts[0];
|
String authType = userInfoParts[0];
|
||||||
String usernameEnc = URLEncoder.encode(userInfoParts[1], "UTF-8");
|
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
|
||||||
String passwordEnc = URLEncoder.encode(userInfoParts[2], "UTF-8");
|
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[2]);
|
||||||
|
|
||||||
newUserInfo = authType + ":" + usernameEnc + ":" + passwordEnc;
|
newUserInfo = authType + ":" + usernameEnc + ":" + passwordEnc;
|
||||||
}
|
}
|
||||||
} else if (storeUriStr.startsWith("pop3")) {
|
} else if (storeUriStr.startsWith("pop3")) {
|
||||||
String[] userInfoParts = uri.getUserInfo().split(":", 2);
|
String[] userInfoParts = uri.getUserInfo().split(":", 2);
|
||||||
String usernameEnc = URLEncoder.encode(userInfoParts[0], "UTF-8");
|
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
|
||||||
|
|
||||||
String passwordEnc = "";
|
String passwordEnc = "";
|
||||||
if (userInfoParts.length > 1) {
|
if (userInfoParts.length > 1) {
|
||||||
passwordEnc = ":" + URLEncoder.encode(userInfoParts[1], "UTF-8");
|
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
newUserInfo = usernameEnc + passwordEnc;
|
newUserInfo = usernameEnc + passwordEnc;
|
||||||
} else if (storeUriStr.startsWith("webdav")) {
|
} else if (storeUriStr.startsWith("webdav")) {
|
||||||
String[] userInfoParts = uri.getUserInfo().split(":", 2);
|
String[] userInfoParts = uri.getUserInfo().split(":", 2);
|
||||||
String usernameEnc = URLEncoder.encode(userInfoParts[0], "UTF-8");
|
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
|
||||||
|
|
||||||
String passwordEnc = "";
|
String passwordEnc = "";
|
||||||
if (userInfoParts.length > 1) {
|
if (userInfoParts.length > 1) {
|
||||||
passwordEnc = ":" + URLEncoder.encode(userInfoParts[1], "UTF-8");
|
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
newUserInfo = usernameEnc + passwordEnc;
|
newUserInfo = usernameEnc + passwordEnc;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
@ -279,12 +280,7 @@ public class MessageOpenPgpView extends LinearLayout {
|
||||||
String accName = OpenPgpApiHelper.buildAccountName(identity);
|
String accName = OpenPgpApiHelper.buildAccountName(identity);
|
||||||
intent.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, accName);
|
intent.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, accName);
|
||||||
|
|
||||||
InputStream is = null;
|
InputStream is = new ByteArrayInputStream(mData.getBytes(Charset.forName("UTF-8")));
|
||||||
try {
|
|
||||||
is = new ByteArrayInputStream(mData.getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
Log.e(K9.LOG_TAG, "UnsupportedEncodingException.", e);
|
|
||||||
}
|
|
||||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
|
||||||
DecryptVerifyCallback callback = new DecryptVerifyCallback(os, REQUEST_CODE_DECRYPT_VERIFY);
|
DecryptVerifyCallback callback = new DecryptVerifyCallback(os, REQUEST_CODE_DECRYPT_VERIFY);
|
||||||
|
|
|
@ -47,6 +47,7 @@ import com.fsck.k9.fragment.MessageViewFragment;
|
||||||
import com.fsck.k9.helper.ClipboardManager;
|
import com.fsck.k9.helper.ClipboardManager;
|
||||||
import com.fsck.k9.helper.Contacts;
|
import com.fsck.k9.helper.Contacts;
|
||||||
import com.fsck.k9.helper.HtmlConverter;
|
import com.fsck.k9.helper.HtmlConverter;
|
||||||
|
import com.fsck.k9.helper.UrlEncodingHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
|
@ -790,7 +791,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
|
||||||
// Try to get the filename from the URL
|
// Try to get the filename from the URL
|
||||||
int start = path.lastIndexOf("/");
|
int start = path.lastIndexOf("/");
|
||||||
if (start != -1 && start + 1 < path.length()) {
|
if (start != -1 && start + 1 < path.length()) {
|
||||||
filename = URLDecoder.decode(path.substring(start + 1), "UTF-8");
|
filename = UrlEncodingHelper.decodeUtf8(path.substring(start + 1));
|
||||||
} else {
|
} else {
|
||||||
// Use a dummy filename if necessary
|
// Use a dummy filename if necessary
|
||||||
filename = "saved_image";
|
filename = "saved_image";
|
||||||
|
|
Loading…
Reference in a new issue