90fb2daaf151
fix: Bound cumulative locked sync inbox (v2.14.15)
- time
- 2026-08-11 17:27 UTC · 2 months ago
- machine
- koh2
- agent
- gpt-5.6-sol
- session
- opaque locked background sync
- parent
- c7780c7fe52a
↓ peach-android-90fb2daa.tar.gzatlas at this save
files changed3 files
VERSION+1 −1app/src/main/java/com/peachpasswords/sync/LockedSyncSpoolStore.kt+8 −1app/src/test/java/com/peachpasswords/sync/LockedSyncSpoolModelTest.kt+35 −0app/src/main/java/com/peachpasswords/sync/LockedSyncSpoolStore.kt+8 −1
@@ -28,7 +28,14 @@2828 val tombstones: Map<String, Long>,2929 val inboxEntries: Map<String, LockedSyncCachedEntry> = emptyMap(),3030 val inboxTombstones: Map<String, Long> = emptyMap(),31-)31+) {32+ init {33+ require(entries.size <= SyncLimits.MAX_ENTRY_COUNT) { "sync_entry_count_exceeded" }34+ require(inboxEntries.size <= SyncLimits.MAX_ENTRY_COUNT) { "sync_entry_count_exceeded" }35+ require(tombstones.size <= SyncLimits.MAX_TOMBSTONE_COUNT) { "sync_tombstone_count_exceeded" }36+ require(inboxTombstones.size <= SyncLimits.MAX_TOMBSTONE_COUNT) { "sync_tombstone_count_exceeded" }37+ }38+}3239 3340 /** A Keystore-encrypted cache of opaque entry envelopes and transport identity. */3441 @Singletonapp/src/test/java/com/peachpasswords/sync/LockedSyncSpoolModelTest.kt+35 −0
@@ -0,0 +1,35 @@1+package com.peachpasswords.sync2+3+import org.junit.Assert.assertThrows4+import org.junit.Test5+6+class LockedSyncSpoolModelTest {7+ @Test fun cumulative_inbox_counts_are_bounded_when_state_is_rebuilt() {8+ val entries = (0..SyncLimits.MAX_ENTRY_COUNT).associate { index ->9+ "entry-$index" to LockedSyncCachedEntry(1, "AA==")10+ }11+ val tombstones = (0..SyncLimits.MAX_TOMBSTONE_COUNT).associate { index ->12+ "tombstone-$index" to 1L13+ }14+15+ assertThrows(IllegalArgumentException::class.java) { state(inboxEntries = entries) }16+ assertThrows(IllegalArgumentException::class.java) { state(inboxTombstones = tombstones) }17+ }18+19+ private fun state(20+ inboxEntries: Map<String, LockedSyncCachedEntry> = emptyMap(),21+ inboxTombstones: Map<String, Long> = emptyMap(),22+ ) = LockedSyncSpool(23+ vaultId = "a".repeat(64),24+ deviceId = "device",25+ deviceName = "Android",26+ localVersion = 1,27+ longTermPublicKeyHex = "b".repeat(64),28+ longTermPrivateKeyHex = "c".repeat(64),29+ signingPublicKeyHex = "d".repeat(64),30+ entries = emptyMap(),31+ tombstones = emptyMap(),32+ inboxEntries = inboxEntries,33+ inboxTombstones = inboxTombstones,34+ )35+}