优化
This commit is contained in:
@@ -14,7 +14,9 @@ import io.legado.app.help.crypto.SymmetricCryptoAndroid
|
|||||||
import io.legado.app.help.http.CookieStore
|
import io.legado.app.help.http.CookieStore
|
||||||
import io.legado.app.help.source.copy
|
import io.legado.app.help.source.copy
|
||||||
import io.legado.app.help.source.getShareScope
|
import io.legado.app.help.source.getShareScope
|
||||||
|
import io.legado.app.model.Debug
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
|
import io.legado.app.utils.GSONStrict
|
||||||
import io.legado.app.utils.fromJsonArray
|
import io.legado.app.utils.fromJsonArray
|
||||||
import io.legado.app.utils.fromJsonObject
|
import io.legado.app.utils.fromJsonObject
|
||||||
import io.legado.app.utils.has
|
import io.legado.app.utils.has
|
||||||
@@ -112,7 +114,10 @@ interface BaseSource : JsExtensions {
|
|||||||
|
|
||||||
else -> it
|
else -> it
|
||||||
}
|
}
|
||||||
GSON.fromJsonObject<Map<String, String>>(json).getOrNull()?.let { map ->
|
GSONStrict.fromJsonObject<Map<String, String>>(json).getOrNull()?.let { map ->
|
||||||
|
putAll(map)
|
||||||
|
} ?: GSON.fromJsonObject<Map<String, String>>(json).getOrNull()?.let { map ->
|
||||||
|
Debug.log("≡请求头规则 JSON 格式不规范,请改为规范格式")
|
||||||
putAll(map)
|
putAll(map)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
@@ -520,6 +520,12 @@ class AnalyzeRule(
|
|||||||
return ruleList
|
return ruleList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getOrCreateSingleSourceRule(rule: String): List<SourceRule> {
|
||||||
|
return stringRuleCache.getOrPutLimit(rule, 16) {
|
||||||
|
listOf(SourceRule(rule))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 规则类
|
* 规则类
|
||||||
*/
|
*/
|
||||||
@@ -672,7 +678,8 @@ class AnalyzeRule(
|
|||||||
|
|
||||||
regType == jsRuleType -> {
|
regType == jsRuleType -> {
|
||||||
if (isRule(ruleParam[index])) {
|
if (isRule(ruleParam[index])) {
|
||||||
getString(arrayListOf(SourceRule(ruleParam[index]))).let {
|
val ruleList = getOrCreateSingleSourceRule(ruleParam[index])
|
||||||
|
getString(ruleList).let {
|
||||||
infoVal.insert(0, it)
|
infoVal.insert(0, it)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ recyclerview = "1.2.0"
|
|||||||
#noinspection GradleDependency
|
#noinspection GradleDependency
|
||||||
viewpager2 = "1.0.0"
|
viewpager2 = "1.0.0"
|
||||||
webkit = "1.13.0"
|
webkit = "1.13.0"
|
||||||
|
collection = "1.5.0"
|
||||||
|
|
||||||
zxingLite = "3.2.0"
|
zxingLite = "3.2.0"
|
||||||
|
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activ
|
|||||||
androidx-annotation = { group = "androidx.annotation", name = "annotation", version = "1.9.1" }
|
androidx-annotation = { group = "androidx.annotation", name = "annotation", version = "1.9.1" }
|
||||||
#androidx-annotation-experimental = { group = "androidx.annotation", name = "annotation-experimental", version = "1.3.1" }
|
#androidx-annotation-experimental = { group = "androidx.annotation", name = "annotation-experimental", version = "1.3.1" }
|
||||||
|
|
||||||
|
androidx-collection = { module = "androidx.collection:collection", version.ref = "collection" }
|
||||||
appcompat-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
|
appcompat-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
|
||||||
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
implementation(libs.okhttp)
|
implementation(libs.okhttp)
|
||||||
|
implementation(libs.androidx.collection)
|
||||||
|
|
||||||
// def coroutines_version = '1.7.3'
|
// def coroutines_version = '1.7.3'
|
||||||
// implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
|
// implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.script.rhino
|
||||||
|
|
||||||
|
import androidx.collection.LruCache
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
class ClassNameMatcher(classNames: List<String>) {
|
||||||
|
|
||||||
|
private val sortedClassNames = classNames.sorted()
|
||||||
|
private val matchCache = LruCache<String, Boolean>(64)
|
||||||
|
|
||||||
|
fun match(className: String): Boolean {
|
||||||
|
matchCache[className]?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
val match = matchInternal(className)
|
||||||
|
matchCache.put(className, match)
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun matchInternal(className: String): Boolean {
|
||||||
|
val index = sortedClassNames.fastBinarySearch { prefix ->
|
||||||
|
comparePrefix(className, prefix)
|
||||||
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val prefix = sortedClassNames.getOrNull(-index - 2) ?: return false
|
||||||
|
return className.getOrNull(prefix.length) == '.' && className.startsWith(prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun comparePrefix(className: String, prefix: String): Int {
|
||||||
|
val len = min(className.length, prefix.length)
|
||||||
|
for (i in 0 ..< len) {
|
||||||
|
val c1 = className[i]
|
||||||
|
val c2 = prefix[i]
|
||||||
|
if (c1 != c2) return c2 - c1
|
||||||
|
}
|
||||||
|
return prefix.length - className.length
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.script.rhino
|
||||||
|
|
||||||
|
inline fun <T> List<T>.fastBinarySearch(
|
||||||
|
comparison: (T) -> Int
|
||||||
|
): Int {
|
||||||
|
var low = 0
|
||||||
|
var high = lastIndex
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
val midVal = get(mid)
|
||||||
|
val cmp = comparison(midVal)
|
||||||
|
|
||||||
|
if (cmp < 0)
|
||||||
|
low = mid + 1
|
||||||
|
else if (cmp > 0)
|
||||||
|
high = mid - 1
|
||||||
|
else
|
||||||
|
return mid // key found
|
||||||
|
}
|
||||||
|
return -(low + 1) // key not found
|
||||||
|
}
|
||||||
@@ -45,8 +45,8 @@ import java.util.Collections
|
|||||||
*/
|
*/
|
||||||
object RhinoClassShutter : ClassShutter {
|
object RhinoClassShutter : ClassShutter {
|
||||||
|
|
||||||
private val protectedClassNames by lazy {
|
private val protectedClassNamesMatcher by lazy {
|
||||||
hashSetOf(
|
listOf(
|
||||||
"java.lang.Class",
|
"java.lang.Class",
|
||||||
"java.lang.ClassLoader",
|
"java.lang.ClassLoader",
|
||||||
"java.net.URLClassLoader",
|
"java.net.URLClassLoader",
|
||||||
@@ -113,7 +113,7 @@ object RhinoClassShutter : ClassShutter {
|
|||||||
"com.script",
|
"com.script",
|
||||||
"org.mozilla",
|
"org.mozilla",
|
||||||
"sun",
|
"sun",
|
||||||
).let { Collections.unmodifiableSet(it) }
|
).let { ClassNameMatcher(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val systemClassProtectedName by lazy {
|
private val systemClassProtectedName by lazy {
|
||||||
@@ -181,14 +181,7 @@ object RhinoClassShutter : ClassShutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visibleToScripts(fullClassName: String): Boolean {
|
override fun visibleToScripts(fullClassName: String): Boolean {
|
||||||
var className = fullClassName
|
return !protectedClassNamesMatcher.match(fullClassName)
|
||||||
while (className.isNotEmpty()) {
|
|
||||||
if (protectedClassNames.contains(className)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
className = className.substringBeforeLast(".", "")
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user