am f50c7fb0: Merge change 2252 into donut
Merge commit 'f50c7fb0842c403edc47ea7258af06e7fd1f262c'
* commit 'f50c7fb0842c403edc47ea7258af06e7fd1f262c':
Fix the java.lang.StringIndexOutOfBoundsException that occurs when an SMTP server closes the connection early or returns an empty line.
diff --git a/src/com/android/email/mail/store/Pop3Store.java b/src/com/android/email/mail/store/Pop3Store.java
index 25e2e1c..8104e85 100644
--- a/src/com/android/email/mail/store/Pop3Store.java
+++ b/src/com/android/email/mail/store/Pop3Store.java
@@ -511,6 +511,9 @@
*/
public boolean parseSingleLine(String response) {
mErr = false;
+ if (response == null || response.length() == 0) {
+ return false;
+ }
char first = response.charAt(0);
if (first == '+') {
String[] uidParts = response.split(" +");
@@ -536,6 +539,9 @@
*/
public boolean parseMultiLine(String response) {
mErr = false;
+ if (response == null || response.length() == 0) {
+ return false;
+ }
char first = response.charAt(0);
if (first == '.') {
mEndOfMessage = true;
diff --git a/src/com/android/email/mail/transport/SmtpSender.java b/src/com/android/email/mail/transport/SmtpSender.java
index 9aa4f14..b7f585a 100644
--- a/src/com/android/email/mail/transport/SmtpSender.java
+++ b/src/com/android/email/mail/transport/SmtpSender.java
@@ -280,9 +280,11 @@
result += line.substring(3);
}
- char c = result.charAt(0);
- if ((c == '4') || (c == '5')) {
- throw new MessagingException(result);
+ if (result.length() > 0) {
+ char c = result.charAt(0);
+ if ((c == '4') || (c == '5')) {
+ throw new MessagingException(result);
+ }
}
return result;
diff --git a/tests/src/com/android/email/mail/store/Pop3StoreUnitTests.java b/tests/src/com/android/email/mail/store/Pop3StoreUnitTests.java
index 4230871..da8fe43 100644
--- a/tests/src/com/android/email/mail/store/Pop3StoreUnitTests.java
+++ b/tests/src/com/android/email/mail/store/Pop3StoreUnitTests.java
@@ -105,6 +105,42 @@
}
/**
+ * Test various rainy-day operations of the UIDL parser for multi-line responses
+ * TODO other malformed responses
+ */
+ public void testUIDLParserMultiFail() {
+ // multi-line mode
+ Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
+
+ // Test with null input
+ boolean result;
+ result = parser.parseMultiLine(null);
+ assertFalse(result);
+
+ // Test with empty input
+ result = parser.parseMultiLine("");
+ assertFalse(result);
+ }
+
+ /**
+ * Test various rainy-day operations of the UIDL parser for single-line responses
+ * TODO other malformed responses
+ */
+ public void testUIDLParserSingleFail() {
+ // single-line mode
+ Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
+
+ // Test with null input
+ boolean result;
+ result = parser.parseSingleLine(null);
+ assertFalse(result);
+
+ // Test with empty input
+ result = parser.parseSingleLine("");
+ assertFalse(result);
+ }
+
+ /**
* Tests that variants on the RFC-specified formatting of UIDL work properly.
*/
public void testUIDLComcastVariant() {
diff --git a/tests/src/com/android/email/mail/transport/SmtpSenderUnitTests.java b/tests/src/com/android/email/mail/transport/SmtpSenderUnitTests.java
index 5414e7d..08b932a 100644
--- a/tests/src/com/android/email/mail/transport/SmtpSenderUnitTests.java
+++ b/tests/src/com/android/email/mail/transport/SmtpSenderUnitTests.java
@@ -110,6 +110,30 @@
}
/**
+ * Test: Recover from a server closing early (or returning an empty string)
+ */
+ public void testEmptyLineResponse() throws MessagingException {
+ MockTransport mockTransport = openAndInjectMockTransport();
+
+ // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open
+ mockTransport.expectClose();
+
+ // Load up just the bare minimum to expose the error
+ mockTransport.expect(null, "220 MockTransport 2000 Ready To Assist You Peewee");
+ mockTransport.expect("EHLO .*", "");
+
+ // Now trigger the transmission
+ // Note, a null message is sufficient here, as we won't even get past open()
+ try {
+ mSender.sendMessage(null);
+ fail("Should not be able to send with failed open()");
+ } catch (MessagingException me) {
+ // good - expected
+ // TODO maybe expect a particular exception?
+ }
+ }
+
+ /**
* Set up a basic MockTransport. open it, and inject it into mStore
*/
private MockTransport openAndInjectMockTransport() {