From 9e93d6b1936e9d4fbe7ae3efc1e6c635fbff2429 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 21 Aug 2022 20:16:45 +0200 Subject: [PATCH] YoutubeThrottlingDecrypter: Check if returned string is a valid JavaScript function --- .../youtube/YoutubeThrottlingDecrypter.java | 18 ++++++++++++++---- .../newpipe/extractor/utils/JavaScript.java | 12 ++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeThrottlingDecrypter.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeThrottlingDecrypter.java index d6ae18112..3b096fd51 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeThrottlingDecrypter.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeThrottlingDecrypter.java @@ -5,12 +5,13 @@ import org.schabi.newpipe.extractor.utils.JavaScript; import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.StringUtils; -import javax.annotation.Nonnull; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.annotation.Nonnull; + /** * YouTube's streaming URLs of HTML5 clients are protected with a cipher, which modifies their * {@code n} query parameter. @@ -154,8 +155,9 @@ public class YoutubeThrottlingDecrypter { private static String parseWithParenthesisMatching(final String playerJsCode, final String functionName) { final String functionBase = functionName + "=function"; - return functionBase + StringUtils.matchToClosingParenthesis(playerJsCode, functionBase) - + ";"; + return validateFunction(functionBase + + StringUtils.matchToClosingParenthesis(playerJsCode, functionBase) + + ";"); } @Nonnull @@ -163,7 +165,15 @@ public class YoutubeThrottlingDecrypter { throws Parser.RegexException { final Pattern functionPattern = Pattern.compile(functionName + "=function(.*?};)\n", Pattern.DOTALL); - return "function " + functionName + Parser.matchGroup1(functionPattern, playerJsCode); + return validateFunction("function " + + functionName + + Parser.matchGroup1(functionPattern, playerJsCode)); + } + + @Nonnull + private static String validateFunction(@Nonnull final String function) { + JavaScript.compileOrThrow(function); + return function; } @Deprecated diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/JavaScript.java b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/JavaScript.java index c58879384..ab30ed806 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/JavaScript.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/JavaScript.java @@ -9,6 +9,18 @@ public final class JavaScript { private JavaScript() { } + public static void compileOrThrow(final String function) { + try { + final Context context = Context.enter(); + context.setOptimizationLevel(-1); + + // If it doesn't compile it throws an exception here + context.compileString(function, null, 1, null); + } finally { + Context.exit(); + } + } + public static String run(final String function, final String functionName, final String... parameters) {