Fix the java.lang.StringIndexOutOfBoundsException that occurs when an SMTP server closes the connection early or returns an empty line.

Fix the same error in the Pop3 UIDL parser.
This commit is contained in:
Andrew Stadler 2009-05-22 11:48:14 -07:00
parent ae1213c4c9
commit b011a812e0
4 changed files with 71 additions and 3 deletions

View File

@ -511,6 +511,9 @@ public class Pop3Store extends Store {
*/
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 class Pop3Store extends Store {
*/
public boolean parseMultiLine(String response) {
mErr = false;
if (response == null || response.length() == 0) {
return false;
}
char first = response.charAt(0);
if (first == '.') {
mEndOfMessage = true;

View File

@ -280,9 +280,11 @@ public class SmtpSender extends Sender {
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;

View File

@ -104,6 +104,42 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
assertTrue(parser.mErr);
}
/**
* 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.
*/

View File

@ -109,6 +109,30 @@ public class SmtpSenderUnitTests extends AndroidTestCase {
mSender.sendMessage(message);
}
/**
* 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
*/