Ignore FETCH responses that don't have UID.

We've observed that the secure.emailsrvr.com email server returns an excess
FETCH response for a UID FETCH command.  Excess responses don't have the
UID field, even though we request, which led the response parser to crash.

This patch fixes it by making the parser ignore response lines that don't
have UID.

Bug: 2441065
This commit is contained in:
Makoto Onuki 2010-02-23 17:29:24 -08:00
parent 642219502c
commit 726a9fcef3
2 changed files with 36 additions and 0 deletions

View File

@ -854,8 +854,10 @@ public class ImapStore extends Store {
if (response.mTag == null && response.get(1).equals("FETCH")) {
ImapList fetchList = (ImapList)response.getKeyedValue("FETCH");
String uid = fetchList.getKeyedString("UID");
if (uid == null) continue;
Message message = messageMap.get(uid);
if (message == null) continue;
if (listener != null) {
listener.messageStarted(uid, messageNumber++, messageMap.size());

View File

@ -487,4 +487,38 @@ public class ImapStoreUnitTests extends AndroidTestCase {
String text = MimeUtility.getTextFromPart(emptyBodyPart);
assertNull(text);
}
/**
* Confirm the IMAP parser won't crash when seeing an excess FETCH response line without UID.
*
* <p>We've observed that the secure.emailsrvr.com email server returns an excess FETCH response
* for a UID FETCH command. These excess responses doesn't have the UID field in it, even
* though we request, which led the response parser to crash. We fixed it by ignoring response
* lines that don't have UID. This test is to make sure this case.
*/
public void testExcessFetchResult() throws MessagingException {
MockTransport mock = openAndInjectMockTransport();
setupOpenFolder(mock);
mFolder.open(OpenMode.READ_WRITE, null);
// Create a message, and make sure it's not "SEEN".
Message message1 = mFolder.createMessage("1");
assertFalse(message1.isSet(Flag.SEEN));
FetchProfile fp = new FetchProfile();
fp.clear();
fp.add(FetchProfile.Item.FLAGS);
mock.expect(getNextTag(false) + " UID FETCH 1 \\(UID FLAGS\\)",
new String[] {
"* 1 FETCH (UID 1 FLAGS (\\Seen))",
"* 2 FETCH (FLAGS (\\Seen))",
getNextTag(true) + " OK SUCCESS"
});
// Shouldn't crash
mFolder.fetch(new Message[] { message1 }, fp, null);
// And the message is "SEEN".
assertTrue(message1.isSet(Flag.SEEN));
}
}