From 0a4b179db5253451d100ec32d0f3070676a00625 Mon Sep 17 00:00:00 2001 From: Jason-Whitmore Date: Fri, 10 Oct 2025 22:12:19 -0700 Subject: [PATCH] Fixes Issue 6436: getString(...) must not be null (#6474) * DatabaseUtils.kt: change getString() to allow null returns Before this change, a call to getString() would assume that the specified column name actually exists. A bad String input would cause a null value to be returned to getString(), which would then throw a NPE because getString() can only return non null Strings. This change expands the getString() method to check if the column name exists. If it does exist, the String is retrieved normally. Else, a null value is returned. The method signature is changed to allow null return values. * *Dao.kt: change some usages of getString() Before this change, the getString() method in DatabaseUtils.kt was changed to allow returning a null value upon method failure. All usages of getString() were not changed. This change updates all usages of getString() which require non null return values. If null is returned, an empty string is used instead. --------- Co-authored-by: Nicolas Raoul --- .../bookmarks/items/BookmarkItemsDao.kt | 14 ++++++++++++-- .../bookmarks/pictures/BookmarkPicturesDao.kt | 5 ++++- .../recentsearches/RecentSearchesDao.kt | 18 +++++++++++++----- .../fr/free/nrw/commons/utils/DatabaseUtils.kt | 15 +++++++++++++-- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsDao.kt b/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsDao.kt index d64ab16b3..bfb3ec764 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsDao.kt +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsDao.kt @@ -144,8 +144,18 @@ class BookmarkItemsDao @Inject constructor( */ @SuppressLint("Range") fun fromCursor(cursor: Cursor) = with(cursor) { + var name = getString(COLUMN_NAME) + if (name == null) { + name = "" + } + + var id = getString(COLUMN_ID) + if (id == null) { + id = "" + } + DepictedItem( - getString(COLUMN_NAME), + name, getString(COLUMN_DESCRIPTION), getString(COLUMN_IMAGE), getStringArray(COLUMN_INSTANCE_LIST), @@ -155,7 +165,7 @@ class BookmarkItemsDao @Inject constructor( getStringArray(COLUMN_CATEGORIES_THUMBNAIL_LIST) ), getString(COLUMN_IS_SELECTED).toBoolean(), - getString(COLUMN_ID) + id ) } diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesDao.kt b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesDao.kt index e30b3160d..00c8e3228 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesDao.kt +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesDao.kt @@ -128,7 +128,10 @@ class BookmarkPicturesDao @Inject constructor( } fun fromCursor(cursor: Cursor): Bookmark { - val fileName = cursor.getString(COLUMN_MEDIA_NAME) + var fileName = cursor.getString(COLUMN_MEDIA_NAME) + if (fileName == null) { + fileName = "" + } return Bookmark( fileName, cursor.getString(COLUMN_CREATOR), uriForName(fileName) ) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesDao.kt b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesDao.kt index e1d0740de..d16d250dd 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesDao.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesDao.kt @@ -163,11 +163,19 @@ class RecentSearchesDao @Inject constructor( * @param cursor * @return RecentSearch object */ - fun fromCursor(cursor: Cursor): RecentSearch = RecentSearch( - uriForId(cursor.getInt(COLUMN_ID)), - cursor.getString(COLUMN_NAME), - Date(cursor.getLong(COLUMN_LAST_USED)) - ) + fun fromCursor(cursor: Cursor): RecentSearch { + var query = cursor.getString(COLUMN_NAME) + + if (query == null) { + query = "" + } + + return RecentSearch( + uriForId(cursor.getInt(COLUMN_ID)), + query, + Date(cursor.getLong(COLUMN_LAST_USED)) + ) + } /** * This class contains the database table architechture for recent searches, diff --git a/app/src/main/java/fr/free/nrw/commons/utils/DatabaseUtils.kt b/app/src/main/java/fr/free/nrw/commons/utils/DatabaseUtils.kt index 1fd99bcee..737f34614 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/DatabaseUtils.kt +++ b/app/src/main/java/fr/free/nrw/commons/utils/DatabaseUtils.kt @@ -6,9 +6,20 @@ import android.database.Cursor fun Cursor.getStringArray(name: String): List = stringToArray(getString(name)) +/** + * Gets the String at the current row and specified column. + * + * @param name The name of the column to get the String from. + * @return The String if the column exists. Else, null is returned. + */ @SuppressLint("Range") -fun Cursor.getString(name: String): String = - getString(getColumnIndex(name)) +fun Cursor.getString(name: String): String? { + val index = getColumnIndex(name) + if (index == -1) { + return null + } + return getString(index) +} @SuppressLint("Range") fun Cursor.getInt(name: String): Int =