[YouTube] Add parenthesis matching as way to parse decrypt function
From @Stypox
This commit is contained in:
parent
2967d1ae6a
commit
60794aea31
2 changed files with 62 additions and 1 deletions
|
@ -3,6 +3,7 @@ package org.schabi.newpipe.extractor.services.youtube;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.utils.JavaScript;
|
import org.schabi.newpipe.extractor.utils.JavaScript;
|
||||||
import org.schabi.newpipe.extractor.utils.Parser;
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
|
import org.schabi.newpipe.extractor.utils.StringUtil;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -71,7 +72,20 @@ public class YoutubeThrottlingDecrypter {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private String parseDecodeFunction(final String playerJsCode, final String functionName)
|
private String parseDecodeFunction(final String playerJsCode, final String functionName)
|
||||||
throws Parser.RegexException {
|
throws Parser.RegexException {
|
||||||
Pattern functionPattern = Pattern.compile(functionName + "=function(.*?};)\n",
|
try {
|
||||||
|
return parseWithParenthesisMatching(playerJsCode, functionName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return parseWithRegex(playerJsCode, functionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseWithParenthesisMatching(final String playerJsCode, final String functionName) {
|
||||||
|
final String functionBase = functionName + "=function";
|
||||||
|
return functionBase + StringUtil.matchToClosingParenthesis(playerJsCode, functionBase) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseWithRegex(final String playerJsCode, final String functionName) throws Parser.RegexException {
|
||||||
|
Pattern functionPattern = Pattern.compile(functionName + "=function(.*?}};)\n",
|
||||||
Pattern.DOTALL);
|
Pattern.DOTALL);
|
||||||
return "function " + functionName + Parser.matchGroup1(functionPattern, playerJsCode);
|
return "function " + functionName + Parser.matchGroup1(functionPattern, playerJsCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.schabi.newpipe.extractor.utils;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
|
|
||||||
|
public class StringUtil {
|
||||||
|
|
||||||
|
private StringUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string The string to search in
|
||||||
|
* @param start A string from which to start searching.
|
||||||
|
* @return A substring where each '{' matches a '}'
|
||||||
|
* @throws IndexOutOfBoundsException If {@ string} does not contain {@code start}
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static String matchToClosingParenthesis(@NonNull final String string, @NonNull final String start) {
|
||||||
|
int startIndex = string.indexOf(start);
|
||||||
|
if (startIndex < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
startIndex += start.length();
|
||||||
|
int endIndex = startIndex;
|
||||||
|
while (string.charAt(endIndex) != '{') {
|
||||||
|
++endIndex;
|
||||||
|
}
|
||||||
|
++endIndex;
|
||||||
|
|
||||||
|
int openParenthesis = 1;
|
||||||
|
while (openParenthesis > 0) {
|
||||||
|
switch (string.charAt(endIndex)) {
|
||||||
|
case '{':
|
||||||
|
++openParenthesis;
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
--openParenthesis;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.substring(startIndex, endIndex);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue