Please check before submitting an issue
Describe the bug
-
The app crashes when I enter an invalid path in the AppManager file manager (fmActivity).
In 'normal' mode it shows an error when I open classes.dex inside an APK file, it uses the Virtual File System Protocol VFS:.
Entering a valid path works:
vfs://889435226/com
-
But when I enter the following path:
vfs://889435226/com.android.billingclient.api.ProxyBillingActivity
-> App will crash.
-
Entering:
vfs://889435226/coM
-> App will crash as well.
To Reproduce
-
Open AppManager FileExplorer (fmActivity).
-
Open some apk and the classes.dex inside
-
Tap the pencil icon. In the Go to.... dialog enter some invalid path like:
vfs://889435226/coM
->App crashes
Expected behavior
- App should just tell me 'invalid path' without crashing
Furthermore, inside the VFS: it should be possible to enter Java like path like
vfs://889435226/com.android
instead of
vfs://889435226/com/android
Screenshots
Logs
CrashLog / Stacktrace:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at j$.util.Objects.requireNonNull(SourceFile:219)
at io.github.muntashirakon.io.PathImpl.<init>(PathImpl.java:214)
at io.github.muntashirakon.io.Paths.getStrict(Paths.java:136)
at io.github.muntashirakon.AppManager.fm.FmViewModel.loadFiles(FmViewModel.java:288)
at io.github.muntashirakon.AppManager.fm.FmViewModel.loadFiles(FmViewModel.java:266)
at io.github.muntashirakon.AppManager.fm.FmFragment.goToRawPath(FmFragment.java:612)
at io.github.muntashirakon.AppManager.fm.FmFragment.lambda$onViewCreated$1$io-github-muntashirakon-AppManager-fm-FmFragment(FmFragment.java:231)
at io.github.muntashirakon.AppManager.fm.FmFragment$$ExternalSyntheticLambda4.onClick(D8$$SyntheticClass:0)
at io.github.muntashirakon.dialog.TextInputDialogBuilder.lambda$setPositiveButton$0$io-github-muntashirakon-dialog-TextInputDialogBuilder(TextInputDialogBuilder.java:130)
at io.github.muntashirakon.dialog.TextInputDialogBuilder$$ExternalSyntheticLambda6.onClick(D8$$SyntheticClass:0)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7939)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:551)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:854)
crashdiag - Device Info:
App version: 4.0.5
App version code: 445
Android build version: 1722335373
Android release version: 13
Android SDK version: 33
Android build ID: TQ3A.230901.001
Device brand: samsung
Device manufacturer: samsung
Device name: starlte
Device model: SM-G960F
Device product name: lineage_starlte
Device hardware name: samsungexynos9810
ABIs: [arm64-v8a, armeabi-v7a, armeabi]
ABIs (32bit): [armeabi-v7a, armeabi]
ABIs (64bit): [arm64-v8a]
System language: en
In-App Language: en
Mode: root
Inferred Mode: Root
Device info
- Device: Samsung S9
- OS Version: 13
- App Manager Version: 4.0.5
- Mode: Root
Additional context
- I was evaluating the possibility of better integrating the code explorer.
In the App Info Activity tab, make the path like
com.android.billingclient.api.ProxyBillingActivity
tapable and open it in the AppManager CodeEditor in Java mode to directly examine the code.
However, I'll launch my own issue for that.
Fixing the bug
- I see there is already a try-catch handle inside FmViewModel.loadFiles()
Hmm, strange. Why doesn't it catch the error?
I'm going to ask CoPilot on that.
UPDATE:
I'm back from the 'AI-oracle' :)
Okay, fixing it like this:
} catch (IOException e) {
to
} catch (IOException | NullPointerException e) {
It is tempting.
But it just will conceal an error that lies deeper in the code.
It's the file resolver !!!
[muntashirakon.io.PathImpl.java] (
|
finalDocumentFile = Objects.requireNonNull(finalDocumentFile.findFile(pathComponent)); |
)
erroneously raises a
NullPointerException instead of an
IOException.
Checked vs. Unchecked - why that matters?
These two exceptions are not in the same 'groups'. The NullPointerException is an 'unchecked' one and slips through.
... and crashes the app.
So crash is there for a good reason.
NullPointerException is an unchecked exception and signals that something is fundamentally wrong.
While IOException is a checked one. The idea here is that something is expected to happen once in a while.
So
throw new IOException("Invalid VFS path component: " + pathComponent); should be more appropriate.
"Try" in loadFiles() will catch it and in the end prevents the app from crashing. ;^)
Anyway, stay tuned; PR is on the way... ;^)
Please check before submitting an issue
Describe the bug
The app crashes when I enter an invalid path in the AppManager file manager (fmActivity).
In 'normal' mode it shows an error when I open classes.dex inside an APK file, it uses the Virtual File System Protocol VFS:.
Entering a valid path works:
vfs://889435226/comBut when I enter the following path:
vfs://889435226/com.android.billingclient.api.ProxyBillingActivity-> App will crash.
Entering:
vfs://889435226/coM-> App will crash as well.
To Reproduce
Open AppManager FileExplorer (fmActivity).
Open some apk and the classes.dex inside
Tap the pencil icon. In the Go to.... dialog enter some invalid path like:
vfs://889435226/coM->App crashes
Expected behavior
Furthermore, inside the VFS: it should be possible to enter Java like path like
vfs://889435226/com.androidinstead of
vfs://889435226/com/androidScreenshots
Logs
CrashLog / Stacktrace:
crashdiag - Device Info:
Device info
Additional context
In the App Info Activity tab, make the path like
com.android.billingclient.api.ProxyBillingActivity
tapable and open it in the AppManager CodeEditor in Java mode to directly examine the code.
However, I'll launch my own issue for that.
Fixing the bug
Hmm, strange. Why doesn't it catch the error?
I'm going to ask CoPilot on that.
UPDATE:
I'm back from the 'AI-oracle' :)
Okay, fixing it like this:
} catch (IOException e) {to
} catch (IOException | NullPointerException e) {It is tempting.
But it just will conceal an error that lies deeper in the code.
It's the file resolver !!!
[muntashirakon.io.PathImpl.java] (
AppManager/app/src/main/java/io/github/muntashirakon/io/PathImpl.java
Line 214 in 4f69a92
erroneously raises a NullPointerException instead of an IOException.
Checked vs. Unchecked - why that matters?
These two exceptions are not in the same 'groups'. The NullPointerException is an 'unchecked' one and slips through.
... and crashes the app.
So crash is there for a good reason.
NullPointerException is an unchecked exception and signals that something is fundamentally wrong.
While IOException is a checked one. The idea here is that something is expected to happen once in a while.
So
throw new IOException("Invalid VFS path component: " + pathComponent);should be more appropriate."Try" in loadFiles() will catch it and in the end prevents the app from crashing. ;^)
Anyway, stay tuned; PR is on the way... ;^)