diff options
author | Jay Shrauner <shrauner@google.com> | 2014-04-29 15:14:09 -0700 |
---|---|---|
committer | Jay Shrauner <shrauner@google.com> | 2014-04-30 12:25:42 -0700 |
commit | 2f369a47e14916a34f49c79c0a246a2e3ac3072f (patch) | |
tree | 1da786be374041fcdacc79eb3c0b2308a514097d | |
parent | 8fbd758a9872b9ee9d1d978013cbec7efbe12d0c (diff) | |
download | android_packages_apps_Exchange-2f369a47e14916a34f49c79c0a246a2e3ac3072f.tar.gz android_packages_apps_Exchange-2f369a47e14916a34f49c79c0a246a2e3ac3072f.tar.bz2 android_packages_apps_Exchange-2f369a47e14916a34f49c79c0a246a2e3ac3072f.zip |
Date parser utility helpers throw parse exceptions
Update to reflect API change to parseDateTimeToMillis and
parseEmailDateTimeToMillis, which now throw ParseExceptions on
malformed date strings.
Bug:14279251
Change-Id: I74e015b81079b127ddba15f34c8b7e555099bd1e
8 files changed, 124 insertions, 30 deletions
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java index 45191a6b..d8902ce3 100644 --- a/src/com/android/exchange/EasSyncService.java +++ b/src/com/android/exchange/EasSyncService.java @@ -104,6 +104,7 @@ import java.io.InputStream; import java.lang.Thread.State; import java.net.URI; import java.security.cert.CertificateException; +import java.text.ParseException; public class EasSyncService extends AbstractSyncService { // DO NOT CHECK IN SET TO TRUE @@ -986,6 +987,7 @@ public class EasSyncService extends AbstractSyncService { } return null; } + /** * Send an email responding to a Message that has been marked as a meeting request. The message * will consist a little bit of event information and an iCalendar attachment @@ -1006,6 +1008,10 @@ public class EasSyncService extends AbstractSyncService { String dtStamp = meetingInfo.get(MeetingInfo.MEETING_DTSTAMP); String dtStart = meetingInfo.get(MeetingInfo.MEETING_DTSTART); String dtEnd = meetingInfo.get(MeetingInfo.MEETING_DTEND); + if (TextUtils.isEmpty(dtStamp) || TextUtils.isEmpty(dtStart) || + TextUtils.isEmpty(dtEnd)) { + return; + } // What we're doing here is to create an Entity that looks like an Event as it would be // stored by CalendarProvider @@ -1015,8 +1021,13 @@ public class EasSyncService extends AbstractSyncService { // Fill in times, location, title, and organizer entityValues.put("DTSTAMP", CalendarUtilities.convertEmailDateTimeToCalendarDateTime(dtStamp)); - entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart)); - entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd)); + try { + entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart)); + entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd)); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for DTSTART/DTEND tags.", e); + return; + } entityValues.put(Events.EVENT_LOCATION, meetingInfo.get(MeetingInfo.MEETING_LOCATION)); entityValues.put(Events.TITLE, meetingInfo.get(MeetingInfo.MEETING_TITLE)); entityValues.put(Events.ORGANIZER, organizerEmail); diff --git a/src/com/android/exchange/adapter/CalendarSyncParser.java b/src/com/android/exchange/adapter/CalendarSyncParser.java index 111b510d..a9bb3ea1 100644 --- a/src/com/android/exchange/adapter/CalendarSyncParser.java +++ b/src/com/android/exchange/adapter/CalendarSyncParser.java @@ -33,6 +33,7 @@ import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.Map.Entry; @@ -445,10 +446,18 @@ public class CalendarSyncParser extends AbstractSyncParser { cv.put(Events.EVENT_TIMEZONE, timeZone.getID()); break; case Tags.CALENDAR_START_TIME: - startTime = Utility.parseDateTimeToMillis(getValue()); + try { + startTime = Utility.parseDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_START_TIME tag.", e); + } break; case Tags.CALENDAR_END_TIME: - endTime = Utility.parseDateTimeToMillis(getValue()); + try { + endTime = Utility.parseDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_END_TIME tag.", e); + } break; case Tags.CALENDAR_EXCEPTIONS: // For exceptions to show the organizer, the organizer must be added before @@ -787,9 +796,14 @@ public class CalendarSyncParser extends AbstractSyncParser { attachmentsParser(); break; case Tags.CALENDAR_EXCEPTION_START_TIME: - exceptionStartTime = getValue(); - cv.put(Events.ORIGINAL_INSTANCE_TIME, - Utility.parseDateTimeToMillis(exceptionStartTime)); + final String valueStr = getValue(); + try { + cv.put(Events.ORIGINAL_INSTANCE_TIME, + Utility.parseDateTimeToMillis(valueStr)); + exceptionStartTime = valueStr; + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_EXCEPTION_START_TIME tag.", e); + } break; case Tags.CALENDAR_EXCEPTION_IS_DELETED: if (getValueInt() == 1) { @@ -807,10 +821,18 @@ public class CalendarSyncParser extends AbstractSyncParser { cv.put(Events.DESCRIPTION, getValue()); break; case Tags.CALENDAR_START_TIME: - startTime = Utility.parseDateTimeToMillis(getValue()); + try { + startTime = Utility.parseDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_START_TIME tag.", e); + } break; case Tags.CALENDAR_END_TIME: - endTime = Utility.parseDateTimeToMillis(getValue()); + try { + endTime = Utility.parseDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_END_TIME tag.", e); + } break; case Tags.CALENDAR_LOCATION: cv.put(Events.EVENT_LOCATION, getValue()); diff --git a/src/com/android/exchange/adapter/ContactsSyncParser.java b/src/com/android/exchange/adapter/ContactsSyncParser.java index 75ee50e4..e9aa7c74 100644 --- a/src/com/android/exchange/adapter/ContactsSyncParser.java +++ b/src/com/android/exchange/adapter/ContactsSyncParser.java @@ -47,6 +47,7 @@ import com.android.mail.utils.LogUtils; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.TimeZone; @@ -1047,7 +1048,13 @@ public class ContactsSyncParser extends AbstractSyncParser { return; } // TODO: Store the date in the format expected by EAS servers. - long millis = Utility.parseEmailDateTimeToMillis(birthday); + final long millis; + try { + millis = Utility.parseEmailDateTimeToMillis(birthday); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for birthday date field.", e); + return; + } GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); cal.setTimeInMillis(millis); if (cal.get(GregorianCalendar.HOUR_OF_DAY) >= 12) { diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java index b8676eab..6a9680f2 100644 --- a/src/com/android/exchange/adapter/EmailSyncAdapter.java +++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java @@ -77,6 +77,7 @@ import org.apache.http.entity.ByteArrayEntity; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; @@ -541,7 +542,11 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { msg.mReplyTo = Address.toString(Address.parse(getValue())); break; case Tags.EMAIL_DATE_RECEIVED: - msg.mTimeStamp = Utility.parseEmailDateTimeToMillis(getValue()); + try { + msg.mTimeStamp = Utility.parseEmailDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for EMAIL_DATE_RECEIVED tag.", e); + } break; case Tags.EMAIL_SUBJECT: msg.mSubject = getValue(); @@ -635,8 +640,13 @@ public class EmailSyncAdapter extends AbstractSyncAdapter { Events.EVENT_LOCATION); String dtstart = ps.get(MeetingInfo.MEETING_DTSTART); if (!TextUtils.isEmpty(dtstart)) { - long startTime = Utility.parseEmailDateTimeToMillis(dtstart); - values.put(Events.DTSTART, startTime); + try { + final long startTime = + Utility.parseEmailDateTimeToMillis(dtstart); + values.put(Events.DTSTART, startTime); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for MEETING_DTSTART tag.", e); + } } putFromMeeting(ps, MeetingInfo.MEETING_ALL_DAY, values, Events.ALL_DAY); diff --git a/src/com/android/exchange/adapter/EmailSyncParser.java b/src/com/android/exchange/adapter/EmailSyncParser.java index 787dcdba..d1c94531 100644 --- a/src/com/android/exchange/adapter/EmailSyncParser.java +++ b/src/com/android/exchange/adapter/EmailSyncParser.java @@ -45,6 +45,7 @@ import com.google.common.annotations.VisibleForTesting; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -156,7 +157,11 @@ public class EmailSyncParser extends AbstractSyncParser { msg.mReplyTo = Address.toString(Address.parse(getValue())); break; case Tags.EMAIL_DATE_RECEIVED: - msg.mTimeStamp = Utility.parseEmailDateTimeToMillis(getValue()); + try { + msg.mTimeStamp = Utility.parseEmailDateTimeToMillis(getValue()); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for EMAIL_DATE_RECEIVED tag.", e); + } break; case Tags.EMAIL_SUBJECT: msg.mSubject = getValue(); @@ -250,8 +255,13 @@ public class EmailSyncParser extends AbstractSyncParser { CalendarContract.Events.EVENT_LOCATION); String dtstart = ps.get(MeetingInfo.MEETING_DTSTART); if (!TextUtils.isEmpty(dtstart)) { - long startTime = Utility.parseEmailDateTimeToMillis(dtstart); - values.put(CalendarContract.Events.DTSTART, startTime); + try { + final long startTime = + Utility.parseEmailDateTimeToMillis(dtstart); + values.put(CalendarContract.Events.DTSTART, startTime); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for MEETING_DTSTART tag.", e); + } } putFromMeeting(ps, MeetingInfo.MEETING_ALL_DAY, values, CalendarContract.Events.ALL_DAY); diff --git a/src/com/android/exchange/service/EasMeetingResponder.java b/src/com/android/exchange/service/EasMeetingResponder.java index 28ef2c63..f42f583e 100644 --- a/src/com/android/exchange/service/EasMeetingResponder.java +++ b/src/com/android/exchange/service/EasMeetingResponder.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.Entity; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Events; +import android.text.TextUtils; import com.android.emailcommon.mail.Address; import com.android.emailcommon.mail.MeetingInfo; @@ -29,6 +30,7 @@ import org.apache.http.HttpStatus; import java.io.IOException; import java.security.cert.CertificateException; +import java.text.ParseException; /** * Responds to a meeting request, both notifying the EAS server and sending email. @@ -128,6 +130,10 @@ public class EasMeetingResponder extends EasServerConnection { final String dtStamp = meetingInfo.get(MeetingInfo.MEETING_DTSTAMP); final String dtStart = meetingInfo.get(MeetingInfo.MEETING_DTSTART); final String dtEnd = meetingInfo.get(MeetingInfo.MEETING_DTEND); + if (TextUtils.isEmpty(dtStamp) || TextUtils.isEmpty(dtStart) || + TextUtils.isEmpty(dtEnd)) { + return; + } // What we're doing here is to create an Entity that looks like an Event as it would be // stored by CalendarProvider @@ -137,8 +143,13 @@ public class EasMeetingResponder extends EasServerConnection { // Fill in times, location, title, and organizer entityValues.put("DTSTAMP", CalendarUtilities.convertEmailDateTimeToCalendarDateTime(dtStamp)); - entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart)); - entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd)); + try { + entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart)); + entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd)); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for DTSTART/DTEND tags.", e); + return; + } entityValues.put(Events.EVENT_LOCATION, meetingInfo.get(MeetingInfo.MEETING_LOCATION)); entityValues.put(Events.TITLE, meetingInfo.get(MeetingInfo.MEETING_TITLE)); entityValues.put(Events.ORGANIZER, organizerEmail); diff --git a/src/com/android/exchange/utility/CalendarUtilities.java b/src/com/android/exchange/utility/CalendarUtilities.java index 5661bb10..3cd41837 100644 --- a/src/com/android/exchange/utility/CalendarUtilities.java +++ b/src/com/android/exchange/utility/CalendarUtilities.java @@ -54,6 +54,7 @@ import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.text.DateFormat; +import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -1146,7 +1147,7 @@ public class CalendarUtilities { * Reformat an RRULE style UNTIL to an EAS style until */ @VisibleForTesting - static String recurrenceUntilToEasUntil(String until) { + static String recurrenceUntilToEasUntil(String until) throws ParseException { // Get a calendar in our local time zone GregorianCalendar localCalendar = new GregorianCalendar(TimeZone.getDefault()); // Set the time per GMT time in the 'until' @@ -1176,7 +1177,11 @@ public class CalendarUtilities { } String until = tokenFromRrule(rrule, "UNTIL="); if (until != null) { - s.data(Tags.CALENDAR_RECURRENCE_UNTIL, recurrenceUntilToEasUntil(until)); + try { + s.data(Tags.CALENDAR_RECURRENCE_UNTIL, recurrenceUntilToEasUntil(until)); + } catch (ParseException e) { + LogUtils.w(TAG, "Parse error for CALENDAR_RECURRENCE_UNTIL tag.", e); + } } } diff --git a/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java b/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java index 4501bff1..68e57e0f 100644 --- a/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java +++ b/tests/src/com/android/exchange/utility/CalendarUtilitiesTests.java @@ -42,6 +42,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; import java.text.DateFormat; +import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -203,7 +204,7 @@ public class CalendarUtilitiesTests extends AndroidTestCase { assertNull(CalendarUtilities.tokenFromRrule(rrule, "UNTIL=")); } - public void testRecurrenceUntilToEasUntil() { + public void testRecurrenceUntilToEasUntil() throws ParseException { TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); // Case where local time crosses into next day in GMT assertEquals("20110730T000000Z", @@ -211,9 +212,18 @@ public class CalendarUtilitiesTests extends AndroidTestCase { // Case where local time does not cross into next day in GMT assertEquals("20110730T000000Z", CalendarUtilities.recurrenceUntilToEasUntil("20110730T235959Z")); + // Abbreviated date format + assertEquals("20110729T000000Z", + CalendarUtilities.recurrenceUntilToEasUntil("20110730")); + try { + CalendarUtilities.recurrenceUntilToEasUntil("201107"); + fail("Expected ParseException"); + } catch (ParseException e) { + // expected + } } - public void testParseEmailDateTimeToMillis(String date) { + public void testParseEmailDateTimeToMillis(String date) throws ParseException { // Format for email date strings is 2010-02-23T16:00:00.000Z String dateString = "2010-02-23T15:16:17.000Z"; long dateTime = Utility.parseEmailDateTimeToMillis(dateString); @@ -228,7 +238,7 @@ public class CalendarUtilitiesTests extends AndroidTestCase { assertEquals(cal.get(Calendar.SECOND), 17); } - public void testParseDateTimeToMillis(String date) { + public void testParseDateTimeToMillis(String date) throws ParseException { // Format for calendar date strings is 20100223T160000000Z String dateString = "20100223T151617000Z"; long dateTime = Utility.parseDateTimeToMillis(dateString); @@ -254,10 +264,14 @@ public class CalendarUtilitiesTests extends AndroidTestCase { // Fill in times, location, title, and organizer entityValues.put("DTSTAMP", CalendarUtilities.convertEmailDateTimeToCalendarDateTime("2010-04-05T14:30:51Z")); - entityValues.put(Events.DTSTART, - Utility.parseEmailDateTimeToMillis("2010-04-12T18:30:00Z")); - entityValues.put(Events.DTEND, - Utility.parseEmailDateTimeToMillis("2010-04-12T19:30:00Z")); + try { + entityValues.put(Events.DTSTART, + Utility.parseEmailDateTimeToMillis("2010-04-12T18:30:00Z")); + entityValues.put(Events.DTEND, + Utility.parseEmailDateTimeToMillis("2010-04-12T19:30:00Z")); + } catch (ParseException e) { + // ignore + } entityValues.put(Events.EVENT_LOCATION, location); entityValues.put(Events.TITLE, title); entityValues.put(Events.ORGANIZER, organizer); @@ -282,8 +296,12 @@ public class CalendarUtilitiesTests extends AndroidTestCase { ContentValues entityValues = entity.getEntityValues(); entityValues.put(Events.ORIGINAL_SYNC_ID, 69); // The exception will be on April 26th - entityValues.put(Events.ORIGINAL_INSTANCE_TIME, - Utility.parseEmailDateTimeToMillis("2010-04-26T18:30:00Z")); + try { + entityValues.put(Events.ORIGINAL_INSTANCE_TIME, + Utility.parseEmailDateTimeToMillis("2010-04-26T18:30:00Z")); + } catch (ParseException e) { + // ignore + } return entity; } @@ -540,7 +558,7 @@ public class CalendarUtilitiesTests extends AndroidTestCase { // Set up the "exception"... String title = "Discuss Unit Tests"; Entity entity = setupTestExceptionEntity(ORGANIZER, ATTENDEE, title); - + ContentValues entityValues = entity.getEntityValues(); // Mark the Exception as dirty entityValues.put(Events.DIRTY, 1); |