diff options
author | Jeff Brown <jeffbrown@google.com> | 2013-01-07 17:15:12 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2013-01-08 15:32:50 -0800 |
commit | c21b5a019c1da00b6d861cd2859e3c349a44b3a7 (patch) | |
tree | 750072f97e644448c149c8d5447d514cca189ba0 /core/java/android/database | |
parent | f6f00b14fb4d2a247393fd3e6d45de077a8b4da9 (diff) | |
download | frameworks_base-c21b5a019c1da00b6d861cd2859e3c349a44b3a7.zip frameworks_base-c21b5a019c1da00b6d861cd2859e3c349a44b3a7.tar.gz frameworks_base-c21b5a019c1da00b6d861cd2859e3c349a44b3a7.tar.bz2 |
Fix cursor window leak when query execution fails.
Ensure that the Cursor object is closed if a query on a
content provider fails due to an error or is canceled during
execution. There are several places in the code where
similar problems can occur.
To further reduce the likelihood of leaks, close the cursor
window immediately when a query fails.
Bug: 7278577
Change-Id: I8c686c259de80a162b9086628a817d57f09fdd13
Diffstat (limited to 'core/java/android/database')
-rw-r--r-- | core/java/android/database/CursorToBulkCursorAdaptor.java | 5 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteCursor.java | 29 |
2 files changed, 24 insertions, 10 deletions
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java index 525be96..82a61d4 100644 --- a/core/java/android/database/CursorToBulkCursorAdaptor.java +++ b/core/java/android/database/CursorToBulkCursorAdaptor.java @@ -132,6 +132,11 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } + /** + * Returns an object that contains sufficient metadata to reconstruct + * the cursor remotely. May throw if an error occurs when executing the query + * and obtaining the row count. + */ public BulkCursorDescriptor getBulkCursorDescriptor() { synchronized (mLock) { throwIfCursorIsClosed(); diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index b29897e..5a1a8e2 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -138,17 +138,26 @@ public class SQLiteCursor extends AbstractWindowedCursor { private void fillWindow(int requiredPos) { clearOrCreateWindow(getDatabase().getPath()); - if (mCount == NO_COUNT) { - int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0); - mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true); - mCursorWindowCapacity = mWindow.getNumRows(); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "received count(*) from native_fill_window: " + mCount); + try { + if (mCount == NO_COUNT) { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0); + mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true); + mCursorWindowCapacity = mWindow.getNumRows(); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "received count(*) from native_fill_window: " + mCount); + } + } else { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, + mCursorWindowCapacity); + mQuery.fillWindow(mWindow, startPos, requiredPos, false); } - } else { - int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, - mCursorWindowCapacity); - mQuery.fillWindow(mWindow, startPos, requiredPos, false); + } catch (RuntimeException ex) { + // Close the cursor window if the query failed and therefore will + // not produce any results. This helps to avoid accidentally leaking + // the cursor window if the client does not correctly handle exceptions + // and fails to close the cursor. + closeWindow(); + throw ex; } } |