@@ -9,11 +9,14 @@ import com.lagradost.cloudstream3.utils.INFER_TYPE
99import com.lagradost.cloudstream3.utils.Qualities
1010import com.lagradost.cloudstream3.utils.loadExtractor
1111import com.lagradost.cloudstream3.utils.newExtractorLink
12+ import kotlinx.coroutines.Dispatchers
1213import kotlinx.coroutines.delay
14+ import kotlinx.coroutines.withContext
1315import org.jsoup.Jsoup
1416import org.jsoup.nodes.Element
1517import org.mozilla.javascript.BaseFunction
1618import org.mozilla.javascript.Context
19+ import org.mozilla.javascript.ContextFactory
1720import org.mozilla.javascript.Function
1821import org.mozilla.javascript.Scriptable
1922import org.mozilla.javascript.ScriptableObject
@@ -249,7 +252,7 @@ class KuramanimeProvider : MainAPI() {
249252 suspend fun fetchAuth (): String {
250253 val url = " $mainUrl /storage/leviathan.js?v=${System .currentTimeMillis()} "
251254 val res = app.get(url).text
252- return extractAuthToken(res) ? : throw ErrorLoadingException ()
255+ return withContext( Dispatchers . IO ) { extractAuthToken(res) } ? : throw ErrorLoadingException ()
253256 }
254257
255258 private fun extractAuthToken (rawScript : String ): String? {
@@ -269,65 +272,89 @@ class KuramanimeProvider : MainAPI() {
269272 }
270273 }
271274
272- val rhino = Context .enter()
273- try {
274- rhino.optimizationLevel = - 1 // interpreted mode: avoids JVM method-size limits on big scripts
275- rhino.setLanguageVersion(Context .VERSION_ES6 )
276- val scope: Scriptable = rhino.initSafeStandardObjects()
275+ val factory = object : ContextFactory () {
276+ override fun observeInstructionCount (cx : Context , instructionCount : Int ) {
277+ if (Thread .currentThread().isInterrupted) {
278+ throw InterruptedException (" aborted" )
279+ }
280+ }
277281
278- val noop = object : BaseFunction () {
279- override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any =
280- Undefined .instance
282+ override fun makeContext (): Context {
283+ val cx = super .makeContext()
284+ cx.instructionObserverThreshold = 2000
285+ return cx
281286 }
282- val fetchStub = object : BaseFunction () {
283- override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any {
284- captureFromOptions(args.getOrNull(1 ))
285- return Undefined .instance
287+ }
288+
289+ val worker = Thread (null , {
290+ val rhino = factory.enterContext()
291+ try {
292+ rhino.optimizationLevel = - 1 // interpreted mode: avoids JVM method-size limits on big scripts + enables the kill switch above
293+ rhino.setLanguageVersion(Context .VERSION_ES6 )
294+ val scope: Scriptable = rhino.initSafeStandardObjects()
295+
296+ val noop = object : BaseFunction () {
297+ override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any =
298+ Undefined .instance
286299 }
287- }
288- val ajaxStub = object : BaseFunction () {
289- override fun call ( cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array < Any ?>): Any {
290- captureFromOptions(args.getOrNull( 0 ))
291- return Undefined .instance
300+ val fetchStub = object : BaseFunction () {
301+ override fun call ( cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array < Any ?>): Any {
302+ captureFromOptions( args.getOrNull( 1 ))
303+ return Undefined .instance
304+ }
292305 }
293- }
294- val dollarStub = object : BaseFunction () {
295- override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any = scope
296- }
297- ScriptableObject .putProperty(dollarStub, " ajax" , ajaxStub)
298-
299- scope.put(" fetch" , scope, fetchStub)
300- scope.put(" $" , scope, dollarStub)
301- scope.put(" setInterval" , scope, noop)
302- scope.put(" setTimeout" , scope, noop)
303- scope.put(" clearInterval" , scope, noop)
304- scope.put(" clearTimeout" , scope, noop)
305- scope.put(" document" , scope, rhino.newObject(scope))
306- scope.put(" navigator" , scope, rhino.newObject(scope))
307- scope.put(" window" , scope, scope)
308-
309- val preExisting = scope.ids.toSet()
310-
311- rhino.evaluateString(scope, script, " leviathan.js" , 1 , null )
312-
313- val dummyOpts = rhino.newObject(scope)
314- val candidateArgs = arrayOf<Any ?>(
315- " $mainUrl /probe" , " POST" , " json" , dummyOpts, noop, noop, noop
316- )
317-
318- for (id in scope.ids) {
319- if (captured != null ) break
320- val name = id as ? String ? : continue
321- if (name in preExisting) continue
322- val fn = ScriptableObject .getProperty(scope, name) as ? Function ? : continue
323- try {
324- fn.call(rhino, scope, scope, candidateArgs)
325- } catch (_: Exception ) {
306+ val ajaxStub = object : BaseFunction () {
307+ override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any {
308+ captureFromOptions(args.getOrNull(0 ))
309+ return Undefined .instance
310+ }
311+ }
312+ val dollarStub = object : BaseFunction () {
313+ override fun call (cx : Context , scope : Scriptable , thisObj : Scriptable , args : Array <Any ?>): Any = scope
314+ }
315+ ScriptableObject .putProperty(dollarStub, " ajax" , ajaxStub)
316+
317+ scope.put(" fetch" , scope, fetchStub)
318+ scope.put(" $" , scope, dollarStub)
319+ scope.put(" setInterval" , scope, noop)
320+ scope.put(" setTimeout" , scope, noop)
321+ scope.put(" clearInterval" , scope, noop)
322+ scope.put(" clearTimeout" , scope, noop)
323+ scope.put(" document" , scope, rhino.newObject(scope))
324+ scope.put(" navigator" , scope, rhino.newObject(scope))
325+ scope.put(" window" , scope, scope)
326+
327+ val preExisting = scope.ids.toSet()
328+
329+ rhino.evaluateString(scope, script, " leviathan.js" , 1 , null )
330+
331+ val dummyOpts = rhino.newObject(scope)
332+ val candidateArgs = arrayOf<Any ?>(
333+ " $mainUrl /probe" , " POST" , " json" , dummyOpts, noop, noop, noop
334+ )
335+
336+ for (id in scope.ids) {
337+ if (captured != null ) break
338+ val name = id as ? String ? : continue
339+ if (name in preExisting) continue
340+ val fn = ScriptableObject .getProperty(scope, name) as ? Function ? : continue
341+ try {
342+ fn.call(rhino, scope, scope, candidateArgs)
343+ } catch (_: Throwable ) {
344+ }
326345 }
346+ } catch (_: Throwable ) {
347+ } finally {
348+ Context .exit()
327349 }
328- } catch (_: Exception ) {
329- } finally {
330- Context .exit()
350+ }, " kuramanime-leviathan-js" , 8 * 1024 * 1024 )
351+
352+ worker.isDaemon = true
353+ worker.start()
354+ worker.join(10_000L )
355+ if (worker.isAlive) {
356+ worker.interrupt()
357+ worker.join(1_000L )
331358 }
332359
333360 return captured
0 commit comments