@@ -38,7 +38,15 @@ public final class YoutubeThrottlingDecrypter {
3838
3939 private static final Pattern N_PARAM_PATTERN = Pattern .compile ("[&?]n=([^&]+)" );
4040 private static final Pattern DECRYPT_FUNCTION_NAME_PATTERN = Pattern .compile (
41- "\\ .get\\ (\" n\" \\ )\\ )&&\\ (b=([a-zA-Z0-9$]+)(?:\\ [(\\ d+)])?\\ ([a-zA-Z0-9]\\ )" );
41+ // CHECKSTYLE:OFF
42+ "\\ .get\\ (\" n\" \\ )\\ )&&\\ ([a-zA-Z0-9$_]=([a-zA-Z0-9$_]+)(?:\\ [(\\ d+)])?\\ ([a-zA-Z0-9$_]\\ )" );
43+ // CHECKSTYLE:ON
44+
45+ // Escape the curly end brace to allow compatibility with Android's regex engine
46+ // See https://stackoverflow.com/q/45074813
47+ @ SuppressWarnings ("RegExpRedundantEscape" )
48+ private static final String DECRYPT_FUNCTION_BODY_REGEX =
49+ "=\\ s*function([\\ S\\ s]*?\\ }\\ s*return [\\ w$]+?\\ .join\\ (\" \" \\ )\\ s*\\ };)" ;
4250
4351 private static final Map <String , String > N_PARAMS_CACHE = new HashMap <>();
4452 private static String decryptFunction ;
@@ -128,11 +136,9 @@ private static String parseDecodeFunction(final String playerJsCode, final Strin
128136 @ Nonnull
129137 private static String parseWithRegex (final String playerJsCode , final String functionName )
130138 throws Parser .RegexException {
131- // Escape the curly end brace to allow compatibility with Android's regex engine
132- // See https://stackoverflow.com/q/45074813
133- //noinspection RegExpRedundantEscape
134- final Pattern functionPattern = Pattern .compile (functionName + "=function(.*?\\ };)\n " ,
135- Pattern .DOTALL );
139+ // Quote the function name, as it may contain special regex characters such as dollar
140+ final Pattern functionPattern = Pattern .compile (
141+ Pattern .quote (functionName ) + DECRYPT_FUNCTION_BODY_REGEX , Pattern .DOTALL );
136142 return validateFunction ("function "
137143 + functionName
138144 + Parser .matchGroup1 (functionPattern , playerJsCode ));
0 commit comments