This commit is contained in:
Horis
2025-05-21 14:29:58 +08:00
parent 4488c16ecd
commit 6daff489a1
7 changed files with 85 additions and 13 deletions
@@ -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 {
+3
View File
@@ -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" }
+1
View File
@@ -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
} }
} }