summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Mak <tonymak@google.com>2015-06-08 10:11:59 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-08 10:12:00 +0000
commit53b6f267b6d37cc1cc88a5d960dd04ae5970e1ae (patch)
tree5d8160156be18a3d505a7db1891fe1ecbf77537e
parent7d5a314146e64d45cd0981010f7b556897527d2e (diff)
parent503a798e5f76ecce75607277292bd9a326ba79ec (diff)
downloadandroid_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
-rw-r--r--src/com/android/providers/calendar/CalendarDatabaseHelper.java19
-rw-r--r--src/com/android/providers/calendar/CalendarProvider2.java51
-rw-r--r--tests/src/com/android/providers/calendar/CalendarProvider2Test.java44
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 {