-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
The app crashes with a StackOverflowError
when attempting to delete a folder that has been renamed, while navigating deep within its nested child structure.
This seems to be caused by uncontrolled recursion in RealSavedSitesRepository.traverseBranch()
, likely due to cyclic or deep traversal of a folder structure.
stack trace:
FATAL EXCEPTION: DefaultDispatcher-worker-10
Process: com.duckduckgo.mobile.android.debug, PID: 31900
java.lang.StackOverflowError: stack size 1035KB
at java.lang.Object.hashCode(Object.java:122)
at java.util.WeakHashMap.hash(WeakHashMap.java:303)
at java.util.WeakHashMap.put(WeakHashMap.java:455)
at android.database.sqlite.SQLiteConnectionPool.finishAcquireConnectionLocked(SQLiteConnectionPool.java:1026)
at android.database.sqlite.SQLiteConnectionPool.tryAcquirePrimaryConnectionLocked(SQLiteConnectionPool.java:960)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:723)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:392)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:896)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:62)
at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1714)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1689)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.kt:156)
at androidx.room.RoomDatabase.query(RoomDatabase.kt:484)
at androidx.room.util.DBUtil.query(DBUtil.kt:75)
at com.duckduckgo.savedsites.store.SavedSitesRelationsDao_Impl.countEntitiesInFolder(SavedSitesRelationsDao_Impl.kt:589)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.mapToBookmarkFolder(SavedSitesRepository.kt:597)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.folderContent(SavedSitesRepository.kt:201)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.traverseBranch(SavedSitesRepository.kt:181)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.traverseBranch(SavedSitesRepository.kt:185)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.traverseBranch(SavedSitesRepository.kt:185)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.traverseBranch(SavedSitesRepository.kt:185)
………(repeat)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.traverseBranch(SavedSitesRepository.kt:185)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.getFolderBranch(SavedSitesRepository.kt:172)
at com.duckduckgo.savedsites.impl.RealSavedSitesRepository.deleteFolderBranch(SavedSitesRepository.kt:210)
at com.duckduckgo.savedsites.impl.bookmarks.BookmarksViewModel$delete$2.invokeSuspend(BookmarksViewModel.kt:328)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:811)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:715)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:702)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelled}@4253af9, [Dispatchers.IO](http://dispatchers.io/)]
How to Reproduce
- Open the DuckDuckGo app
- Navigate to Bookmarks
- Add a new folder named "a"
- Enter folder "a"
- Add a subfolder named "b" inside "a"
- Enter folder "b"
- Use the search bar to find folder "a" again
- Click the Edit option for folder "a", and rename it to "c"
- After renaming, delete folder "c"
- App crashes
output_silent.webm
Expected behavior
The folder should be safely deleted without causing the app to crash.
Environment
- DDG App Version:5.238.0
- Device:Pixel 5
- OS:Android 14