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 f812e7007..1f135bde7 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 @@ -38,7 +38,15 @@ public final class YoutubeThrottlingDecrypter { private static final Pattern N_PARAM_PATTERN = Pattern.compile("[&?]n=([^&]+)"); private static final Pattern DECRYPT_FUNCTION_NAME_PATTERN = Pattern.compile( - "\\.get\\(\"n\"\\)\\)&&\\(b=([a-zA-Z0-9$]+)(?:\\[(\\d+)])?\\([a-zA-Z0-9]\\)"); + // CHECKSTYLE:OFF + "\\.get\\(\"n\"\\)\\)&&\\([a-zA-Z0-9$_]=([a-zA-Z0-9$_]+)(?:\\[(\\d+)])?\\([a-zA-Z0-9$_]\\)"); + // CHECKSTYLE:ON + + // Escape the curly end brace to allow compatibility with Android's regex engine + // See https://stackoverflow.com/q/45074813 + @SuppressWarnings("RegExpRedundantEscape") + private static final String DECRYPT_FUNCTION_BODY_REGEX = + "=\\s*function([\\S\\s]*?\\}\\s*return [\\w$]+?\\.join\\(\"\"\\)\\s*\\};)"; private static final Map N_PARAMS_CACHE = new HashMap<>(); private static String decryptFunction; @@ -128,11 +136,9 @@ public final class YoutubeThrottlingDecrypter { @Nonnull private static String parseWithRegex(final String playerJsCode, final String functionName) throws Parser.RegexException { - // Escape the curly end brace to allow compatibility with Android's regex engine - // See https://stackoverflow.com/q/45074813 - //noinspection RegExpRedundantEscape - final Pattern functionPattern = Pattern.compile(functionName + "=function(.*?\\};)\n", - Pattern.DOTALL); + // Quote the function name, as it may contain special regex characters such as dollar + final Pattern functionPattern = Pattern.compile( + Pattern.quote(functionName) + DECRYPT_FUNCTION_BODY_REGEX, Pattern.DOTALL); return validateFunction("function " + functionName + Parser.matchGroup1(functionPattern, playerJsCode));