From e714cb6423d752fc747518c1eccda6652be6be77 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 15 May 2020 11:11:27 -0400 Subject: [PATCH] Fix potential issues with ConversationDataSource boundaries. --- .../conversation/ConversationAdapter.java | 5 +++- .../conversation/ConversationDataSource.java | 25 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationAdapter.java index 1cbd7e47e8..af16b65180 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationAdapter.java @@ -357,7 +357,7 @@ public class ConversationAdapter * Momentarily highlights a row at the requested position. */ void pulseHighlightItem(int position) { - if (position < getItemCount()) { + if (position >= 0 && position < getItemCount()) { recordToPulseHighlight = getItem(position); notifyItemChanged(position); } @@ -430,7 +430,10 @@ public class ConversationAdapter pool.setMaxRecycledViews(MESSAGE_TYPE_UPDATE, 5); } + @MainThread private void cleanFastRecords() { + Util.assertMainThread(); + synchronized (releasedFastRecords) { Iterator recordIterator = fastRecords.iterator(); while (recordIterator.hasNext()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java index 4289dd0b8f..fcae9bb23e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java @@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.util.Util; import java.util.ArrayList; import java.util.List; +import java.util.Locale; /** * Core data source for loading an individual conversation. @@ -58,7 +59,20 @@ class ConversationDataSource extends PositionalDataSource { } } - callback.onResult(records, params.requestedStartPosition, db.getConversationCount(threadId)); + int effectiveCount = records.size() + params.requestedStartPosition; + int totalCount = db.getConversationCount(threadId); + + if (effectiveCount > totalCount) { + Log.w(TAG, String.format(Locale.ENGLISH, "Miscalculation! Records: %d, Start Position: %d, Total: %d. Adjusting total.", + records.size(), + params.requestedStartPosition, + totalCount)); + totalCount = effectiveCount; + } + + records = ensureMultipleOfPageSize(records, params.pageSize, totalCount); + + callback.onResult(records, params.requestedStartPosition, totalCount); Util.runOnMain(dataUpdateCallback::onDataUpdated); Log.d(TAG, "[Initial Load] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : "")); @@ -84,6 +98,15 @@ class ConversationDataSource extends PositionalDataSource { Log.d(TAG, "[Update] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : "")); } + private static @NonNull List ensureMultipleOfPageSize(@NonNull List records, int pageSize, int total) { + if (records.size() != total && records.size() % pageSize != 0) { + int overflow = records.size() % pageSize; + return records.subList(0, records.size() - overflow); + } else { + return records; + } + } + interface DataUpdatedCallback { void onDataUpdated(); }