Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.NullPointerException: getEtag(...) must not be null #284

Closed
TheLastZombie opened this issue Nov 25, 2024 · 3 comments · Fixed by #285
Closed

java.lang.NullPointerException: getEtag(...) must not be null #284

TheLastZombie opened this issue Nov 25, 2024 · 3 comments · Fixed by #285
Labels

Comments

@TheLastZombie
Copy link

Overview

When trying to access a KeePass database file on a WebDAV server, KeePassVault crashes with the following error:

java.lang.NullPointerException: getEtag(...) must not be null
	at com.ivanovsky.passnotes.data.repository.file.webdav.WebDavClientV2.toRemoteFileMetadata(WebDavClientV2.kt:333)
	at com.ivanovsky.passnotes.data.repository.file.webdav.WebDavClientV2.toRemoteFileMetadata$default(WebDavClientV2.kt:319)
	at com.ivanovsky.passnotes.data.repository.file.webdav.WebDavClientV2.getFileMetadata(WebDavClientV2.kt:158)
	at com.ivanovsky.passnotes.data.repository.file.webdav.WebDavClientV2.getFileMetadata(WebDavClientV2.kt:138)
	at com.ivanovsky.passnotes.data.repository.file.remote.RemoteApiClientAdapter.getFileMetadataOrThrow(RemoteApiClientAdapter.kt:44)
	at com.ivanovsky.passnotes.data.repository.file.remote.RemoteFileSystemProvider.openFileForRead(RemoteFileSystemProvider.java:295)
	at com.ivanovsky.passnotes.data.repository.keepass.KeepassDatabaseRepository.open(KeepassDatabaseRepository.kt:53)
	at com.ivanovsky.passnotes.domain.interactor.unlock.UnlockInteractor$openDatabase$2.invokeSuspend(UnlockInteractor.kt:113)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@8b5a6ee, Dispatchers.Main.immediate]

How to reproduce

  1. Set up a WebDAV server. I've tried copyparty and dufs, the issue occurs with both.
  2. Upload a KeePass database to the server.
  3. Open KeePassVault and add the database to the list.
  4. Enter the database password. When tapping the unlock button, the app crashes with the above message.

Version

1.9.0 (via F-Droid)

Android Version

Android 15 (GrapheneOS)

Device Model

Pixel 8 Pro

@9001
Copy link

9001 commented Nov 27, 2024

KeepassVault expects the WebDAV server to provide an ETag, which it uses to ensure that the file contents have (or have not) been altered on the serverside. This makes perfect sense, but according to the WebDAV spec, it is not required that WebDAV servers implement ETag support. It is however strongly recommended.

Most of the synchronization-oriented WebDAV servers do have ETags, such as owncloud, nextcloud and seafile, as this is necessary to keep track of sync state, but many of the smaller lightweight servers do not. Usually the reason is that those servers do not keep track of file contents, and thus don't have a good basis for providing a strong ETag.

So the question is whether @aivanovski made the ETag requirement as a conscious decision. Most WebDAV servers operate at a 1-second precision in the last-modified timestamps, so I can understand the preference of a strong ETag, to be entirely certain of the server state. One approach could be for KeepassVault to generate its own weak ETags when necessary, based on the server's lastmodified header. But again, I understand if there is an apprehension towards this.

I'll quickly mention that copyparty is in a position where strong ETags could be provided, but performance concerns and (until now) a lack of interest has not made this a priority.

@aivanovski
Copy link
Owner

Hi @9001
Thank you for the detailed explanation. I didn't know that ETag is optional, it should be easy to replace it with last-modified when it is not available.

@aivanovski aivanovski linked a pull request Nov 30, 2024 that will close this issue
@aivanovski
Copy link
Owner

The fix is in version 1.10.0. Build is available in Releases page or will be available later in Google Play and F-Droid. Thanks for reporting this issue. @TheLastZombie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants