[YouTube] Add JavaScript lexer to parse completely throttling decryption function (#905)
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package org.schabi.newpipe.extractor.utils;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.utils.jsextractor.JavaScriptExtractor;
|
||||
import org.schabi.newpipe.extractor.utils.jsextractor.Lexer;
|
||||
import org.schabi.newpipe.extractor.utils.jsextractor.Token;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.FileUtils.resolveTestResource;
|
||||
|
||||
public class JavaScriptExtractorTest
|
||||
{
|
||||
@Test
|
||||
void testJsExtractor() throws ParsingException {
|
||||
final String src = "Wka=function(d){var x = [/,,/,913,/(,)}/g,\"abcdef}\\\"\",];var y = 10/2/1;return x[1][y];}//some={}random-padding+;";
|
||||
final String result = JavaScriptExtractor.matchToClosingBrace(src, "Wka=function");
|
||||
assertEquals("(d){var x = [/,,/,913,/(,)}/g,\"abcdef}\\\"\",];var y = 10/2/1;return x[1][y];}", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEverythingJs() throws ParsingException, IOException {
|
||||
final File jsFile = resolveTestResource("es5.js");
|
||||
final StringBuilder contentBuilder = new StringBuilder();
|
||||
Files.lines(jsFile.toPath()).forEach(line -> contentBuilder.append(line).append("\n"));
|
||||
|
||||
final String js = contentBuilder.toString();
|
||||
|
||||
final Lexer lexer = new Lexer(js);
|
||||
Lexer.ParsedToken parsedToken = null;
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
parsedToken = lexer.getNextToken();
|
||||
if (parsedToken.token == Token.EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (final Exception e){
|
||||
if (parsedToken != null) {
|
||||
throw new ParsingException("Issue occured at pos " + parsedToken.end + ", after\n" +
|
||||
js.substring(Math.max(0, parsedToken.start - 50), parsedToken.end), e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
assertTrue(lexer.isBalanced());
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.schabi.newpipe.extractor.utils;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.schabi.newpipe.extractor.utils.StringUtils.matchToClosingParenthesis;
|
||||
|
||||
public class StringUtilsTest {
|
||||
|
||||
@Test
|
||||
public void actualDecodeFunction__success() {
|
||||
String preNoise = "if(\"function\"===typeof b&&\"function\"===typeof c||\"function\"===typeof c&&\"function\"===typeof d)throw Error(\"It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function.\");\"function\"===typeof b&&\"undefined\"===typeof c&&(c=b,b=void 0);if(\"undefined\"!==typeof c){if(\"function\"!==typeof c)throw Error(\"Expected the enhancer to be a function.\");return c(Dr)(a,b)}if(\"function\"!==typeof a)throw Error(\"Expected the reducer to be a function.\");\n" +
|
||||
"var l=a,m=b,n=[],p=n,q=!1;h({type:Cr});a={};var t=(a.dispatch=h,a.subscribe=f,a.getState=e,a.replaceReducer=function(u){if(\"function\"!==typeof u)throw Error(\"Expected the nextReducer to be a function.\");l=u;h({type:hha});return t},a[Er]=function(){var u={};\n" +
|
||||
"return u.subscribe=function(x){function y(){x.next&&x.next(e())}\n" +
|
||||
"if(\"object\"!==typeof x||null===x)throw new TypeError(\"Expected the observer to be an object.\");y();return{unsubscribe:f(y)}},u[Er]=function(){return this},u},a);\n" +
|
||||
"return t};\n" +
|
||||
"Fr=function(a){De.call(this,a,-1,iha)};\n" +
|
||||
"Gr=function(a){De.call(this,a)};\n" +
|
||||
"jha=function(a,b){for(;Jd(b);)switch(b.C){case 10:var c=Od(b);Ge(a,1,c);break;case 18:c=Od(b);Ge(a,2,c);break;case 26:c=Od(b);Ge(a,3,c);break;case 34:c=Od(b);Ge(a,4,c);break;case 40:c=Hd(b.i);Ge(a,5,c);break;default:if(!we(b))return a}return a};";
|
||||
String signature = "kha=function(a)";
|
||||
String body = "{var b=a.split(\"\"),c=[-1186681497,-1653318181,372630254,function(d,e){for(var f=64,h=[];++f-h.length-32;){switch(f){case 58:f-=14;case 91:case 92:case 93:continue;case 123:f=47;case 94:case 95:case 96:continue;case 46:f=95}h.push(String.fromCharCode(f))}d.forEach(function(l,m,n){this.push(n[m]=h[(h.indexOf(l)-h.indexOf(this[m])+m-32+f--)%h.length])},e.split(\"\"))},\n" +
|
||||
"-467738125,1158037010,function(d,e){e=(e%d.length+d.length)%d.length;var f=d[0];d[0]=d[e];d[e]=f},\n" +
|
||||
"\"continue\",158531598,-172776392,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(-e).reverse().forEach(function(f){d.unshift(f)})},\n" +
|
||||
"-1753359936,function(d){for(var e=d.length;e;)d.push(d.splice(--e,1)[0])},\n" +
|
||||
"1533713399,-1736576025,-1274201783,function(d){d.reverse()},\n" +
|
||||
"169126570,1077517431,function(d,e){d.push(e)},\n" +
|
||||
"-1807932259,-150219E3,480561184,-3495188,-1856307605,1416497372,b,-1034568435,-501230371,1979778585,null,b,-1049521459,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(0,1,d.splice(e,1,d[0])[0])},\n" +
|
||||
"1119056651,function(d,e){for(e=(e%d.length+d.length)%d.length;e--;)d.unshift(d.pop())},\n" +
|
||||
"b,1460920438,135616752,-1807932259,-815823682,-387465417,1979778585,113585E4,function(d,e){d.push(e)},\n" +
|
||||
"-1753359936,-241651400,-386043301,-144139513,null,null,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(e,1)}];\n" +
|
||||
"c[30]=c;c[49]=c;c[50]=c;try{c[51](c[26],c[25]),c[10](c[30],c[17]),c[5](c[28],c[9]),c[18](c[51]),c[14](c[19],c[21]),c[8](c[40],c[22]),c[50](c[35],c[28]),c[24](c[29],c[3]),c[0](c[31],c[19]),c[27](c[26],c[33]),c[29](c[36],c[40]),c[50](c[26]),c[27](c[32],c[9]),c[8](c[10],c[14]),c[35](c[44],c[28]),c[22](c[44],c[1]),c[8](c[11],c[3]),c[29](c[44]),c[21](c[41],c[45]),c[16](c[32],c[4]),c[17](c[14],c[26]),c[36](c[20],c[45]),c[43](c[35],c[39]),c[43](c[20],c[23]),c[43](c[10],c[51]),c[43](c[34],c[32]),c[29](c[34],\n" +
|
||||
"c[49]),c[43](c[20],c[44]),c[49](c[20]),c[19](c[15],c[8]),c[36](c[15],c[46]),c[17](c[20],c[37]),c[18](c[10]),c[17](c[34],c[31]),c[19](c[10],c[30]),c[19](c[20],c[2]),c[36](c[20],c[21]),c[43](c[35],c[16]),c[19](c[35],c[5]),c[18](c[46],c[34])}catch(d){return\"enhanced_except_lJMB6-z-_w8_\"+a}return b.join(\"\")}";
|
||||
String postNoise = "Hr=function(a){this.i=a}";
|
||||
|
||||
String substring = matchToClosingParenthesis(preNoise + '\n' + signature + body + ";" + postNoise, signature);
|
||||
|
||||
assertEquals(body, substring);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moreClosing__success() {
|
||||
String expected = "{{{}}}";
|
||||
String string = "a" + expected + "}}";
|
||||
|
||||
String substring = matchToClosingParenthesis(string, "a");
|
||||
|
||||
assertEquals(expected, substring);
|
||||
}
|
||||
|
||||
@Disabled("Functionality currently not needed")
|
||||
@Test
|
||||
public void lessClosing__success() {
|
||||
String expected = "{{{}}}";
|
||||
String string = "a{{" + expected;
|
||||
|
||||
String substring = matchToClosingParenthesis(string, "a");
|
||||
|
||||
assertEquals(expected, substring);
|
||||
}
|
||||
|
||||
@Test
|
||||
void find_closing_with_quotes() {
|
||||
final String expected = "{return \",}\\\"/\"}";
|
||||
final String string = "function(d){return \",}\\\"/\"}";
|
||||
|
||||
final String substring = matchToClosingParenthesis(string, "function(d)");
|
||||
|
||||
assertEquals(expected, substring);
|
||||
}
|
||||
}
|
||||
182
extractor/src/test/resources/es5.js
Normal file
182
extractor/src/test/resources/es5.js
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
Source: https://github.com/michaelficarra/everything.js
|
||||
|
||||
Copyright (c) 2014, Michael Ficarra.
|
||||
BSD-3-Clause license: https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/* this file contains all grammatical productions in ECMA-262 edition 5.1 ** * **/
|
||||
|
||||
// whitespace
|
||||
tab:for(;;)break tab;
|
||||
verticalTab:for(;;)breakverticalTab;
|
||||
formFeed:for(;;)breakformFeed;
|
||||
space:for(;;)break space;
|
||||
nbsp:for(;;)break nbsp;
|
||||
bom:for(;;)breakbom;
|
||||
|
||||
// line terminators
|
||||
lineFeed:0
|
||||
0;
|
||||
carriageReturn:0
|
||||
0;
|
||||
carriageReturnLineFeed:0
|
||||
0;
|
||||
lineSeparator:0
0;
|
||||
paragraphSeparator:0
0;
|
||||
|
||||
// identifier names
|
||||
var $, _, \u0078, x$, x_, x\u0030, xa, x0, x0a, x0123456789,
|
||||
qwertyuiopasdfghjklzxcvbnm, QWERTYUIOPASDFGHJKLZXCVBNM;
|
||||
// a representative sample of unicode letters and numbers
|
||||
var œ一, ǻ둘, ɤ〩, φ, fiⅷ, ユニコード, x;
|
||||
|
||||
null; true; false;
|
||||
|
||||
0; 00; 1234567890; 01234567;
|
||||
0.; 0.00; 10.00; .0; .00
|
||||
0e0; 0E0; 0.e0; 0.00e+0; .00e-0;
|
||||
0x0; 0X0; 0x0123456789abcdefABCDEF;
|
||||
2e308;
|
||||
|
||||
""; "'"; "\'\"\\\b\f\n\r\t\v\0";
|
||||
"\1\00\400\000";
|
||||
"\x01\x23\x45\x67\x89\xAB\xCD\xEF";
|
||||
"\u0123\u4567\u89AB\uCDEF"; "\
|
||||
";
|
||||
|
||||
''; '"'; '\'\"\\\b\f\n\r\t\v\0';
|
||||
'\1\00\400\000';
|
||||
'\x01\x23\x45\x67\x89\xAB\xCD\xEF';
|
||||
'\u0123\u4567\u89AB\uCDEF'; '\
|
||||
';
|
||||
|
||||
/x/; /|/; /|||/;
|
||||
/^$\b\B/; /(?=(?!(?:(.))))/;
|
||||
/a.\f\n\r\t\v\0\[\-\/\\\x00\u0000/; /\d\D\s\S\w\W/;
|
||||
/\ca\cb\cc\cd\ce\cf\cg\ch\ci\cj\ck\cl\cm\cn\co\cp\cq\cr\cs\ct\cu\cv\cw\cx\cy\cz/;
|
||||
/\cA\cB\cC\cD\cE\cF\cG\cH\cI\cJ\cK\cL\cM\cN\cO\cP\cQ\cR\cS\cT\cU\cV\cW\cX\cY\cZ/;
|
||||
/[a-z-]/; /[^\b\-^]/; /[/\]\\]/;
|
||||
/./i; /./g; /./m; /./igm;
|
||||
/.*/; /.*?/; /.+/; /.+?/; /.?/; /.??/;
|
||||
/.{0}/; /.{0,}/; /.{0,0}/;
|
||||
|
||||
this;
|
||||
|
||||
x;
|
||||
|
||||
[]; [,]; [0]; [0,]; [,0]; [0,0]; [0,0,]; [0,,0]; [,,];
|
||||
|
||||
({}); ({x:0}); ({x:0,y:0}); ({x:0,}); ({'x':0,"y":0,var:0,});
|
||||
({0:0}); ({0.:0}); ({0.0:0}); ({.0:0}); ({0e0:0}); ({0x0:0});
|
||||
({
|
||||
get x(){}, set x(a){}, get 'y'(){}, set "y"(a){},
|
||||
get 0(){}, set 0(a){}, get var(){}, set var(x){},
|
||||
});
|
||||
|
||||
0..a;
|
||||
|
||||
0[0];
|
||||
|
||||
// this function makes the NewExpression and CallExpression tests not throw at runtime
|
||||
x = function f(){ return f; }; x[0] = x; x.a = x;
|
||||
|
||||
new x(); new new x()();
|
||||
new x[0](); new x.a(); new x[0].a(); new x.a[0]();
|
||||
new x; new new x; new new x();
|
||||
new new x().a; new new x()[0];
|
||||
|
||||
x(); x()(); x(x); x(x, x);
|
||||
x.a().a(); x[0]()[0](); x().a[0]();
|
||||
|
||||
x++; x--;
|
||||
|
||||
delete void typeof+-~!x; ++x; --x;
|
||||
|
||||
0*0; 0/0; 0%0;
|
||||
|
||||
0+0; 0-0;
|
||||
|
||||
0<<0; 0>>0; 0>>>0;
|
||||
|
||||
0<0; 0>0; 0<=0; 0>=0;
|
||||
0 instanceof function(){};
|
||||
0 in{};
|
||||
|
||||
0==0; 0!=0; 0===0; 0!==0;
|
||||
|
||||
0&0; 0^0; 0|0; 0&&0; 0||0;
|
||||
|
||||
0?0:0; 0?0?0:0:0; 0||0?x=0:x=0;
|
||||
|
||||
x=0; x*=0; x/=0; x%=0; x+=0; x-=0;
|
||||
x<<=0; x>>=0; x>>>=0; x&=0; x^=0; x|=0;
|
||||
|
||||
0,0; 0,0,0; x=0,x=0;
|
||||
|
||||
|
||||
{} {;} {0} {0;} {0;0} {0;0;}
|
||||
|
||||
var x; var x,y; var x,y,z;
|
||||
var x=0; var x=0,y; var x,y=0; var x=0,y=0;
|
||||
|
||||
;
|
||||
|
||||
if(0); if(0);else;
|
||||
|
||||
do;while(0);
|
||||
while(0);
|
||||
for(;;)break; for(0;0;0); for((0 in[]);0;);
|
||||
for(var a;;)break; for(var a,b;0;0);
|
||||
for(var a=0;;)break; for(var a=(0 in[]);0;);
|
||||
for(x in{}); for(var x in{});
|
||||
for(var x=[]in{}); for(var x=(0 in[])in{});
|
||||
|
||||
for(;0;)continue; x:for(;0;)continue x;
|
||||
|
||||
for(;;)break; x:for(;;)break x;
|
||||
switch(0){case 0:break;}
|
||||
|
||||
function f(){ return; }
|
||||
function f(){ return 0; }
|
||||
|
||||
with(0);
|
||||
|
||||
switch(0){} switch(0){case 0:} switch(0){case 0:case 0:}
|
||||
switch(0){default:} switch(0){case 0:default:case 0:}
|
||||
switch(0){case 0:;} switch(0){case 0:;;}
|
||||
switch(0){default:;} switch(0){default:;;}
|
||||
|
||||
x:; x:y:;
|
||||
|
||||
try { throw 0; }catch(x){}
|
||||
|
||||
try{}catch(x){}
|
||||
try{}finally{}
|
||||
try{}catch(x){}finally{}
|
||||
|
||||
debugger;
|
||||
|
||||
function f(){}
|
||||
function f(x){}
|
||||
function f(x,y){}
|
||||
function f(){ function f(){} }
|
||||
|
||||
function f(){ "use strict" }
|
||||
function f(){ 'use strict' }
|
||||
function f(){ "other directive" }
|
||||
function f(){ 'other directive' }
|
||||
function f(){ ("string") }
|
||||
function f(){ ('string') }
|
||||
function f(){
|
||||
'string'
|
||||
+0
|
||||
}
|
||||
|
||||
(function(){});
|
||||
(function(x){});
|
||||
(function(x,y){});
|
||||
(function(){ function f(){} });
|
||||
(function f(){});
|
||||
(function f(x){});
|
||||
(function f(x,y){});
|
||||
(function f(){ function f(){} });
|
||||
Reference in New Issue
Block a user