Clean code (#2335)
This commit is contained in:
parent
7826b68645
commit
10804dfa7f
|
|
@ -13,6 +13,7 @@ import java.util.jar.JarFile;
|
|||
import java.util.zip.ZipEntry;
|
||||
|
||||
import sun.net.www.ParseUtil;
|
||||
import sun.net.www.protocol.jar.Handler;
|
||||
|
||||
final class ClassPathURLStreamHandler extends Handler {
|
||||
private final String fileUri;
|
||||
|
|
@ -41,7 +42,7 @@ final class ClassPathURLStreamHandler extends Handler {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
protected void finalize() throws IOException {
|
||||
jarFile.close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,192 +0,0 @@
|
|||
package org.lsposed.lspd.util;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public abstract class Handler extends java.net.URLStreamHandler {
|
||||
|
||||
private static final String separator = "!/";
|
||||
|
||||
private static int indexOfBangSlash(String spec) {
|
||||
int indexOfBang = spec.length();
|
||||
while ((indexOfBang = spec.lastIndexOf('!', indexOfBang)) != -1) {
|
||||
if ((indexOfBang != (spec.length() - 1)) &&
|
||||
(spec.charAt(indexOfBang + 1) == '/')) {
|
||||
return indexOfBang + 1;
|
||||
} else {
|
||||
indexOfBang--;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sameFile(URL u1, URL u2) {
|
||||
if (!u1.getProtocol().equals("jar") || !u2.getProtocol().equals("jar"))
|
||||
return false;
|
||||
|
||||
String file1 = u1.getFile();
|
||||
String file2 = u2.getFile();
|
||||
int sep1 = file1.indexOf(separator);
|
||||
int sep2 = file2.indexOf(separator);
|
||||
|
||||
if (sep1 == -1 || sep2 == -1) {
|
||||
return super.sameFile(u1, u2);
|
||||
}
|
||||
|
||||
String entry1 = file1.substring(sep1 + 2);
|
||||
String entry2 = file2.substring(sep2 + 2);
|
||||
|
||||
if (!entry1.equals(entry2))
|
||||
return false;
|
||||
|
||||
URL enclosedURL1, enclosedURL2;
|
||||
try {
|
||||
enclosedURL1 = new URL(file1.substring(0, sep1));
|
||||
enclosedURL2 = new URL(file2.substring(0, sep2));
|
||||
} catch (MalformedURLException unused) {
|
||||
return super.sameFile(u1, u2);
|
||||
}
|
||||
|
||||
return super.sameFile(enclosedURL1, enclosedURL2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int hashCode(URL u) {
|
||||
int h = 0;
|
||||
|
||||
String protocol = u.getProtocol();
|
||||
if (protocol != null)
|
||||
h += protocol.hashCode();
|
||||
|
||||
String file = u.getFile();
|
||||
int sep = file.indexOf(separator);
|
||||
|
||||
if (sep == -1)
|
||||
return h + file.hashCode();
|
||||
|
||||
URL enclosedURL;
|
||||
String fileWithoutEntry = file.substring(0, sep);
|
||||
try {
|
||||
enclosedURL = new URL(fileWithoutEntry);
|
||||
h += enclosedURL.hashCode();
|
||||
} catch (MalformedURLException unused) {
|
||||
h += fileWithoutEntry.hashCode();
|
||||
}
|
||||
|
||||
String entry = file.substring(sep + 2);
|
||||
h += entry.hashCode();
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void parseURL(URL url, String spec, int start, int limit) {
|
||||
String file = null;
|
||||
String ref = null;
|
||||
// first figure out if there is an anchor
|
||||
int refPos = spec.indexOf('#', limit);
|
||||
boolean refOnly = refPos == start;
|
||||
if (refPos > -1) {
|
||||
ref = spec.substring(refPos + 1);
|
||||
if (refOnly) {
|
||||
file = url.getFile();
|
||||
}
|
||||
}
|
||||
// then figure out if the spec is
|
||||
// 1. absolute (jar:)
|
||||
// 2. relative (i.e. url + foo/bar/baz.ext)
|
||||
// 3. anchor-only (i.e. url + #foo), which we already did (refOnly)
|
||||
boolean absoluteSpec = false;
|
||||
if (spec.length() >= 4) {
|
||||
absoluteSpec = spec.substring(0, 4).equalsIgnoreCase("jar:");
|
||||
}
|
||||
spec = spec.substring(start, limit);
|
||||
|
||||
if (absoluteSpec) {
|
||||
file = parseAbsoluteSpec(spec);
|
||||
} else if (!refOnly) {
|
||||
file = parseContextSpec(url, spec);
|
||||
|
||||
// Canonize the result after the bangslash
|
||||
int bangSlash = indexOfBangSlash(file);
|
||||
String toBangSlash = file.substring(0, bangSlash);
|
||||
String afterBangSlash = file.substring(bangSlash);
|
||||
afterBangSlash = canonizeString(afterBangSlash);
|
||||
file = toBangSlash + afterBangSlash;
|
||||
}
|
||||
setURL(url, "jar", "", -1, file, ref);
|
||||
}
|
||||
|
||||
private String canonizeString(String file) {
|
||||
int i;
|
||||
int lim;
|
||||
|
||||
// Remove embedded /../
|
||||
while ((i = file.indexOf("/../")) >= 0) {
|
||||
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
|
||||
file = file.substring(0, lim) + file.substring(i + 3);
|
||||
} else {
|
||||
file = file.substring(i + 3);
|
||||
}
|
||||
}
|
||||
// Remove embedded /./
|
||||
while ((i = file.indexOf("/./")) >= 0) {
|
||||
file = file.substring(0, i) + file.substring(i + 2);
|
||||
}
|
||||
// Remove trailing ..
|
||||
while (file.endsWith("/..")) {
|
||||
i = file.indexOf("/..");
|
||||
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
|
||||
file = file.substring(0, lim + 1);
|
||||
} else {
|
||||
file = file.substring(0, i);
|
||||
}
|
||||
}
|
||||
// Remove trailing .
|
||||
if (file.endsWith("/."))
|
||||
file = file.substring(0, file.length() - 1);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
private String parseAbsoluteSpec(String spec) {
|
||||
int index;
|
||||
// check for !/
|
||||
if ((index = indexOfBangSlash(spec)) == -1) {
|
||||
throw new NullPointerException("no !/ in spec");
|
||||
}
|
||||
// test the inner URL
|
||||
try {
|
||||
String innerSpec = spec.substring(0, index - 1);
|
||||
new URL(innerSpec);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new NullPointerException("invalid url: " +
|
||||
spec + " (" + e + ")");
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
private String parseContextSpec(URL url, String spec) {
|
||||
String ctxFile = url.getFile();
|
||||
// if the spec begins with /, chop up the jar back !/
|
||||
if (spec.startsWith("/")) {
|
||||
int bangSlash = indexOfBangSlash(ctxFile);
|
||||
if (bangSlash == -1) {
|
||||
throw new NullPointerException("malformed " + "context url:" + url + ": no !/");
|
||||
}
|
||||
ctxFile = ctxFile.substring(0, bangSlash);
|
||||
}
|
||||
if (!ctxFile.endsWith("/") && (!spec.startsWith("/"))) {
|
||||
// chop up the last component
|
||||
int lastSlash = ctxFile.lastIndexOf('/');
|
||||
if (lastSlash == -1) {
|
||||
throw new NullPointerException("malformed " + "context url:" + url);
|
||||
}
|
||||
ctxFile = ctxFile.substring(0, lastSlash + 1);
|
||||
}
|
||||
return (ctxFile + spec);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* This file is part of LSPosed.
|
||||
*
|
||||
* LSPosed is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LSPosed is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright (C) 2020 EdXposed Contributors
|
||||
* Copyright (C) 2021 LSPosed Contributors
|
||||
*/
|
||||
|
||||
package org.lsposed.lspd.util;
|
||||
|
||||
import android.os.IBinder;
|
||||
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
|
||||
public class InstallerVerifier {
|
||||
|
||||
public static void sendBinderToManager(final ClassLoader classLoader, IBinder binder) {
|
||||
try {
|
||||
var clazz = XposedHelpers.findClass("org.lsposed.manager.Constants", classLoader);
|
||||
var ok = (boolean) XposedHelpers.callStaticMethod(clazz, "setBinder",
|
||||
new Class[]{IBinder.class}, binder);
|
||||
if (ok) return;
|
||||
throw new RuntimeException("setBinder: " + false);
|
||||
} catch (Throwable t) {
|
||||
Utils.logW("Could not send binder to LSPosed Manager", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,10 +23,10 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import hidden.ByteBufferDexClassLoader;
|
||||
import sun.misc.CompoundEnumeration;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public final class LspModuleClassLoader extends ByteBufferDexClassLoader {
|
||||
|
|
@ -135,7 +135,12 @@ public final class LspModuleClassLoader extends ByteBufferDexClassLoader {
|
|||
protected URL findResource(String name) {
|
||||
try {
|
||||
var urlHandler = new ClassPathURLStreamHandler(apk);
|
||||
return urlHandler.getEntryUrlOrNull(name);
|
||||
var url = urlHandler.getEntryUrlOrNull(name);
|
||||
if (url == null) {
|
||||
// noinspection FinalizeCalledExplicitly
|
||||
urlHandler.finalize();
|
||||
}
|
||||
return url;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -171,16 +176,8 @@ public final class LspModuleClassLoader extends ByteBufferDexClassLoader {
|
|||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
if (apk == null) {
|
||||
return "LspModuleClassLoader[instantiating]";
|
||||
}
|
||||
var nativeLibraryDirsString = nativeLibraryDirs.stream()
|
||||
.map(File::getPath)
|
||||
.collect(Collectors.joining(", "));
|
||||
return "LspModuleClassLoader[" +
|
||||
"module=" + apk + ", " +
|
||||
"nativeLibraryDirs=" + nativeLibraryDirsString + ", " +
|
||||
super.toString() + "]";
|
||||
if (apk == null) return "LspModuleClassLoader[instantiating]";
|
||||
return "LspModuleClassLoader[module=" + apk + ", " + super.toString() + "]";
|
||||
}
|
||||
|
||||
public static ClassLoader loadApk(String apk,
|
||||
|
|
|
|||
|
|
@ -20,3 +20,8 @@
|
|||
plugins {
|
||||
`java-library`
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
package android.content.pm;
|
||||
|
||||
import android.content.IntentSender;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
import android.os.RemoteException;
|
||||
|
||||
public interface IShortcutService extends IInterface {
|
||||
boolean isRequestPinItemSupported(int user, int requestType) throws RemoteException;
|
||||
ParceledListSlice<ShortcutInfo> getShortcuts(String packageName, int matchFlags, int userId) throws RemoteException;
|
||||
ParceledListSlice<ShortcutInfo> getPinnedShortcuts(String packageName, int userId) throws RemoteException;
|
||||
boolean requestPinShortcut(String packageName, ShortcutInfo shortcut,
|
||||
IntentSender resultIntent, int userId) throws RemoteException;
|
||||
|
||||
boolean updateShortcuts(String packageName, ParceledListSlice<ShortcutInfo> shortcuts, int userId) throws RemoteException;
|
||||
|
||||
abstract class Stub extends Binder implements IShortcutService {
|
||||
|
||||
public static IShortcutService asInterface(IBinder obj) {
|
||||
throw new RuntimeException("STUB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package android.content.pm;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class ShortcutInfo implements Parcelable {
|
||||
public static final Creator<ShortcutInfo> CREATOR = new Creator<>() {
|
||||
@Override
|
||||
public ShortcutInfo createFromParcel(Parcel in) {
|
||||
throw new IllegalArgumentException("STUB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortcutInfo[] newArray(int size) {
|
||||
throw new IllegalArgumentException("STUB");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
throw new IllegalArgumentException("STUB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
throw new IllegalArgumentException("STUB");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package android.os;
|
||||
|
||||
public class ShellCallback implements Parcelable {
|
||||
public static final Parcelable.Creator<ShellCallback> CREATOR = new Creator<>() {
|
||||
public static final Parcelable.Creator<ShellCallback> CREATOR = new Creator<ShellCallback>() {
|
||||
@Override
|
||||
public ShellCallback createFromParcel(Parcel source) {
|
||||
throw new IllegalArgumentException("STUB");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package org.lsposed.lspd.util;
|
||||
package sun.misc;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.NoSuchElementException;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package sun.net.www.protocol.jar;
|
||||
|
||||
public abstract class Handler extends java.net.URLStreamHandler {
|
||||
}
|
||||
|
|
@ -89,6 +89,18 @@ public class ParasiticManagerHooker {
|
|||
return managerPkgInfo;
|
||||
}
|
||||
|
||||
private static void sendBinderToManager(final ClassLoader classLoader, IBinder binder) {
|
||||
try {
|
||||
var clazz = XposedHelpers.findClass("org.lsposed.manager.Constants", classLoader);
|
||||
var ok = (boolean) XposedHelpers.callStaticMethod(clazz, "setBinder",
|
||||
new Class[]{IBinder.class}, binder);
|
||||
if (ok) return;
|
||||
throw new RuntimeException("setBinder: " + false);
|
||||
} catch (Throwable t) {
|
||||
Utils.logW("Could not send binder to LSPosed Manager", t);
|
||||
}
|
||||
}
|
||||
|
||||
private static void hookForManager(ILSPManagerService managerService) {
|
||||
var managerApkHooker = new XC_MethodHook() {
|
||||
@Override
|
||||
|
|
@ -111,7 +123,7 @@ public class ParasiticManagerHooker {
|
|||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
var pkgInfo = getManagerPkgInfo(null);
|
||||
if (pkgInfo != null && XposedHelpers.getObjectField(param.thisObject, "mApplicationInfo") == pkgInfo.applicationInfo) {
|
||||
InstallerVerifier.sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder());
|
||||
sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder());
|
||||
unhooks[0].unhook();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue