From d15478b86318eea1a80fd238b33d8f587173470a Mon Sep 17 00:00:00 2001 From: rfc2822 Date: Sat, 26 Oct 2013 20:35:22 +0200 Subject: [PATCH] bug fixes * avoid crashes when content providers return null cursors * ignore invalid URLs (for instance, with spaces) in WebDAV multi-status responses --- .../davdroid/resource/LocalAddressBook.java | 23 ++++++++++--------- .../davdroid/resource/LocalCalendar.java | 12 ++++++---- .../bitfire/davdroid/webdav/DavResponse.java | 2 +- .../davdroid/webdav/WebDavCollection.java | 11 +++++++-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/at/bitfire/davdroid/resource/LocalAddressBook.java b/src/at/bitfire/davdroid/resource/LocalAddressBook.java index 1b80bd29..770f9e15 100644 --- a/src/at/bitfire/davdroid/resource/LocalAddressBook.java +++ b/src/at/bitfire/davdroid/resource/LocalAddressBook.java @@ -105,9 +105,10 @@ public class LocalAddressBook extends LocalCollection { Cursor cursor = providerClient.query(entriesURI(), new String[] { RawContacts._ID, entryColumnRemoteName(), entryColumnETag() }, entryColumnRemoteName() + "=?", new String[] { remoteName }, null); - if (cursor.moveToNext()) + if (cursor != null && cursor.moveToNext()) return new Contact(cursor.getLong(0), cursor.getString(1), cursor.getString(2)); - return null; + else + return null; } @Override @@ -118,7 +119,7 @@ public class LocalAddressBook extends LocalCollection { Cursor cursor = providerClient.query(ContentUris.withAppendedId(entriesURI(), c.getLocalID()), new String[] { entryColumnUID(), RawContacts.STARRED }, null, null, null); - if (cursor.moveToNext()) { + if (cursor != null && cursor.moveToNext()) { c.setUid(cursor.getString(0)); c.setStarred(cursor.getInt(1) != 0); } @@ -130,7 +131,7 @@ public class LocalAddressBook extends LocalCollection { /* 6 */ StructuredName.PHONETIC_GIVEN_NAME, StructuredName.PHONETIC_MIDDLE_NAME, StructuredName.PHONETIC_FAMILY_NAME }, StructuredName.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(res.getLocalID()), StructuredName.CONTENT_ITEM_TYPE }, null); - if (cursor.moveToNext()) { + if (cursor != null && cursor.moveToNext()) { c.setDisplayName(cursor.getString(0)); c.setPrefix(cursor.getString(1)); @@ -149,7 +150,7 @@ public class LocalAddressBook extends LocalCollection { Nickname.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Nickname.CONTENT_ITEM_TYPE }, null); List nickNames = new LinkedList(); - while (cursor.moveToNext()) + while (cursor != null && cursor.moveToNext()) nickNames.add(cursor.getString(0)); if (!nickNames.isEmpty()) c.setNickNames(nickNames.toArray(new String[0])); @@ -158,7 +159,7 @@ public class LocalAddressBook extends LocalCollection { cursor = providerClient.query(dataURI(), new String[] { Email.TYPE, Email.ADDRESS }, Email.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Email.CONTENT_ITEM_TYPE }, null); - while (cursor.moveToNext()) { + while (cursor != null && cursor.moveToNext()) { net.fortuna.ical4j.vcard.property.Email email = new net.fortuna.ical4j.vcard.property.Email(cursor.getString(1)); switch (cursor.getInt(0)) { case Email.TYPE_HOME: @@ -175,7 +176,7 @@ public class LocalAddressBook extends LocalCollection { cursor = providerClient.query(dataURI(), new String[] { Phone.TYPE, Phone.NUMBER }, Phone.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Phone.CONTENT_ITEM_TYPE }, null); - while (cursor.moveToNext()) { + while (cursor != null && cursor.moveToNext()) { Telephone number = new Telephone(cursor.getString(1)); List types = new LinkedList(); @@ -220,14 +221,14 @@ public class LocalAddressBook extends LocalCollection { cursor = providerClient.query(dataURI(), new String[] { Photo.PHOTO }, Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Photo.CONTENT_ITEM_TYPE }, null); - if (cursor.moveToNext()) + if (cursor != null && cursor.moveToNext()) c.setPhoto(cursor.getBlob(0)); // events (birthday) cursor = providerClient.query(dataURI(), new String[] { CommonDataKinds.Event.TYPE, CommonDataKinds.Event.START_DATE }, Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), CommonDataKinds.Event.CONTENT_ITEM_TYPE }, null); - while (cursor.moveToNext()) + while (cursor != null && cursor.moveToNext()) try { switch (cursor.getInt(0)) { case CommonDataKinds.Event.TYPE_BIRTHDAY: @@ -242,7 +243,7 @@ public class LocalAddressBook extends LocalCollection { cursor = providerClient.query(dataURI(), new String[] { Website.URL }, Website.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Website.CONTENT_ITEM_TYPE }, null); - while (cursor.moveToNext()) + while (cursor != null && cursor.moveToNext()) try { c.addURL(new URI(cursor.getString(0))); } catch (URISyntaxException ex) { @@ -253,7 +254,7 @@ public class LocalAddressBook extends LocalCollection { cursor = providerClient.query(dataURI(), new String[] { Note.NOTE }, Website.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(c.getLocalID()), Note.CONTENT_ITEM_TYPE }, null); - while (cursor.moveToNext()) + while (cursor != null && cursor.moveToNext()) c.addNote(new String(cursor.getString(0))); c.populated = true; diff --git a/src/at/bitfire/davdroid/resource/LocalCalendar.java b/src/at/bitfire/davdroid/resource/LocalCalendar.java index 9e93128f..9f454f5d 100644 --- a/src/at/bitfire/davdroid/resource/LocalCalendar.java +++ b/src/at/bitfire/davdroid/resource/LocalCalendar.java @@ -107,8 +107,9 @@ public class LocalCalendar extends LocalCollection { Cursor cursor = providerClient.query(calendarsURI(account), new String[] { Calendars._ID, Calendars.NAME, COLLECTION_COLUMN_CTAG }, Calendars.DELETED + "=0 AND " + Calendars.SYNC_EVENTS + "=1", null, null); + LinkedList calendars = new LinkedList(); - while (cursor.moveToNext()) + while (cursor != null && cursor.moveToNext()) calendars.add(new LocalCalendar(account, providerClient, cursor.getInt(0), cursor.getString(1), cursor.getString(2))); return calendars.toArray(new LocalCalendar[0]); } @@ -147,9 +148,10 @@ public class LocalCalendar extends LocalCollection { new String[] { entryColumnID(), entryColumnRemoteName(), entryColumnETag() }, Events.CALENDAR_ID + "=? AND " + entryColumnRemoteName() + "=?", new String[] { String.valueOf(id), remoteName }, null); - if (cursor.moveToNext()) + if (cursor != null && cursor.moveToNext()) return new Event(cursor.getLong(0), cursor.getString(1), cursor.getString(2)); - return null; + else + return null; } @Override @@ -167,7 +169,7 @@ public class LocalCalendar extends LocalCollection { /* 14 */ Events.HAS_ATTENDEE_DATA, Events.ORGANIZER, Events.SELF_ATTENDEE_STATUS, /* 17 */ entryColumnUID() }, null, null, null); - if (cursor.moveToNext()) { + if (cursor != null && cursor.moveToNext()) { e.setUid(cursor.getString(17)); e.setSummary(cursor.getString(0)); @@ -250,7 +252,7 @@ public class LocalCalendar extends LocalCollection { /* 0 */ Attendees.ATTENDEE_EMAIL, Attendees.ATTENDEE_NAME, Attendees.ATTENDEE_TYPE, /* 3 */ Attendees.ATTENDEE_RELATIONSHIP, Attendees.STATUS }, Attendees.EVENT_ID + "=?", new String[] { String.valueOf(e.getLocalID()) }, null); - while (c.moveToNext()) { + while (c != null && c.moveToNext()) { try { Attendee attendee = new Attendee("mailto:" + c.getString(0)); ParameterList params = attendee.getParameters(); diff --git a/src/at/bitfire/davdroid/webdav/DavResponse.java b/src/at/bitfire/davdroid/webdav/DavResponse.java index 12dc5850..68d77c18 100644 --- a/src/at/bitfire/davdroid/webdav/DavResponse.java +++ b/src/at/bitfire/davdroid/webdav/DavResponse.java @@ -19,7 +19,7 @@ import org.simpleframework.xml.Root; public class DavResponse { @Element @Getter DavHref href; - + @ElementList(inline=true) @Getter List propstat; } diff --git a/src/at/bitfire/davdroid/webdav/WebDavCollection.java b/src/at/bitfire/davdroid/webdav/WebDavCollection.java index 5beb0f7d..d0a07012 100644 --- a/src/at/bitfire/davdroid/webdav/WebDavCollection.java +++ b/src/at/bitfire/davdroid/webdav/WebDavCollection.java @@ -30,7 +30,6 @@ import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import android.util.Log; -import at.bitfire.davdroid.resource.IncapableResourceException; public class WebDavCollection extends WebDavResource { private static final String TAG = "davdroid.WebDavCollection"; @@ -170,8 +169,16 @@ public class WebDavCollection extends WebDavResource { } WebDavResource referenced = null; + + URI thisURI; + try { + thisURI = location.resolve(href); + } catch(IllegalArgumentException ex) { + Log.w(TAG, "Server returned illegal URI", ex); + continue; + } - if (sameURL(location, location.resolve(href))) { + if (sameURL(location, thisURI)) { // response is about this property referenced = this;