"""Parsing and executing JavaScript code""" import base64 from typing import Any import regex import js2py # Thanks to http://regex.inginf.units.it/ arrowexp = regex.compile(r'\w[^\}]*+') def to_ecma5_function(f: str) -> str: """Converts a ECMA6 function to ECMA5 format (without arrow expressions) :param f: ECMA6 function :type f: str :return: ECMA5 function :rtype: str """ f = regex.sub(r'/\*.+?\*/', '', f) match = arrowexp.search(f) conv = '(function(){' + match.group(0) + '})()' return regex.sub( r'(?:s|\(s\)) => s.split\([\'"]{2}\).reverse\(\).join\([\'"]{2}\)', 'function(s){return s.split(\'\').reverse().join(\'\')}', conv ) def atob(s: str) -> str: """Decodes base64 string :param s: Encoded data :type s: str :return: Decoded string :rtype: str """ return base64.standard_b64decode(str(s)).decode('utf-8') def exec_js(f: str) -> Any: """Executes a JavaScript function :param f: ECMA6 function :type f: str :return: JavaScript interpreter context :rtype: Any """ ctx = js2py.EvalJs({'atob': atob}) ctx.execute('window.document = { };') ctx.execute('window.Map = function(_i){ };') ctx.execute('window.setTimeout = function(_f,_t){ };') ctx.execute('window.setInterval = function(_f,_t){ };') ctx.execute('window.encodeURIComponent = function(_s){ };') ctx.execute(to_ecma5_function(f)) return ctx