sebaro / SaveTube

Download videos from video sharing web sites.
http://sebaro.pro/savetube
GNU General Public License v3.0
14 stars 2 forks source link

Dirty fix for broken Youtube this evening #1

Open SpyroTEQ opened 1 year ago

SpyroTEQ commented 1 year ago

Hi, This evening, the Savetube script (2022.07.11) stopped working on Youtube for Firefox Digging in the console, we get:

Uncaught (in promise) SyntaxError: unterminated regular expression literal
    ytGetUnscrambleParamFunc moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:799
    SaveTube moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:919
    window["__f__ljqiosax.rql"]/</< moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:1308
    window["__f__ljqiosax.rql"]/< moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:1322
    St https://www.youtube.com/watch?v=ZU74ATbAhns:9
    window["__f__ljqiosax.rql"]/< moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:1
    "__f__ljqiosax.rql" moz-extension://437a936d-5257-43bf-a2f7-372a6e0a7b5b/userscripts/SaveTube.user.js?id=5095000f-66d1-4199-ade0-8aace8f6b18a:1
    St https://www.youtube.com/watch?v=ZU74ATbAhns:9
    s https://www.youtube.com/watch?v=ZU74ATbAhns:72
    <anonymous> https://www.youtube.com/watch?v=ZU74ATbAhns:75
    g https://www.youtube.com/watch?v=ZU74ATbAhns:69

The erroneous line at 799 is

ytMainFuncBody = 'try {' + ytMainFuncBody + '} catch(e) {return null}';

Adding some console logs, it seems the body of the parsed ytMainFuncBody function is:

var b=a.split(""),c=[-265090265,751968325,-1951798130,160288705,function(d,e,f,h,l,m,n,p){return e(f,h,l,m,n,p)},
1941204574,/()\/"()(;)[;,'

which looks indeed truncated From the original script https://www.youtube.com/s/player/1dda5629/player_ias.vflset/fr_FR/base.js we see a regex /()\/"()(;)[;,'};]();/ which holds a dandling "}", that probably breaks the parser

As a quick and dirty fix, I made the "parseMyContent" function as below:

function parseMyContent(content, pattern) {
    var parse, response;
    content = content.replace(/(\r\n|\n|\r)/gm, '');
    content = content.replace("/()\\/\"()(;)[;,'};]();/","/####/"); // Manual dirty patch
    parse = content.match(pattern);
    if (parse) {
        response = (/g$/.test(pattern)) ? parse : parse[1];
        response = response.replace("/####/", "/()\\/\"()(;)[;,'};]();/"); // Manual dirty patch
    }
    return response;
}

By replacing the regex with dandling "}" before running the parsing Regex of line 797 (ytMainFuncBody = getMyContent(ytScriptUrl, new RegExp('(?:^|;)' + ytMainFuncName.replace(/\$/, '\\$') + '\\s*=\\s*function\\s*' + '\\s*\\(\\w+\\)\\s*\\{(.*?)\\};')); ) I get a properly parsed youtube script and SaveTube works again

I'm not opening a pull request here, because this is clearly not a nice "fix", but I wanted to share my root cause analysis of this issue so you may find a proper fix quicker and easier :)

(Note: since I edited this parseMyContent, i'm not 100% of my line numbers in this issue)

sebaro commented 1 year ago

For me the base.js didn't change yet: https://www.youtube.com/s/player/23604418/player_ias.vflset/en_US/base.js

Try with this line:

ytMainFuncBody = getMyContent(ytScriptUrl, new RegExp('(?:^|;)' + ytMainFuncName.replace(/\$/, '\\$') + '\\s*=\\s*function\\s*' + '\\s*\\(\\w+\\)\\s*\\{(.*?\\))\\};'));
SpyroTEQ commented 1 year ago

Well, I wanted to reproduce the issue to test your suggested change (which I think would work seeing the regex and looks way better), so I reverted my changes, but I could not reproduce my yesterday issue :/ I redownloaded the original 2022.07.11 from Gitlab but again, it seems the issue is no longer reproducible

If I end up crossing the path of the same bug, I'll give a try to your suggested change and I'll let you know it that works nice

Thanks! :) And sorry for not being able to reproduce my own bug today :/

sebaro commented 1 year ago

The base.js file is not always needed or it doesn't always have the string that breaks the script. New versions of the script uses the Android API which doesn't need the js file: http://sebaro.pro/savetube/files/savetubetest.user.js

SpyroTEQ commented 1 year ago

Ah, the issue happened again on https://www.youtube.com/watch?v=pNjFqW4amGQ

I've just tested your suggestion and it indeed works like a charm ! Thanks for the patch :)