Skip to content

Fix compatibility with Chrome v150 - #305

Open
matheuslive wants to merge 2 commits into
JingMatrix:masterfrom
matheuslive:chrome-150-compat
Open

Fix compatibility with Chrome v150#305
matheuslive wants to merge 2 commits into
JingMatrix:masterfrom
matheuslive:chrome-150-compat

Conversation

@matheuslive

Copy link
Copy Markdown

Chrome v150 renames the fields of TabImpl, which breaks the heuristics that locate them by declaration order. With 65 instance fields, the order in which the obfuscated names are sorted (a, a0, b, b0, …) no longer matches the declaration order, so both mId and mIsLoading resolve to nothing and the !! operator throws inside the initializer of UserScriptProxy. As initHooks was not guarded, this aborts every hook and the module ends up completely inert:

java.lang.ExceptionInInitializerError
    at org.matrix.chromext.hook.UserScriptHook.init(UserScript.kt:25)
    at org.matrix.chromext.MainHook.handleLoadPackage$lambda$0(MainHook.kt:64)
Caused by: java.lang.NullPointerException
    at org.matrix.chromext.proxy.UserScriptProxy.<clinit>(UserScript.kt:64)

Same failure mode as #285. In v150 the fields are TabImpl.b (mId, found in the body of getId) and TabImpl.A (mIsLoading, the only field written by loadingStateChanged).

First commit

  • mId is resolved lazily: it is dead weight whenever getId is found, so it must not break the initializer.
  • mIsLoading is allowed to be null; the loading state is then tracked by hooking loadingStateChanged(boolean), whose name is preserved by the obfuscation since it is called from the native side, and which is the only writer of that field. Last resort is to keep injecting, which is harmless because both the init script and GM.bootstrap are idempotent for a given document.
  • initHooks(UserScriptHook) is guarded, so one broken hook no longer takes the others down.

Second commit, for the page menu (same kind of breakage as #258)

  • onMenuOrKeyboardAction takes up to 4 parameters now.
  • The field of PropertyModel is declared as a HashMap, no longer as a Map.
  • MVCListAdapter.ListItem swapped its constructor parameters to (PropertyModel, int).

Testing

Chrome 150.0.7871.186 on Android 13: every hook initializes without exception, user scripts are injected again, and the Eruda console entry is back in the app menu. Only the ChromeTabbedActivity path was exercised — Custom Tabs, Edge, Samsung Internet and Cromite were not, though the mIsLoading change does affect all of them.

TabImpl has 65 instance fields in Chrome v150, and the order in which the
obfuscated names are sorted no longer matches the declaration order, so
the heuristics locating mId and mIsLoading by position both resolve to
nothing and the !! operator throws inside the initializer of
UserScriptProxy. Since initHooks was not guarded, the resulting
ExceptionInInitializerError aborted every hook.

Resolve mId lazily, since it is dead weight whenever getId is available,
and let mIsLoading be null: in that case, track the loading state by
hooking loadingStateChanged, whose name is preserved by the obfuscation
as it is called from the native side.
Three signatures changed: onMenuOrKeyboardAction takes up to 4 parameters
now, the field of PropertyModel is declared as a HashMap instead of a Map,
and MVCListAdapter.ListItem swapped its constructor parameters.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant