diff options
author | Tony Mak <tonymak@google.com> | 2015-06-08 10:11:59 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-06-08 10:12:00 +0000 |
commit | 53b6f267b6d37cc1cc88a5d960dd04ae5970e1ae (patch) | |
tree | 5d8160156be18a3d505a7db1891fe1ecbf77537e | |
parent | 7d5a314146e64d45cd0981010f7b556897527d2e (diff) | |
parent | 503a798e5f76ecce75607277292bd9a326ba79ec (diff) | |
download | android_packages_providers_CalendarProvider-53b6f267b6d37cc1cc88a5d960dd04ae5970e1ae.tar.gz android_packages_providers_CalendarProvider-53b6f267b6d37cc1cc88a5d960dd04ae5970e1ae.tar.bz2 android_packages_providers_CalendarProvider-53b6f267b6d37cc1cc88a5d960dd04ae5970e1ae.zip |
Merge "Fix crash when inserting reminder/attendee/extended property to a non-existent event" into mnc-dev
3 files changed, 88 insertions, 26 deletions
diff --git a/src/com/android/providers/calendar/CalendarDatabaseHelper.java b/src/com/android/providers/calendar/CalendarDatabaseHelper.java index 407e21a..bb979c6 100644 --- a/src/com/android/providers/calendar/CalendarDatabaseHelper.java +++ b/src/com/android/providers/calendar/CalendarDatabaseHelper.java @@ -3368,21 +3368,12 @@ import java.util.TimeZone; */ protected void duplicateEvent(final long id) { final SQLiteDatabase db = getWritableDatabase(); - try { - final long canPartiallyUpdate = DatabaseUtils.longForQuery(db, "SELECT " - + Calendars.CAN_PARTIALLY_UPDATE + " FROM " + Views.EVENTS - + " WHERE " + Events._ID + " = ?", new String[] { + final long canPartiallyUpdate = DatabaseUtils.longForQuery(db, "SELECT " + + Calendars.CAN_PARTIALLY_UPDATE + " FROM " + Views.EVENTS + + " WHERE " + Events._ID + " = ?", new String[]{ String.valueOf(id) - }); - if (canPartiallyUpdate == 0) { - return; - } - } catch (SQLiteDoneException e) { - // b/11392862 - // If no results are returned, this will be thrown. This can happen if the Events View - // has no rows for the provided id. This might happen for example if someone inserts a - // reminder that refers to a non existent event id. - // Return without doing anything because there is no event to duplicate. + }); + if (canPartiallyUpdate == 0) { return; } diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java index 73a2275..ea2dd38 100644 --- a/src/com/android/providers/calendar/CalendarProvider2.java +++ b/src/com/android/providers/calendar/CalendarProvider2.java @@ -2174,8 +2174,8 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } if (updatedValues.containsKey(Events.ORIGINAL_SYNC_ID) && !updatedValues.containsKey(Events.ORIGINAL_ID)) { - long originalId = getOriginalId(updatedValues.getAsString( - Events.ORIGINAL_SYNC_ID), + long originalId = getOriginalId(updatedValues + .getAsString(Events.ORIGINAL_SYNC_ID), updatedValues.getAsString(Events.CALENDAR_ID)); if (originalId != -1) { updatedValues.put(Events.ORIGINAL_ID, originalId); @@ -2284,11 +2284,16 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } id = mDbHelper.colorsInsert(values); break; - case ATTENDEES: + case ATTENDEES: { if (!values.containsKey(Attendees.EVENT_ID)) { throw new IllegalArgumentException("Attendees values must " + "contain an event_id"); } + Long eventIdObj = values.getAsLong(Reminders.EVENT_ID); + if (!doesEventExist(eventIdObj)) { + Log.i(TAG, "Trying to insert a attendee to a non-existent event"); + return null; + } if (!callerIsSyncAdapter) { final Long eventId = values.getAsLong(Attendees.EVENT_ID); mDbHelper.duplicateEvent(eventId); @@ -2299,13 +2304,18 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // Copy the attendee status value to the Events table. updateEventAttendeeStatus(mDb, values); break; - case REMINDERS: - { + } + case REMINDERS: { Long eventIdObj = values.getAsLong(Reminders.EVENT_ID); if (eventIdObj == null) { throw new IllegalArgumentException("Reminders values must " + "contain a numeric event_id"); } + if (!doesEventExist(eventIdObj)) { + Log.i(TAG, "Trying to insert a reminder to a non-existent event"); + return null; + } + if (!callerIsSyncAdapter) { mDbHelper.duplicateEvent(eventIdObj); setEventDirty(eventIdObj); @@ -2322,19 +2332,31 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun mCalendarAlarm.scheduleNextAlarm(false /* do not remove alarms */); break; } - case CALENDAR_ALERTS: - if (!values.containsKey(CalendarAlerts.EVENT_ID)) { + case CALENDAR_ALERTS: { + Long eventIdObj = values.getAsLong(Reminders.EVENT_ID); + if (eventIdObj == null) { throw new IllegalArgumentException("CalendarAlerts values must " - + "contain an event_id"); + + "contain a numeric event_id"); + } + if (!doesEventExist(eventIdObj)) { + Log.i(TAG, "Trying to insert an alert to a non-existent event"); + return null; } id = mDbHelper.calendarAlertsInsert(values); // Note: dirty bit is not set for Alerts because it is not synced. // It is generated from Reminders, which is synced. break; - case EXTENDED_PROPERTIES: - if (!values.containsKey(CalendarContract.ExtendedProperties.EVENT_ID)) { + } + case EXTENDED_PROPERTIES: { + Long eventIdObj = values.getAsLong(Reminders.EVENT_ID); + if (eventIdObj == null) { throw new IllegalArgumentException("ExtendedProperties values must " - + "contain an event_id"); + + "contain a numeric event_id"); + } + if (!doesEventExist(eventIdObj)) { + Log.i(TAG, "Trying to insert extended properties to a non-existent event id = " + + eventIdObj); + return null; } if (!callerIsSyncAdapter) { final Long eventId = values @@ -2344,6 +2366,7 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } id = mDbHelper.extendedPropertiesInsert(values); break; + } case EMMA: // Special target used during code-coverage evaluation. handleEmmaRequest(values); @@ -2364,10 +2387,14 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun if (id < 0) { return null; } - return ContentUris.withAppendedId(uri, id); } + private boolean doesEventExist(long eventId) { + return DatabaseUtils.queryNumEntries(mDb, Tables.EVENTS, Events._ID + "=?", + new String[]{String.valueOf(eventId)}) > 0; + } + /** * Handles special commands related to EMMA code-coverage testing. * diff --git a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java index 98c4b6a..a4c5e35 100644 --- a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java +++ b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java @@ -2014,6 +2014,50 @@ public class CalendarProvider2Test extends AndroidTestCase { cursor.close(); } + public void testInsertAlertToNonExistentEvent() { + Uri alertUri = CalendarContract.CalendarAlerts.insert(mResolver, 1 /* eventId */, + 2 /* begin */, 3 /* end */, 4 /* alarmTime */, 5 /* minutes */); + assertEquals(null, alertUri); + } + + public void testInsertReminderToNonExistentEvent() { + ContentValues reminder = new ContentValues(); + reminder.put(CalendarContract.Reminders.MINUTES, 30); + reminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_EMAIL); + reminder.put(CalendarContract.Attendees.EVENT_ID, 1); + Uri reminderUri = mResolver.insert( + updatedUri(CalendarContract.Reminders.CONTENT_URI, true, DEFAULT_ACCOUNT, + DEFAULT_ACCOUNT_TYPE), reminder); + assertEquals(null, reminderUri); + } + + public void testInsertAttendeeToNonExistentEvent() { + ContentValues attendee = new ContentValues(); + attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Joe"); + attendee.put(CalendarContract.Attendees.ATTENDEE_EMAIL, DEFAULT_ACCOUNT); + attendee.put(CalendarContract.Attendees.ATTENDEE_TYPE, + CalendarContract.Attendees.TYPE_REQUIRED); + attendee.put(CalendarContract.Attendees.ATTENDEE_RELATIONSHIP, + CalendarContract.Attendees.RELATIONSHIP_ORGANIZER); + attendee.put(CalendarContract.Attendees.EVENT_ID, 1); + attendee.put(CalendarContract.Attendees.ATTENDEE_IDENTITY, "ID1"); + attendee.put(CalendarContract.Attendees.ATTENDEE_ID_NAMESPACE, "IDNS1"); + Uri attendeesUri = mResolver.insert(CalendarContract.Attendees.CONTENT_URI, attendee); + assertEquals(null, attendeesUri); + } + + public void testInsertExtendedPropertyToNonExistentEvent() { + ContentValues extended = new ContentValues(); + extended.put(CalendarContract.ExtendedProperties.NAME, "foo"); + extended.put(CalendarContract.ExtendedProperties.VALUE, "bar"); + extended.put(CalendarContract.ExtendedProperties.EVENT_ID, 1); + + Uri extendedUri = mResolver.insert( + updatedUri(CalendarContract.ExtendedProperties.CONTENT_URI, true, + DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), extended); + assertEquals(null, extendedUri); + } + void checkEvents(int count, SQLiteDatabase db) { Cursor cursor = db.query("Events", null, null, null, null, null, null); try { |