Handle query with an id of -1 more gracefully

* In query of an otherwise valid URI with -1 as an id, simply return
  an empty cursor
* Add unit test to verify proper handling of invalid uri's

Bug: 3183245
Bug: 3292080

Change-Id: Ia0c35cbd0f5dd0dc4a8fc794226399644cf1fe13
This commit is contained in:
Marc Blank 2010-12-30 14:55:27 -08:00
parent 1c1bd6a3eb
commit d306ba3438
2 changed files with 67 additions and 1 deletions

View File

@ -44,6 +44,7 @@ import android.content.Context;
import android.content.OperationApplicationException;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@ -1258,7 +1259,30 @@ public class EmailProvider extends ContentProvider {
time = System.nanoTime();
}
Cursor c = null;
int match = findMatch(uri, "query");
int match;
try {
match = findMatch(uri, "query");
} catch (IllegalArgumentException e) {
String uriString = uri.toString();
// If we were passed an illegal uri, see if it ends in /-1
// if so, and if substituting 0 for -1 results in a valid uri, return an empty cursor
if (uriString != null && uriString.endsWith("/-1")) {
uri = Uri.parse(uriString.substring(0, uriString.length() - 2) + "0");
match = findMatch(uri, "query");
switch (match) {
case BODY_ID:
case MESSAGE_ID:
case DELETED_MESSAGE_ID:
case UPDATED_MESSAGE_ID:
case ATTACHMENT_ID:
case MAILBOX_ID:
case ACCOUNT_ID:
case HOSTAUTH_ID:
return new MatrixCursor(projection, 0);
}
}
throw e;
}
Context context = getContext();
// See the comment at delete(), above
SQLiteDatabase db = getDatabase(context);

View File

@ -2370,4 +2370,46 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
// Check
assertEquals(start + 1, Mailbox.restoreMailboxWithId(c, b1.mId).mSyncInterval);
}
/**
* Check that we're handling illegal uri's properly (by throwing an exception unless it's a
* query for an id of -1, in which case we return a zero-length cursor)
*/
public void testIllegalUri() {
final ContentResolver cr = mMockContext.getContentResolver();
ContentValues cv = new ContentValues();
Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/fooble");
try {
cr.insert(uri, cv);
fail("Insert should have thrown exception");
} catch (IllegalArgumentException e) {
}
try {
cr.update(uri, cv, null, null);
fail("Update should have thrown exception");
} catch (IllegalArgumentException e) {
}
try {
cr.delete(uri, null, null);
fail("Delete should have thrown exception");
} catch (IllegalArgumentException e) {
}
try {
cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
fail("Query should have thrown exception");
} catch (IllegalArgumentException e) {
}
uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/fred");
try {
cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
fail("Query should have thrown exception");
} catch (IllegalArgumentException e) {
}
uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/-1");
Cursor c = cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
assertNotNull(c);
assertEquals(0, c.getCount());
c.close();
}
}